Repository: google/exposure-notifications-server
Pull request #1061 (2020-10-06 20:17:01)

Fix e2e terraform deployment by supplying hosts
Terraform smoke test failed due to index out of bound error at https://github.com/google/exposure-notifications-server/blob/5e41925d7b2c441185979827f7ae58dc29991429/terraform/lb.tf#L203

google-oss-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/google/exposure-notifications-server/pull/1061#" title="Author self-approved">chaodaiG</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **mikehelmick** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @mikehelmick` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=google%2Fexposure-notifications-server).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/google/exposure-notifications-server/blob/main/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["mikehelmick"]} -->
chaodaiG: /cc @sethvargo 
sethvargo: /lgmt
sethvargo: /lgtm

Patch:
diff --git a/internal/generate/config.go b/internal/generate/config.go
index 5ede2d7..7dc1c89 100644
--- a/internal/generate/config.go
+++ b/internal/generate/config.go
@@ -50,6 +50,8 @@ type Config struct {
 	DefaultRegion                string        `env:"DEFAULT_REGION, default=US"`
 	ChanceOfKeyRevision          int           `env:"CHANCE_OF_KEY_REVISION, default=30"` // 0-100 are valid values.
 	KeyRevisionDelay             time.Duration `env:"KEY_REVISION_DELAY, default=2h"`     // key revision will be forward dates this amount.
+	UseDefaultSymptomOnset       bool          `env:"USE_DEFAULT_SYMPTOM_ONSET_DAYS, default=true"`
+	SymptomOnsetDays             uint          `env:"DEFAULT_SYMPTOM_ONSET_DAYS, default=10"`
 }
 
 func (c *Config) MaxExposureKeys() uint {
@@ -72,6 +74,14 @@ func (c *Config) MaxSymptomOnsetDays() uint {
 	return c.MaxMagnitudeSymptomOnsetDays
 }
 
+func (c *Config) UseDefaultSymptomOnsetDays() bool {
+	return c.UseDefaultSymptomOnset
+}
+
+func (c *Config) DefaultSymptomOnsetDays() int32 {
+	return int32(c.SymptomOnsetDays)
+}
+
 func (c *Config) DebugReleaseSameDayKeys() bool {
 	return false
 }
diff --git a/internal/publish/config.go b/internal/publish/config.go
index 1f17ff9..bebf8ad 100644
--- a/internal/publish/config.go
+++ b/internal/publish/config.go
@@ -53,9 +53,14 @@ type Config struct {
 	// Provides compatibility w/ 1.5 release.
 	MaxSameStartIntervalKeys     uint          `env:"MAX_SAME_START_INTERVAL_KEYS, default=3"`
 	MaxIntervalAge               time.Duration `env:"MAX_INTERVAL_AGE_ON_PUBLISH, default=360h"`
-	MaxMagnitudeSymptomOnsetDays uint          `env:"MAX_SYMPTOM_ONSET_DAYS, default=14"`
+	MaxMagnitudeSymptomOnsetDays uint          `env:"MAX_SYMPTOM_ONSET_DAYS, default=10"`
 	CreatedAtTruncateWindow      time.Duration `env:"TRUNCATE_WINDOW, default=1h"`
 
+	// If set, TEKs that arrive without a days since symptom onset (i.e. no symptom onset date)
+	// will be set to the default symptom onset days.
+	UseDefaultSymptomOnset bool `env:"USE_DEFAULT_SYMPTOM_ONSET_DAYS, default=true"`
+	SymptomOnsetDays       uint `env:"DEFAULT_SYMPTOM_ONSET_DAYS, default=10"`
+
 	ResponsePaddingMinBytes int64 `env:"RESPONSE_PADDING_MIN_BYTES, default=1024"`
 	ResponsePaddingRange    int64 `env:"RESPONSE_PADDING_RANGE, default=1024"`
 
@@ -103,6 +108,14 @@ func (c *Config) MaxSymptomOnsetDays() uint {
 	return c.MaxMagnitudeSymptomOnsetDays
 }
 
+func (c *Config) UseDefaultSymptomOnsetDays() bool {
+	return c.UseDefaultSymptomOnset
+}
+
+func (c *Config) DefaultSymptomOnsetDays() int32 {
+	return int32(c.SymptomOnsetDays)
+}
+
 func (c *Config) DebugReleaseSameDayKeys() bool {
 	return c.ReleaseSameDayKeys
 }
diff --git a/internal/publish/model/exposure_model.go b/internal/publish/model/exposure_model.go
index acde1d4..7c700e6 100644
--- a/internal/publish/model/exposure_model.go
+++ b/internal/publish/model/exposure_model.go
@@ -379,17 +379,21 @@ type TransformerConfig interface {
 	MaxIntervalStartAge() time.Duration
 	TruncateWindow() time.Duration
 	MaxSymptomOnsetDays() uint
+	UseDefaultSymptomOnsetDays() bool
+	DefaultSymptomOnsetDays() int32
 	DebugReleaseSameDayKeys() bool
 }
 
 // Transformer represents a configured Publish -> Exposure[] transformer.
 type Transformer struct {
-	maxExposureKeys     int           // Overall maximum number of keys.
-	maxSameDayKeys      int           // Number of keys that are allowed to have the same start interval.
-	maxIntervalStartAge time.Duration // How many intervals old does this server accept?
-	truncateWindow      time.Duration
-	maxSymptomOnsetDays float64 // to avoid casting in comparisons
-	debugReleaseSameDay bool    // If true, still valid keys are not embargoed.
+	maxExposureKeys            int           // Overall maximum number of keys.
+	maxSameDayKeys             int           // Number of keys that are allowed to have the same start interval.
+	maxIntervalStartAge        time.Duration // How many intervals old does this server accept?
+	truncateWindow             time.Duration
+	maxSymptomOnsetDays        float64 // to avoid casting in comparisons
+	useDefaultSymptomOnsetDays bool
+	defaultSymptomOnsetDays    int32
+	debugReleaseSameDay        bool // If true, still valid keys are not embargoed.
 }
 
 // NewTransformer creates a transformer for turning publish API requests into
@@ -403,12 +407,14 @@ func NewTransformer(config TransformerConfig) (*Transformer, error) {
 		return nil, fmt.Errorf("maxSameDayKeys must be >= 1, got %v", config.MaxSameDayKeys())
 	}
 	return &Transformer{
-		maxExposureKeys:     int(config.MaxExposureKeys()),
-		maxSameDayKeys:      int(config.MaxSameDayKeys()),
-		maxIntervalStartAge: config.MaxIntervalStartAge(),
-		truncateWindow:      config.TruncateWindow(),
-		maxSymptomOnsetDays: float64(config.MaxSymptomOnsetDays()),
-		debugReleaseSameDay: config.DebugReleaseSameDayKeys(),
+		maxExposureKeys:            int(config.MaxExposureKeys()),
+		maxSameDayKeys:             int(config.MaxSameDayKeys()),
+		maxIntervalStartAge:        config.MaxIntervalStartAge(),
+		truncateWindow:             config.TruncateWindow(),
+		maxSymptomOnsetDays:        float64(config.MaxSymptomOnsetDays()),
+		useDefaultSymptomOnsetDays: config.UseDefaultSymptomOnsetDays(),
+		defaultSymptomOnsetDays:    config.DefaultSymptomOnsetDays(),
+		debugReleaseSameDay:        config.DebugReleaseSameDayKeys(),
 	}, nil
 }
 
@@ -609,6 +615,11 @@ func (t *Transformer) TransformPublish(ctx context.Context, inData *verifyapi.Pu
 				exposure.SetDaysSinceSymptomOnset(daysSince)
 			}
 		}
