[swd-e2e-tests] Allow omaha server address to be specified

This extends the omaha server to be served on a fixed address, rather
than an arbitrary port. This is helpful for testing omaha, because the
omaha server is embedded into vbmeta. If this port is random, it
requires users to repave the device in order to perform cycle testing.

Change-Id: Ib2a3bbf3ea414bb14af665a870eacde731b51485
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/404658
Commit-Queue: Erick Tryzelaar <etryzelaar@google.com>
Reviewed-by: Alex Legg <alexlegg@google.com>
Testability-Review: Alex Legg <alexlegg@google.com>
diff --git a/src/sys/pkg/testing/host-target-testing/omaha/omaha.go b/src/sys/pkg/testing/host-target-testing/omaha/omaha.go
index 6cf30bc..e131a65 100644
--- a/src/sys/pkg/testing/host-target-testing/omaha/omaha.go
+++ b/src/sys/pkg/testing/host-target-testing/omaha/omaha.go
@@ -91,8 +91,11 @@
 	Response responseConfig `json:"response"`
 }
 
-// NewOmahaServer starts an http server that serves the omaha response.
-func NewOmahaServer(ctx context.Context, localHostname string) (*OmahaServer, error) {
+// NewOmahaServer starts an http server that serves the omaha response. The
+// `serverAddress` is the address the server will listen on. The
+// `localHostname` is the hostname running the server from the perspective of
+// the test device.
+func NewOmahaServer(ctx context.Context, serverAddress string, localHostname string) (*OmahaServer, error) {
 	l := logger.NewLogger(
 		logger.DebugLevel,
 		color.NewColor(color.ColorAuto),
@@ -102,7 +105,7 @@
 	l.SetFlags(logger.Ldate | logger.Ltime | logger.LUTC | logger.Lshortfile)
 	ctx = logger.WithLogger(ctx, l)
 
-	listener, err := net.Listen("tcp", ":0")
+	listener, err := net.Listen("tcp", serverAddress)
 	if err != nil {
 		return nil, err
 	}
@@ -237,10 +240,12 @@
 		return fmt.Errorf("update package URL's host must not be empty")
 	}
 
-	logger.Infof(ctx, "Omaha Server update package set to %q", u.String())
+	logger.Infof(ctx, "Omaha Server update package set to %q %q", u.Host, u.String())
 
 	o.updateHost = fmt.Sprintf("fuchsia-pkg://%s", u.Host)
 
+	logger.Infof(ctx, "Omaha Server update package set to %q", u.String())
+
 	// The updatePkg field is the URL with the scheme and host stripped off.
 	u.Scheme = ""
 	u.Host = ""
diff --git a/src/sys/pkg/testing/host-target-testing/omaha/omaha_test.go b/src/sys/pkg/testing/host-target-testing/omaha/omaha_test.go
index 3128d5c..299fd1d 100644
--- a/src/sys/pkg/testing/host-target-testing/omaha/omaha_test.go
+++ b/src/sys/pkg/testing/host-target-testing/omaha/omaha_test.go
@@ -27,18 +27,24 @@
 
 func TestSetPkgURL(t *testing.T) {
 	ctx := context.Background()
-	o, err := NewOmahaServer(ctx, "localhost")
-	err = o.SetUpdatePkgURL(ctx, "bad")
-	if err == nil {
+	o, err := NewOmahaServer(ctx, ":0", "localhost")
+	if err != nil {
+		t.Fatalf("failed to create omaha server: %v", err)
+	}
+
+	if err = o.SetUpdatePkgURL(ctx, "bad"); err == nil {
 		t.Fatalf("SetUpdatePkgURL should fail when given string 'bad'.")
 	}
+
 	err = o.SetUpdatePkgURL(ctx, "fuchsia-pkg://fuchsia.com/update/0?hash=abcdef")
 	if err != nil {
 		t.Fatalf("SetUpdatePkgURL should not fail with the given input. %s", err)
 	}
+
 	if o.updateHost != "fuchsia-pkg://fuchsia.com" {
 		t.Fatalf("updateHost does not match. Got %s expect %s", o.updateHost, "fuchsia-pkg://fuchsia.com")
 	}
+
 	if o.updatePkg != "/update/0?hash=abcdef" {
 		t.Fatalf("updatePkg does not match. Got %s expect %s", o.updatePkg, "/update/0?hash=abcdef")
 	}
@@ -46,11 +52,16 @@
 
 func TestBeforeAfterSetPkgURL(t *testing.T) {
 	ctx := context.Background()
-	o, err := NewOmahaServer(ctx, "localhost")
+	o, err := NewOmahaServer(ctx, ":0", "localhost")
+	if err != nil {
+		t.Fatalf("failed to create omaha server: %v", err)
+	}
+
 	resp, err := http.Get(o.URL())
 	if err != nil {
 		t.Fatalf("Get request shouldn't fail. %s", err)
 	}
+
 	if resp.StatusCode != 200 {
 		t.Fatalf("Get response code not 200 (OK), got %d", resp.StatusCode)
 	}
@@ -68,36 +79,44 @@
 
 	dec := json.NewDecoder(resp.Body)
 	var data response
-	err = dec.Decode(&data)
-	if err != nil {
+	if err = dec.Decode(&data); err != nil {
 		t.Fatalf("Could not decode")
 	}
+
 	updateCheck := data.Response.App[0].UpdateCheck
+
 	if updateCheck.Status != "ok" {
 		t.Fatalf("Status should be 'ok', is %s", updateCheck.Status)
 	}
+
 	if updateCheck.Urls.Url[0].Codebase != "fuchsia-pkg://fuchsia.com" {
 		t.Fatalf(
 			"Update package host should be 'fuchsia-pkg://fuchsia.com', is %s",
 			updateCheck.Urls.Url[0].Codebase)
 	}
+
 	action := updateCheck.Manifest.Actions.Action[0]
+
 	if action.Run != "/update/0?hash=abcdef" {
 		t.Fatalf(
 			"Manifest action should have '/update/0?hash=abcdef', is %s",
 			action.Run)
 	}
+
 	if action.Event != "update" {
 		t.Fatalf(
 			"First manifest action should have event 'update', is %s",
 			action.Event)
 	}
+
 	action = data.Response.App[0].UpdateCheck.Manifest.Actions.Action[1]
+
 	if action.Event != "postinstall" {
 		t.Fatalf(
 			"Second manifest action should have event 'postinstall', is %s",
 			action.Event)
 	}
+
 	if updateCheck.Manifest.Packages.Pkg[0].Name != "/update/0?hash=abcdef" {
 		t.Fatalf(
 			"Manifest package should have '/update?hash=abcdef', is %s",
@@ -107,11 +126,16 @@
 
 func TestShutdown(t *testing.T) {
 	ctx := context.Background()
-	o, err := NewOmahaServer(ctx, "localhost")
+	o, err := NewOmahaServer(ctx, ":0", "localhost")
+	if err != nil {
+		t.Fatalf("failed to create omaha server: %v", err)
+	}
+
 	resp, err := http.Get(o.URL())
 	if err != nil {
 		t.Fatalf("Get request shouldn't fail. %s", err)
 	}
+
 	if resp.StatusCode != 200 {
 		t.Fatalf("Get response code not 200 (OK), got %d", resp.StatusCode)
 	}
diff --git a/src/sys/pkg/tests/system-tests/config/installer.go b/src/sys/pkg/tests/system-tests/config/installer.go
index c44542d..2f70c42 100644
--- a/src/sys/pkg/tests/system-tests/config/installer.go
+++ b/src/sys/pkg/tests/system-tests/config/installer.go
@@ -33,6 +33,7 @@
 	avbTool         *avb.AVBTool
 	updater         updater.Updater
 	omahaServer     *omaha.OmahaServer
+	omahaAddress    string
 }
 
 func NewInstallerConfig(fs *flag.FlagSet) (*InstallerConfig, error) {
@@ -45,6 +46,7 @@
 		"path to the avbtool binary")
 	fs.StringVar(&c.keyPath, "vbmeta-key", filepath.Join(testDataPath, "atx_psk.pem"), "path to the vbmeta private key")
 	fs.StringVar(&c.keyMetadataPath, "vbmeta-key-metadata", filepath.Join(testDataPath, "avb_atx_metadata.bin"), "path to the vbmeta public key metadata")
+	fs.StringVar(&c.omahaAddress, "omaha-address", ":0", "which address to serve omaha server on (default random)")
 
 	return c, nil
 }
@@ -65,7 +67,7 @@
 	switch c.installerMode {
 	case Omaha:
 		if c.omahaServer == nil {
-			omahaServer, err := omaha.NewOmahaServer(ctx, "localhost")
+			omahaServer, err := omaha.NewOmahaServer(ctx, c.omahaAddress, "localhost")
 			if err != nil {
 				return nil, err
 			}