treewide: fix t.Fatal calls in non-test goroutines

Functions that abruptly terminate a test, such as the
Fatal, Fatalf, FailNow, and Skip{,f,Now} methods of *testing.T,
must be called from the test goroutine itself, as they call
runtime.Goexit internally to stop the calling goroutine, not the
test.

Change-Id: I4926c802bfbb11aeec6e130b0f4fb2407879cbd4
Reviewed-on: https://review.monogon.dev/c/monogon/+/2972
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/cloud/bmaas/bmdb/sessions_test.go b/cloud/bmaas/bmdb/sessions_test.go
index d3c80bd..9806ddb 100644
--- a/cloud/bmaas/bmdb/sessions_test.go
+++ b/cloud/bmaas/bmdb/sessions_test.go
@@ -582,11 +582,13 @@
 	}
 
 	worker := func(workerID int) {
-		ctxS, ctxC := context.WithCancel(ctx)
-		defer ctxC()
+		ctxS, ctxSC := context.WithCancel(ctx)
+		defer ctxSC()
 		session, err := conn.StartSession(ctxS)
 		if err != nil {
-			t.Fatalf("Starting session failed: %v", err)
+			t.Errorf("Starting session failed: %v", err)
+			ctxC()
+			return
 		}
 		for {
 			err := workOnce(ctxS, workerID, session)
@@ -597,7 +599,9 @@
 				if errors.Is(err, ctxS.Err()) {
 					return
 				}
-				t.Fatalf("worker failed: %v", err)
+				t.Errorf("worker failed: %v", err)
+				ctxC()
+				return
 			}
 		}
 	}
@@ -608,7 +612,11 @@
 
 	// Wait for at least three workers to be alive.
 	for i := 0; i < 3; i++ {
-		workStarted <- struct{}{}
+		select {
+			case workStarted <- struct{}{}:
+			case <-ctx.Done():
+				t.FailNow()
+		}
 	}
 
 	// Allow all workers to continue running from now on.
diff --git a/go/net/psample/psample_test.go b/go/net/psample/psample_test.go
index 925ae0d..b01ad97 100644
--- a/go/net/psample/psample_test.go
+++ b/go/net/psample/psample_test.go
@@ -179,7 +179,8 @@
 	}
 
 	// Look for packets matching attributes defined in 'sa'. Signal on 'dC'
-	// immediately after the expected packet has been received, then return.
+	// immediately after the expected packet has been received or an error
+	// occurred, then return.
 	dC := make(chan struct{})
 	go func() {
 		for {
@@ -188,7 +189,9 @@
 			// the sampled traffic could not have been captured, and had been
 			// dropped instead.
 			if err != nil && !errors.Is(err, syscall.ENOBUFS) {
-				t.Fatalf("while receiving psamples: %v", err)
+				t.Errorf("while receiving psamples: %v", err)
+				dC <- struct{}{}
+				return
 			}
 			for _, raw := range pkts {
 				if sa.match(t, raw) {
diff --git a/metropolis/node/core/curator/impl_leader_test.go b/metropolis/node/core/curator/impl_leader_test.go
index e89d4a1..2d92536 100644
--- a/metropolis/node/core/curator/impl_leader_test.go
+++ b/metropolis/node/core/curator/impl_leader_test.go
@@ -182,7 +182,8 @@
 	externalLis := bufconn.Listen(1024 * 1024)
 	go func() {
 		if err := srv.Serve(externalLis); err != nil {
-			t.Fatalf("GRPC serve failed: %v", err)
+			t.Errorf("GRPC serve failed: %v", err)
+			return
 		}
 	}()
 
diff --git a/metropolis/node/core/mgmt/svc_logs_test.go b/metropolis/node/core/mgmt/svc_logs_test.go
index 9517600..734a149 100644
--- a/metropolis/node/core/mgmt/svc_logs_test.go
+++ b/metropolis/node/core/mgmt/svc_logs_test.go
@@ -35,7 +35,8 @@
 	externalLis := bufconn.Listen(1024 * 1024)
 	go func() {
 		if err := srv.Serve(externalLis); err != nil {
-			t.Fatalf("GRPC serve failed: %v", err)
+			t.Errorf("GRPC serve failed: %v", err)
+			return
 		}
 	}()
 	withLocalDialer := grpc.WithContextDialer(func(_ context.Context, _ string) (net.Conn, error) {
diff --git a/metropolis/node/core/roleserve/worker_statuspush_test.go b/metropolis/node/core/roleserve/worker_statuspush_test.go
index d1a8d2d..06e48e8 100644
--- a/metropolis/node/core/roleserve/worker_statuspush_test.go
+++ b/metropolis/node/core/roleserve/worker_statuspush_test.go
@@ -87,7 +87,8 @@
 	defer lis.Close()
 	go func() {
 		if err := srv.Serve(lis); err != nil {
-			t.Fatalf("GRPC serve failed: %v", err)
+			t.Errorf("GRPC serve failed: %v", err)
+			return
 		}
 	}()
 	withLocalDialer := grpc.WithContextDialer(func(_ context.Context, _ string) (net.Conn, error) {
diff --git a/metropolis/node/core/rpc/resolver/resolver_test.go b/metropolis/node/core/rpc/resolver/resolver_test.go
index eac59d1..e0f67ef 100644
--- a/metropolis/node/core/rpc/resolver/resolver_test.go
+++ b/metropolis/node/core/rpc/resolver/resolver_test.go
@@ -153,7 +153,8 @@
 		ipb.RegisterCuratorLocalServer(servers[i], impls[i])
 		go func() {
 			if err := servers[i].Serve(listeners[i]); err != nil {
-				t.Fatalf("GRPC serve failed: %v", err)
+				t.Errorf("GRPC serve failed: %v", err)
+				return
 			}
 		}()
 
diff --git a/metropolis/node/core/rpc/server_authentication_test.go b/metropolis/node/core/rpc/server_authentication_test.go
index b0da0a9..8a869bd 100644
--- a/metropolis/node/core/rpc/server_authentication_test.go
+++ b/metropolis/node/core/rpc/server_authentication_test.go
@@ -51,7 +51,8 @@
 	lis := bufconn.Listen(1024 * 1024)
 	go func() {
 		if err := srv.Serve(lis); err != nil {
-			t.Fatalf("GRPC serve failed: %v", err)
+			t.Errorf("GRPC serve failed: %v", err)
+			return
 		}
 	}()
 	defer lis.Close()
diff --git a/metropolis/pkg/event/etcd/etcd_test.go b/metropolis/pkg/event/etcd/etcd_test.go
index e7e1227..6173732 100644
--- a/metropolis/pkg/event/etcd/etcd_test.go
+++ b/metropolis/pkg/event/etcd/etcd_test.go
@@ -210,7 +210,9 @@
 				return
 			}
 			if err != nil {
-				t.Fatalf("Get: %v", err)
+				t.Errorf("Get: %v", err)
+				close(c)
+				return
 			}
 			c <- got.Value
 		}
diff --git a/metropolis/pkg/socksproxy/socksproxy_test.go b/metropolis/pkg/socksproxy/socksproxy_test.go
index 1f384f6..0132ab3 100644
--- a/metropolis/pkg/socksproxy/socksproxy_test.go
+++ b/metropolis/pkg/socksproxy/socksproxy_test.go
@@ -35,7 +35,8 @@
 	go func() {
 		err := http.Serve(lisSrv, mux)
 		if err != nil {
-			t.Fatalf("http.Serve: %v", err)
+			t.Errorf("http.Serve: %v", err)
+			return
 		}
 	}()
 
@@ -47,7 +48,8 @@
 	go func() {
 		err := Serve(ctx, HostHandler, lisPrx)
 		if err != nil && !errors.Is(err, ctx.Err()) {
-			t.Fatalf("proxy.Serve: %v", err)
+			t.Errorf("proxy.Serve: %v", err)
+			return
 		}
 	}()
 
@@ -122,7 +124,8 @@
 	go func() {
 		err := Serve(ctx, handler, lisPrx)
 		if err != nil && !errors.Is(err, ctx.Err()) {
-			t.Fatalf("proxy.Serve: %v", err)
+			t.Errorf("proxy.Serve: %v", err)
+			return
 		}
 	}()
 
diff --git a/metropolis/test/util/curator.go b/metropolis/test/util/curator.go
index 7d1f36a..39b2610 100644
--- a/metropolis/test/util/curator.go
+++ b/metropolis/test/util/curator.go
@@ -95,7 +95,8 @@
 	externalLis := bufconn.Listen(1024 * 1024)
 	go func() {
 		if err := srv.Serve(externalLis); err != nil {
-			t.Fatalf("GRPC serve failed: %v", err)
+			t.Errorf("GRPC serve failed: %v", err)
+			return
 		}
 	}()
 	withLocalDialer := grpc.WithContextDialer(func(_ context.Context, _ string) (net.Conn, error) {