+		// See if a default symptom onset days should be applied.
+		if exposure.DaysSinceSymptomOnset == nil && t.useDefaultSymptomOnsetDays {
+			exposure.SetDaysSinceSymptomOnset(t.defaultSymptomOnsetDays)
+		}
+
 		exposure.Traveler = inData.Traveler
 		entities = append(entities, exposure)
 	}


Test patch:
diff --git a/internal/publish/model/exposure_model_test.go b/internal/publish/model/exposure_model_test.go
index 90672b0..35377d8 100644
--- a/internal/publish/model/exposure_model_test.go
+++ b/internal/publish/model/exposure_model_test.go
@@ -40,12 +40,14 @@ const (
 )
 
 type testConfig struct {
-	maxExposureKeys     uint
-	maxSameDayKeys      uint
-	maxIntervalStartAge time.Duration
-	truncateWindow      time.Duration
-	maxSymptomOnsetDays uint
-	debugReleaseSameDay bool
+	maxExposureKeys            uint
+	maxSameDayKeys             uint
+	maxIntervalStartAge        time.Duration
+	truncateWindow             time.Duration
+	maxSymptomOnsetDays        uint
+	useDefaultSymptomOnsetDays bool
+	defaultSymptomOnsetDays    int32
+	debugReleaseSameDay        bool
 }
 
 func (c *testConfig) MaxExposureKeys() uint {
@@ -68,6 +70,14 @@ func (c *testConfig) MaxSymptomOnsetDays() uint {
 	return c.maxSymptomOnsetDays
 }
 
+func (c *testConfig) UseDefaultSymptomOnsetDays() bool {
+	return c.useDefaultSymptomOnsetDays
+}
+
+func (c *testConfig) DefaultSymptomOnsetDays() int32 {
+	return c.defaultSymptomOnsetDays
+}
+
 func (c *testConfig) DebugReleaseSameDayKeys() bool {
 	return c.debugReleaseSameDay
 }
@@ -98,7 +108,13 @@ func TestInvalidNew(t *testing.T) {
 	}
 
 	for i, c := range cases {
-		_, err := NewTransformer(&testConfig{c.maxKeys, c.maxSameDayKeys, time.Hour, time.Hour, maxSymptomOnsetDays, false})
+		_, err := NewTransformer(&testConfig{
+			maxExposureKeys:     c.maxKeys,
+			maxSameDayKeys:      c.maxSameDayKeys,
+			maxIntervalStartAge: time.Hour,
+			truncateWindow:      time.Hour,
+			maxSymptomOnsetDays: maxSymptomOnsetDays,
+		})
 		if err != nil && errMsg == "" {
 			t.Errorf("%v unexpected error: %v", i, err)
 		} else if err != nil && !strings.Contains(err.Error(), c.message) {
@@ -109,7 +125,13 @@ func TestInvalidNew(t *testing.T) {
 
 func TestInvalidBase64(t *testing.T) {
 	ctx := context.Background()
-	transformer, err := NewTransformer(&testConfig{1, 1, time.Hour * 24, time.Hour, maxSymptomOnsetDays, false})
+	transformer, err := NewTransformer(&testConfig{
+		maxExposureKeys:     1,
+		maxSameDayKeys:      1,
+		maxIntervalStartAge: time.Hour * 24,
+		truncateWindow:      time.Hour,
+		maxSymptomOnsetDays: maxSymptomOnsetDays,
+	})
 	if err != nil {
 		t.Fatalf("error creating transformer: %v", err)
 	}
@@ -311,7 +333,13 @@ func TestPublishValidation(t *testing.T) {
 	for _, c := range cases {
 		t.Run(c.name, func(t *testing.T) {
 			ctx := context.Background()
-			tf, err := NewTransformer(&testConfig{2, 1, maxAge, time.Hour, maxSymptomOnsetDays, c.sameDay})
+			tf, err := NewTransformer(&testConfig{
+				maxExposureKeys:     2,
+				maxSameDayKeys:      1,
+				maxIntervalStartAge: maxAge,
+				truncateWindow:      time.Hour,
+				maxSymptomOnsetDays: maxSymptomOnsetDays,
+				debugReleaseSameDay: c.sameDay})
 			if err != nil {
 				t.Fatalf("unepected error: %v", err)
 			}
@@ -390,7 +418,14 @@ func TestStillValidKey(t *testing.T) {
 	for _, tc := range cases {
 		t.Run(tc.name, func(t *testing.T) {
 			allowedAge := 2 * 24 * time.Hour
-			transformer, err := NewTransformer(&testConfig{10, 1, allowedAge, time.Minute, maxSymptomOnsetDays, tc.releaseSameDayKeys})
+			transformer, err := NewTransformer(&testConfig{
+				maxExposureKeys:     10,
+				maxSameDayKeys:      1,
+				maxIntervalStartAge: allowedAge,
+				truncateWindow:      time.Minute,
+				maxSymptomOnsetDays: maxSymptomOnsetDays,
+				debugReleaseSameDay: tc.releaseSameDayKeys,
+			})
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -785,7 +820,13 @@ func TestTransform(t *testing.T) {
 	}
 
 	allowedAge := 14 * 24 * time.Hour
-	transformer, err := NewTransformer(&testConfig{10, 1, allowedAge, time.Hour, maxSymptomOnsetDays, false})
+	transformer, err := NewTransformer(&testConfig{
+		maxExposureKeys:     10,
+		maxSameDayKeys:      1,
+		maxIntervalStartAge: allowedAge,
+		truncateWindow:      time.Hour,
+		maxSymptomOnsetDays: maxSymptomOnsetDays,
+	})
 	if err != nil {
 		t.Fatalf("NewTransformer returned unexpected error: %v", err)
 	}
@@ -820,6 +861,85 @@ func TestTransform(t *testing.T) {
 	}
 }
 
+func TestDefaultSymptomOnset(t *testing.T) {
+	now := time.Now()
+	intervalNumber := IntervalNumber(now) - 1
+
+	cases := []struct {
+		name               string
+		source             verifyapi.Publish
+		useOnsetDefault    bool
+		onsetDefault       int32
+		wantDaysSinceOnset *int32
+	}{
+		{
+			name: "use_default_when_not_set",
+			source: verifyapi.Publish{
+				Keys: []verifyapi.ExposureKey{
+					{
+						Key:              encodeKey(generateKey(t)),
+						IntervalNumber:   intervalNumber,
+						IntervalCount:    verifyapi.MaxIntervalCount,
+						TransmissionRisk: 1,
+					},
+				},
+			},
+			useOnsetDefault:    true,
+			onsetDefault:       10,
+			wantDaysSinceOnset: proto.Int32(10),
+		},
+		{
+			name: "do_not_set_default",
+			source: verifyapi.Publish{
+				Keys: []verifyapi.ExposureKey{
+					{
+						Key:              encodeKey(generateKey(t)),
+						IntervalNumber:   intervalNumber,
+						IntervalCount:    verifyapi.MaxIntervalCount,
+						TransmissionRisk: 1,
+					},
+				},
+			},
+			useOnsetDefault:    false,
+			onsetDefault:       12,
+			wantDaysSinceOnset: nil,
+		},
+	}
+
+	for _, tc := range cases {
+		t.Run(tc.name, func(t *testing.T) {
+			allowedAge := 2 * 24 * time.Hour
+			transformer, err := NewTransformer(&testConfig{
+				maxExposureKeys:            10,
+				maxSameDayKeys:             1,
+				maxIntervalStartAge:        allowedAge,
+				truncateWindow:             time.Minute,
+				maxSymptomOnsetDays:        maxSymptomOnsetDays,
+				debugReleaseSameDay:        false,
+				useDefaultSymptomOnsetDays: tc.useOnsetDefault,
+				defaultSymptomOnsetDays:    tc.onsetDefault,
+			})
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			ctx := context.Background()
+			tf, _, err := transformer.TransformPublish(ctx, &tc.source, []string{}, nil, now)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			if len(tf) != 1 {
+				t.Fatalf("wrong number of keys, want: 1 got :%v", len(tf))
+			}
+
+			if diff := cmp.Diff(tf[0].DaysSinceSymptomOnset, tc.wantDaysSinceOnset); diff != "" {
+				t.Errorf("mismatch (-want, +got):\n%s", diff)
+			}
+		})
+	}
+}
+
 func TestTransformOverlapping(t *testing.T) {
 	now := time.Now()
 	allowedAge := 3 * 24 * time.Hour
@@ -961,7 +1081,13 @@ func TestTransformOverlapping(t *testing.T) {
 	for _, tc := range cases {
 		t.Run(tc.name, func(t *testing.T) {
 			ctx := context.Background()
-			transformer, err := NewTransformer(&testConfig{10, tc.maxSameIntervalKeys, allowedAge, time.Hour, maxSymptomOnsetDays, false})
+			transformer, err := NewTransformer(&testConfig{
+				maxExposureKeys:     10,
+				maxSameDayKeys:      tc.maxSameIntervalKeys,
+				maxIntervalStartAge: allowedAge,
+				truncateWindow:      time.Hour,
+				maxSymptomOnsetDays: maxSymptomOnsetDays,
+			})
 			if err != nil {
 				t.Fatalf("NewTransformer returned unexpected error: %v", err)
 			}
diff --git a/terraform-e2e/main.tf b/terraform-e2e/main.tf
index 310ee46..f7aea87 100644
--- a/terraform-e2e/main.tf
+++ b/terraform-e2e/main.tf
@@ -39,6 +39,11 @@ module "en" {
 
   create_env_file = true
 
+  debugger_hosts      = ["debugger.todo"]
+  export_hosts        = ["export.todo"]
+  exposure_hosts      = ["exposure.todo"]
+  federationout_hosts = ["federationout.todo"]
+
   service_environment = {
     export = {
       TRUNCATE_WINDOW = "1s"