github.com/bufbuild/connect-grpchealth-go@v1.1.1/grpchealth_test.go (about) 1 // Copyright 2022-2023 Buf Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package grpchealth 16 17 import ( 18 "context" 19 "errors" 20 "net/http" 21 "net/http/httptest" 22 "testing" 23 24 "github.com/bufbuild/connect-go" 25 healthv1 "github.com/bufbuild/connect-grpchealth-go/internal/gen/go/connectext/grpc/health/v1" 26 ) 27 28 func TestHealth(t *testing.T) { 29 const ( 30 userFQN = "acme.user.v1.UserService" 31 unknown = "foobar" 32 ) 33 t.Parallel() 34 mux := http.NewServeMux() 35 checker := NewStaticChecker(userFQN) 36 mux.Handle(NewHandler(checker)) 37 server := httptest.NewUnstartedServer(mux) 38 server.EnableHTTP2 = true 39 server.StartTLS() 40 t.Cleanup(server.Close) 41 42 client := connect.NewClient[healthv1.HealthCheckRequest, healthv1.HealthCheckResponse]( 43 server.Client(), 44 server.URL+"/grpc.health.v1.Health/Check", 45 connect.WithGRPC(), 46 ) 47 48 assertStatus := func( 49 t *testing.T, 50 service string, 51 expect Status, 52 ) { 53 t.Helper() 54 res, err := client.CallUnary( 55 context.Background(), 56 connect.NewRequest(&healthv1.HealthCheckRequest{Service: service}), 57 ) 58 if err != nil { 59 t.Fatalf(err.Error()) 60 } 61 if Status(res.Msg.Status) != expect { 62 t.Fatalf("got status %v, expected %v", res.Msg.Status, expect) 63 } 64 } 65 assertUnknown := func( 66 t *testing.T, 67 service string, 68 ) { 69 t.Helper() 70 _, err := client.CallUnary( 71 context.Background(), 72 connect.NewRequest(&healthv1.HealthCheckRequest{Service: service}), 73 ) 74 if err == nil { 75 t.Fatalf("expected error checking unknown service %q", service) 76 } 77 var connectErr *connect.Error 78 if ok := errors.As(err, &connectErr); !ok { 79 t.Fatalf("got %v (%T), expected a *connect.Error", err, err) 80 } 81 if code := connectErr.Code(); code != connect.CodeNotFound { 82 t.Fatalf("check %q: got code %v, expected CodeNotFound", service, code) 83 } 84 } 85 86 assertStatus(t, "" /* process */, StatusServing) 87 88 assertStatus(t, userFQN, StatusServing) 89 checker.SetStatus(userFQN, StatusNotServing) 90 assertStatus(t, userFQN, StatusNotServing) 91 92 assertUnknown(t, unknown) 93 checker.SetStatus(unknown, StatusServing) 94 assertStatus(t, unknown, StatusServing) 95 96 watcher := connect.NewClient[healthv1.HealthCheckRequest, healthv1.HealthCheckResponse]( 97 server.Client(), 98 server.URL+"/grpc.health.v1.Health/Watch", 99 connect.WithGRPC(), 100 ) 101 stream, err := watcher.CallServerStream( 102 context.Background(), 103 connect.NewRequest(&healthv1.HealthCheckRequest{Service: userFQN}), 104 ) 105 if err != nil { 106 t.Fatalf(err.Error()) 107 } 108 defer stream.Close() 109 if ok := stream.Receive(); ok { 110 t.Fatalf("got message from Watch") 111 } 112 if stream.Err() == nil { 113 t.Fatalf("expected error from stream") 114 } 115 var connectErr *connect.Error 116 if ok := errors.As(stream.Err(), &connectErr); !ok { 117 t.Fatalf("got %v (%T), expected a *connect.Error", err, err) 118 } 119 if code := connectErr.Code(); code != connect.CodeUnimplemented { 120 t.Fatalf("got code %v, expected CodeUnimplemented", code) 121 } 122 }