Repository: clouditor/clouditor
Pull request #480 (2022-02-03 22:26:43)

Fixed blocked exit of CLI program due to REST ready channel
The `ready` channel in the `rest` package was blocking the regular program exit.


codecov[bot]: # [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/480?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) Report
> Merging [#480](https://codecov.io/gh/clouditor/clouditor/pull/480?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (4ed25e4) into [main](https://codecov.io/gh/clouditor/clouditor/commit/e4bdd8398a1d315decb3bef8e7bcdda728e63d18?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (e4bdd83) will **decrease** coverage by `0.07%`.
> The diff coverage is `0.00%`.

[![Impacted file tree graph](https://codecov.io/gh/clouditor/clouditor/pull/480/graphs/tree.svg?width=650&height=150&src=pr&token=syrXsw5LTX&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)](https://codecov.io/gh/clouditor/clouditor/pull/480?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)

```diff
@@            Coverage Diff             @@
##             main     #480      +/-   ##
==========================================
- Coverage   76.89%   76.81%   -0.08%     
==========================================
  Files          44       44              
  Lines        3869     3873       +4     
==========================================
  Hits         2975     2975              
- Misses        754      758       +4     
  Partials      140      140              
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `76.81% <0.00%> (-0.08%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/clouditor/clouditor/pull/480?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) | Coverage Δ | |
|---|---|---|
| [rest/rest.go](https://codecov.io/gh/clouditor/clouditor/pull/480/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-cmVzdC9yZXN0Lmdv) | `65.17% <0.00%> (-2.42%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/clouditor/clouditor/pull/480?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/480?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Last update [e4bdd83...4ed25e4](https://codecov.io/gh/clouditor/clouditor/pull/480?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor).


Patch:
diff --git a/api/assessment/assessment.pb.go b/api/assessment/assessment.pb.go
index f0cc2acc..38586475 100644
--- a/api/assessment/assessment.pb.go
+++ b/api/assessment/assessment.pb.go
@@ -27,7 +27,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.1
+// 	protoc        v3.19.4
 // source: assessment.proto
 
 package assessment
diff --git a/api/assessment/assessment.pb.gw.go b/api/assessment/assessment.pb.gw.go
index b152c9ab..c10567ef 100644
--- a/api/assessment/assessment.pb.gw.go
+++ b/api/assessment/assessment.pb.gw.go
@@ -165,7 +165,7 @@ func RegisterAssessmentHandlerFromEndpoint(ctx context.Context, mux *runtime.Ser
 
 // RegisterAssessmentHandler registers the http handlers for service Assessment to "mux".
 // The handlers forward requests to the grpc endpoint over "conn".
-func RegisterAssessmentHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
+func RegisterAssessmentHandler(ctx context.Context, mux *runtime.ServeMux, conn grpc.ClientConnInterface) error {
 	return RegisterAssessmentHandlerClient(ctx, mux, NewAssessmentClient(conn))
 }
 
diff --git a/api/assessment/assessment_grpc.pb.go b/api/assessment/assessment_grpc.pb.go
index 1adbf042..6145266b 100644
--- a/api/assessment/assessment_grpc.pb.go
+++ b/api/assessment/assessment_grpc.pb.go
@@ -1,4 +1,8 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.2.0
+// - protoc             v3.19.4
+// source: assessment.proto
 
 package assessment
 
diff --git a/api/assessment/metric.pb.go b/api/assessment/metric.pb.go
index 137f6f03..d7b542a4 100644
--- a/api/assessment/metric.pb.go
+++ b/api/assessment/metric.pb.go
@@ -27,7 +27,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.1
+// 	protoc        v3.19.4
 // source: metric.proto
 
 package assessment
diff --git a/api/auth/auth.pb.go b/api/auth/auth.pb.go
index c412993f..b27b4241 100644
--- a/api/auth/auth.pb.go
+++ b/api/auth/auth.pb.go
@@ -27,7 +27,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.1
+// 	protoc        v3.19.4
 // source: auth.proto
 
 package auth
diff --git a/api/auth/auth.pb.gw.go b/api/auth/auth.pb.gw.go
index 44c6463e..ff0f28b5 100644
--- a/api/auth/auth.pb.gw.go
+++ b/api/auth/auth.pb.gw.go
@@ -124,7 +124,7 @@ func RegisterAuthenticationHandlerFromEndpoint(ctx context.Context, mux *runtime
 
 // RegisterAuthenticationHandler registers the http handlers for service Authentication to "mux".
 // The handlers forward requests to the grpc endpoint over "conn".
-func RegisterAuthenticationHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
+func RegisterAuthenticationHandler(ctx context.Context, mux *runtime.ServeMux, conn grpc.ClientConnInterface) error {
 	return RegisterAuthenticationHandlerClient(ctx, mux, NewAuthenticationClient(conn))
 }
 
diff --git a/api/auth/auth_grpc.pb.go b/api/auth/auth_grpc.pb.go
index 53e22836..6c55fe9d 100644
--- a/api/auth/auth_grpc.pb.go
+++ b/api/auth/auth_grpc.pb.go
@@ -1,4 +1,8 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.2.0
+// - protoc             v3.19.4
+// source: auth.proto
 
 package auth
 
diff --git a/api/discovery/discovery.pb.go b/api/discovery/discovery.pb.go
index 3e684d0a..d654b8dd 100644
--- a/api/discovery/discovery.pb.go
+++ b/api/discovery/discovery.pb.go
@@ -27,7 +27,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.1
+// 	protoc        v3.19.4
 // source: discovery.proto
 
 package discovery
diff --git a/api/discovery/discovery.pb.gw.go b/api/discovery/discovery.pb.gw.go
index f769205d..9a1cb69e 100644
--- a/api/discovery/discovery.pb.gw.go
+++ b/api/discovery/discovery.pb.gw.go
@@ -181,7 +181,7 @@ func RegisterDiscoveryHandlerFromEndpoint(ctx context.Context, mux *runtime.Serv
 
 // RegisterDiscoveryHandler registers the http handlers for service Discovery to "mux".
 // The handlers forward requests to the grpc endpoint over "conn".
-func RegisterDiscoveryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
+func RegisterDiscoveryHandler(ctx context.Context, mux *runtime.ServeMux, conn grpc.ClientConnInterface) error {
 	return RegisterDiscoveryHandlerClient(ctx, mux, NewDiscoveryClient(conn))
 }
 
diff --git a/api/discovery/discovery_grpc.pb.go b/api/discovery/discovery_grpc.pb.go
index 53e88366..e7e269a4 100644
--- a/api/discovery/discovery_grpc.pb.go
+++ b/api/discovery/discovery_grpc.pb.go
@@ -1,4 +1,8 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.2.0
+// - protoc             v3.19.4
+// source: discovery.proto
 
 package discovery
 
diff --git a/api/evidence/evidence.pb.go b/api/evidence/evidence.pb.go
index f19fd900..72243ca5 100644
--- a/api/evidence/evidence.pb.go
+++ b/api/evidence/evidence.pb.go
@@ -27,7 +27,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.1
+// 	protoc        v3.19.4
 // source: evidence.proto
 
 package evidence
diff --git a/api/evidence/evidence_store.pb.go b/api/evidence/evidence_store.pb.go
index 8ad837ba..c9b62e46 100644
--- a/api/evidence/evidence_store.pb.go
+++ b/api/evidence/evidence_store.pb.go
@@ -27,7 +27,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.1
+// 	protoc        v3.19.4
 // source: evidence_store.proto
 
 package evidence
diff --git a/api/evidence/evidence_store.pb.gw.go b/api/evidence/evidence_store.pb.gw.go
index baaf4839..6c53572c 100644
--- a/api/evidence/evidence_store.pb.gw.go
+++ b/api/evidence/evidence_store.pb.gw.go
@@ -165,7 +165,7 @@ func RegisterEvidenceStoreHandlerFromEndpoint(ctx context.Context, mux *runtime.
 
 // RegisterEvidenceStoreHandler registers the http handlers for service EvidenceStore to "mux".
 // The handlers forward requests to the grpc endpoint over "conn".
-func RegisterEvidenceStoreHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
+func RegisterEvidenceStoreHandler(ctx context.Context, mux *runtime.ServeMux, conn grpc.ClientConnInterface) error {
 	return RegisterEvidenceStoreHandlerClient(ctx, mux, NewEvidenceStoreClient(conn))
 }
 
diff --git a/api/evidence/evidence_store_grpc.pb.go b/api/evidence/evidence_store_grpc.pb.go
index b4feadaf..a2f7230c 100644
--- a/api/evidence/evidence_store_grpc.pb.go
+++ b/api/evidence/evidence_store_grpc.pb.go
@@ -1,4 +1,8 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.2.0
+// - protoc             v3.19.4
+// source: evidence_store.proto
 
 package evidence
 
diff --git a/api/orchestrator/orchestrator.pb.go b/api/orchestrator/orchestrator.pb.go
index f8b42bb9..72e91a44 100644
--- a/api/orchestrator/orchestrator.pb.go
+++ b/api/orchestrator/orchestrator.pb.go
@@ -27,7 +27,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.27.1
-// 	protoc        v3.19.1
+// 	protoc        v3.19.4
 // source: orchestrator.proto
 
 package orchestrator
diff --git a/api/orchestrator/orchestrator.pb.gw.go b/api/orchestrator/orchestrator.pb.gw.go
index 62ae314d..632bbd95 100644
--- a/api/orchestrator/orchestrator.pb.gw.go
+++ b/api/orchestrator/orchestrator.pb.gw.go
@@ -1223,7 +1223,7 @@ func RegisterOrchestratorHandlerFromEndpoint(ctx context.Context, mux *runtime.S
 
 // RegisterOrchestratorHandler registers the http handlers for service Orchestrator to "mux".
 // The handlers forward requests to the grpc endpoint over "conn".
-func RegisterOrchestratorHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
+func RegisterOrchestratorHandler(ctx context.Context, mux *runtime.ServeMux, conn grpc.ClientConnInterface) error {
 	return RegisterOrchestratorHandlerClient(ctx, mux, NewOrchestratorClient(conn))
 }
 
diff --git a/api/orchestrator/orchestrator_grpc.pb.go b/api/orchestrator/orchestrator_grpc.pb.go
index 67c041d3..3d7b0366 100644
--- a/api/orchestrator/orchestrator_grpc.pb.go
+++ b/api/orchestrator/orchestrator_grpc.pb.go
@@ -1,4 +1,8 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.2.0
+// - protoc             v3.19.4
+// source: orchestrator.proto
 
 package orchestrator
 
diff --git a/rest/rest.go b/rest/rest.go
index 0b970ea4..178aa620 100644
--- a/rest/rest.go
+++ b/rest/rest.go
@@ -171,14 +171,7 @@ func RunServer(ctx context.Context, grpcPort int, httpPort int, corsOpts ...CORS
 			break
 		}
 
-		ready <- false
-
-		_, cancel := context.WithTimeout(ctx, 5*time.Second)
-		defer cancel()
-
-		log.Printf("Shutting down REST gateway on :%d", httpPort)
-
-		_ = srv.Shutdown(ctx)
+		StopServer(ctx)
 	}()
 
 	log.Printf("Starting REST gateway on :%d", httpPort)
@@ -193,6 +186,22 @@ func RunServer(ctx context.Context, grpcPort int, httpPort int, corsOpts ...CORS
 	return srv.Serve(sock)
 }
 
+// StopServer is in charge of stopping the REST API.
+func StopServer(ctx context.Context) {
+	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
+	defer cancel()
+
+	log.Printf("Shutting down REST gateway")
+
+	// Clear our ready channel, otherwise, this will block the exit
+	select {
+	case <-ready:
+	default:
+	}
+
+	_ = srv.Shutdown(ctx)
+}
+
 // GetServerPort returns the actual port used by the REST API
 func GetServerPort() (int, error) {
 	if sock == nil {


Test patch:
diff --git a/rest/rest_test.go b/rest/rest_test.go
index 68e2421d..8231e6b5 100644
--- a/rest/rest_test.go
+++ b/rest/rest_test.go
@@ -27,6 +27,7 @@ package rest
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"net"
 	"net/http"
@@ -45,6 +46,8 @@ var (
 	origins = []string{"clouditor.io", "localhost"}
 	methods = []string{"GET", "POST"}
 	headers = DefaultAllowedHeaders
+
+	grpcPort int = 0
 )
 
 func TestMain(m *testing.M) {
@@ -66,26 +69,32 @@ func TestMain(m *testing.M) {
 		panic(err)
 	}
 
+	grpcPort = sock.Addr().(*net.TCPAddr).Port
+
+	exit := m.Run()
+
+	sock.Close()
+	server.Stop()
+
+	os.Exit(exit)
+}
+
+func TestCORS(t *testing.T) {
 	go func() {
 		err := RunServer(
 			context.Background(),
-			sock.Addr().(*net.TCPAddr).Port,
+			grpcPort,
 			0,
 			WithAllowedOrigins(origins),
 			WithAllowedMethods(methods),
 			WithAllowedHeaders(headers),
 		)
-		if err != nil {
+		if err != nil && !errors.Is(err, http.ErrServerClosed) {
 			panic(err)
 		}
 	}()
+	defer StopServer(context.Background())
 
-	defer sock.Close()
-	defer server.Stop()
-	defer os.Exit(m.Run())
-}
-
-func TestCORS(t *testing.T) {
 	// wait until server is ready to serve
 	select {
 	case <-ready: