github.com/weaveworks/common@v0.0.0-20230728070032-dd9e68f319d5/server/server_test.go (about) 1 package server 2 3 import ( 4 "bytes" 5 "crypto/tls" 6 "crypto/x509" 7 "errors" 8 "flag" 9 "io" 10 "net/http" 11 "os" 12 "os/exec" 13 "strconv" 14 "testing" 15 "time" 16 17 "github.com/prometheus/client_golang/prometheus/testutil" 18 "google.golang.org/grpc" 19 "google.golang.org/grpc/credentials" 20 "google.golang.org/grpc/credentials/insecure" 21 "google.golang.org/grpc/status" 22 23 protobuf "github.com/golang/protobuf/ptypes/empty" 24 "github.com/gorilla/mux" 25 "github.com/prometheus/client_golang/prometheus" 26 "github.com/stretchr/testify/require" 27 "github.com/weaveworks/common/httpgrpc" 28 "github.com/weaveworks/common/logging" 29 "github.com/weaveworks/common/middleware" 30 "golang.org/x/net/context" 31 ) 32 33 type FakeServer struct{} 34 35 func (f FakeServer) FailWithError(_ context.Context, _ *protobuf.Empty) (*protobuf.Empty, error) { 36 return nil, errors.New("test error") 37 } 38 39 func (f FakeServer) FailWithHTTPError(_ context.Context, req *FailWithHTTPErrorRequest) (*protobuf.Empty, error) { 40 return nil, httpgrpc.Errorf(int(req.Code), strconv.Itoa(int(req.Code))) 41 } 42 43 func (f FakeServer) Succeed(_ context.Context, _ *protobuf.Empty) (*protobuf.Empty, error) { 44 return &protobuf.Empty{}, nil 45 } 46 47 func (f FakeServer) Sleep(ctx context.Context, _ *protobuf.Empty) (*protobuf.Empty, error) { 48 err := cancelableSleep(ctx, 10*time.Second) 49 return &protobuf.Empty{}, err 50 } 51 52 func (f FakeServer) StreamSleep(_ *protobuf.Empty, stream FakeServer_StreamSleepServer) error { 53 for x := 0; x < 100; x++ { 54 time.Sleep(time.Second / 100.0) 55 if err := stream.Send(&protobuf.Empty{}); err != nil { 56 return err 57 } 58 } 59 return nil 60 } 61 62 func cancelableSleep(ctx context.Context, sleep time.Duration) error { 63 select { 64 case <-time.After(sleep): 65 case <-ctx.Done(): 66 } 67 return ctx.Err() 68 } 69 70 func TestTCPv4Network(t *testing.T) { 71 cfg := Config{ 72 HTTPListenNetwork: NetworkTCPV4, 73 HTTPListenAddress: "localhost", 74 HTTPListenPort: 9290, 75 GRPCListenNetwork: NetworkTCPV4, 76 GRPCListenAddress: "localhost", 77 GRPCListenPort: 9291, 78 } 79 t.Run("http", func(t *testing.T) { 80 cfg.MetricsNamespace = "testing_http_tcp4" 81 srv, err := New(cfg) 82 require.NoError(t, err) 83 84 errChan := make(chan error, 1) 85 go func() { 86 errChan <- srv.Run() 87 }() 88 89 require.NoError(t, srv.httpListener.Close()) 90 require.NotNil(t, <-errChan) 91 92 // So that address is freed for further tests. 93 srv.GRPC.Stop() 94 }) 95 96 t.Run("grpc", func(t *testing.T) { 97 cfg.MetricsNamespace = "testing_grpc_tcp4" 98 srv, err := New(cfg) 99 require.NoError(t, err) 100 101 errChan := make(chan error, 1) 102 go func() { 103 errChan <- srv.Run() 104 }() 105 106 require.NoError(t, srv.grpcListener.Close()) 107 require.NotNil(t, <-errChan) 108 }) 109 } 110 111 // Ensure that http and grpc servers work with no overrides to config 112 // (except http port because an ordinary user can't bind to default port 80) 113 func TestDefaultAddresses(t *testing.T) { 114 var cfg Config 115 cfg.RegisterFlags(flag.NewFlagSet("", flag.ExitOnError)) 116 cfg.HTTPListenPort = 9090 117 cfg.MetricsNamespace = "testing_addresses" 118 119 server, err := New(cfg) 120 require.NoError(t, err) 121 122 fakeServer := FakeServer{} 123 RegisterFakeServerServer(server.GRPC, fakeServer) 124 125 server.HTTP.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) { 126 w.WriteHeader(204) 127 }) 128 129 go server.Run() 130 defer server.Shutdown() 131 132 conn, err := grpc.Dial("localhost:9095", grpc.WithTransportCredentials(insecure.NewCredentials())) 133 require.NoError(t, err) 134 defer conn.Close() 135 136 empty := protobuf.Empty{} 137 client := NewFakeServerClient(conn) 138 _, err = client.Succeed(context.Background(), &empty) 139 require.NoError(t, err) 140 141 req, err := http.NewRequest("GET", "http://127.0.0.1:9090/test", nil) 142 require.NoError(t, err) 143 _, err = http.DefaultClient.Do(req) 144 require.NoError(t, err) 145 } 146 147 func TestErrorInstrumentationMiddleware(t *testing.T) { 148 var cfg Config 149 cfg.RegisterFlags(flag.NewFlagSet("", flag.ExitOnError)) 150 cfg.HTTPListenPort = 9090 // can't use 80 as ordinary user 151 cfg.GRPCListenAddress = "localhost" 152 cfg.GRPCListenPort = 1234 153 server, err := New(cfg) 154 require.NoError(t, err) 155 156 fakeServer := FakeServer{} 157 RegisterFakeServerServer(server.GRPC, fakeServer) 158 159 server.HTTP.HandleFunc("/succeed", func(w http.ResponseWriter, r *http.Request) { 160 }) 161 server.HTTP.HandleFunc("/error500", func(w http.ResponseWriter, r *http.Request) { 162 w.WriteHeader(500) 163 }) 164 server.HTTP.HandleFunc("/sleep10", func(w http.ResponseWriter, r *http.Request) { 165 _ = cancelableSleep(r.Context(), time.Second*10) 166 }) 167 server.HTTP.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 168 w.WriteHeader(http.StatusNotFound) 169 }) 170 171 go server.Run() 172 173 conn, err := grpc.Dial("localhost:1234", grpc.WithTransportCredentials(insecure.NewCredentials())) 174 require.NoError(t, err) 175 defer conn.Close() 176 177 empty := protobuf.Empty{} 178 client := NewFakeServerClient(conn) 179 res, err := client.Succeed(context.Background(), &empty) 180 require.NoError(t, err) 181 require.EqualValues(t, &empty, res) 182 183 res, err = client.FailWithError(context.Background(), &empty) 184 require.Nil(t, res) 185 require.Error(t, err) 186 187 s, ok := status.FromError(err) 188 require.True(t, ok) 189 require.Equal(t, "test error", s.Message()) 190 191 res, err = client.FailWithHTTPError(context.Background(), &FailWithHTTPErrorRequest{Code: http.StatusPaymentRequired}) 192 require.Nil(t, res) 193 errResp, ok := httpgrpc.HTTPResponseFromError(err) 194 require.True(t, ok) 195 require.Equal(t, int32(http.StatusPaymentRequired), errResp.Code) 196 require.Equal(t, "402", string(errResp.Body)) 197 198 callThenCancel := func(f func(ctx context.Context) error) error { 199 ctx, cancel := context.WithCancel(context.Background()) 200 errChan := make(chan error, 1) 201 go func() { 202 errChan <- f(ctx) 203 }() 204 time.Sleep(50 * time.Millisecond) // allow the call to reach the handler 205 cancel() 206 return <-errChan 207 } 208 209 err = callThenCancel(func(ctx context.Context) error { 210 _, err = client.Sleep(ctx, &empty) 211 return err 212 }) 213 require.Error(t, err, context.Canceled) 214 215 err = callThenCancel(func(ctx context.Context) error { 216 _, err = client.StreamSleep(ctx, &empty) 217 return err 218 }) 219 require.NoError(t, err) // canceling a streaming fn doesn't generate an error 220 221 // Now test the HTTP versions of the functions 222 { 223 req, err := http.NewRequest("GET", "http://127.0.0.1:9090/succeed", nil) 224 require.NoError(t, err) 225 _, err = http.DefaultClient.Do(req) 226 require.NoError(t, err) 227 } 228 { 229 req, err := http.NewRequest("GET", "http://127.0.0.1:9090/error500", nil) 230 require.NoError(t, err) 231 _, err = http.DefaultClient.Do(req) 232 require.NoError(t, err) 233 } 234 { 235 req, err := http.NewRequest("GET", "http://127.0.0.1:9090/notfound", nil) 236 require.NoError(t, err) 237 _, err = http.DefaultClient.Do(req) 238 require.NoError(t, err) 239 } 240 { 241 req, err := http.NewRequest("GET", "http://127.0.0.1:9090/sleep10", nil) 242 require.NoError(t, err) 243 err = callThenCancel(func(ctx context.Context) error { 244 _, err = http.DefaultClient.Do(req.WithContext(ctx)) 245 return err 246 }) 247 require.Error(t, err, context.Canceled) 248 } 249 250 require.NoError(t, conn.Close()) 251 server.Shutdown() 252 253 metrics, err := prometheus.DefaultGatherer.Gather() 254 require.NoError(t, err) 255 256 statuses := map[string]string{} 257 for _, family := range metrics { 258 if *family.Name == "request_duration_seconds" { 259 for _, metric := range family.Metric { 260 var route, statusCode string 261 for _, label := range metric.GetLabel() { 262 switch label.GetName() { 263 case "status_code": 264 statusCode = label.GetValue() 265 case "route": 266 route = label.GetValue() 267 } 268 } 269 statuses[route] = statusCode 270 } 271 } 272 } 273 require.Equal(t, map[string]string{ 274 "/server.FakeServer/FailWithError": "error", 275 "/server.FakeServer/FailWithHTTPError": "402", 276 "/server.FakeServer/Sleep": "cancel", 277 "/server.FakeServer/StreamSleep": "cancel", 278 "/server.FakeServer/Succeed": "success", 279 "error500": "500", 280 "sleep10": "200", 281 "succeed": "200", 282 "notfound": "404", 283 }, statuses) 284 } 285 286 func TestHTTPInstrumentationMetrics(t *testing.T) { 287 reg := prometheus.NewRegistry() 288 prometheus.DefaultRegisterer = reg 289 prometheus.DefaultGatherer = reg 290 291 var cfg Config 292 cfg.RegisterFlags(flag.NewFlagSet("", flag.ExitOnError)) 293 cfg.HTTPListenPort = 9090 // can't use 80 as ordinary user 294 cfg.GRPCListenAddress = "localhost" 295 cfg.GRPCListenPort = 1234 296 server, err := New(cfg) 297 require.NoError(t, err) 298 299 server.HTTP.HandleFunc("/succeed", func(w http.ResponseWriter, r *http.Request) { 300 _, _ = w.Write([]byte("OK")) 301 }) 302 server.HTTP.HandleFunc("/error500", func(w http.ResponseWriter, r *http.Request) { 303 w.WriteHeader(500) 304 }) 305 server.HTTP.HandleFunc("/sleep10", func(w http.ResponseWriter, r *http.Request) { 306 _, _ = io.Copy(io.Discard, r.Body) // Consume body, otherwise it's not counted. 307 _ = cancelableSleep(r.Context(), time.Second*10) 308 }) 309 310 go server.Run() 311 312 callThenCancel := func(f func(ctx context.Context) error) error { 313 ctx, cancel := context.WithCancel(context.Background()) 314 errChan := make(chan error, 1) 315 go func() { 316 errChan <- f(ctx) 317 }() 318 time.Sleep(50 * time.Millisecond) // allow the call to reach the handler 319 cancel() 320 return <-errChan 321 } 322 323 // Now test the HTTP versions of the functions 324 { 325 req, err := http.NewRequest("GET", "http://127.0.0.1:9090/succeed", nil) 326 require.NoError(t, err) 327 resp, err := http.DefaultClient.Do(req) 328 require.NoError(t, err) 329 body, err := io.ReadAll(resp.Body) 330 require.NoError(t, err) 331 require.Equal(t, "OK", string(body)) 332 } 333 { 334 req, err := http.NewRequest("GET", "http://127.0.0.1:9090/error500", nil) 335 require.NoError(t, err) 336 _, err = http.DefaultClient.Do(req) 337 require.NoError(t, err) 338 } 339 { 340 req, err := http.NewRequest("POST", "http://127.0.0.1:9090/sleep10", bytes.NewReader([]byte("Body"))) 341 require.NoError(t, err) 342 err = callThenCancel(func(ctx context.Context) error { 343 _, err = http.DefaultClient.Do(req.WithContext(ctx)) 344 return err 345 }) 346 require.Error(t, err, context.Canceled) 347 } 348 349 server.Shutdown() 350 351 require.NoError(t, testutil.GatherAndCompare(prometheus.DefaultGatherer, bytes.NewBufferString(` 352 # HELP inflight_requests Current number of inflight requests. 353 # TYPE inflight_requests gauge 354 inflight_requests{method="POST",route="sleep10"} 0 355 inflight_requests{method="GET",route="succeed"} 0 356 inflight_requests{method="GET",route="error500"} 0 357 358 # HELP request_message_bytes Size (in bytes) of messages received in the request. 359 # TYPE request_message_bytes histogram 360 request_message_bytes_bucket{method="GET",route="error500",le="1.048576e+06"} 1 361 request_message_bytes_bucket{method="GET",route="error500",le="2.62144e+06"} 1 362 request_message_bytes_bucket{method="GET",route="error500",le="5.24288e+06"} 1 363 request_message_bytes_bucket{method="GET",route="error500",le="1.048576e+07"} 1 364 request_message_bytes_bucket{method="GET",route="error500",le="2.62144e+07"} 1 365 request_message_bytes_bucket{method="GET",route="error500",le="5.24288e+07"} 1 366 request_message_bytes_bucket{method="GET",route="error500",le="1.048576e+08"} 1 367 request_message_bytes_bucket{method="GET",route="error500",le="2.62144e+08"} 1 368 request_message_bytes_bucket{method="GET",route="error500",le="+Inf"} 1 369 request_message_bytes_sum{method="GET",route="error500"} 0 370 request_message_bytes_count{method="GET",route="error500"} 1 371 372 request_message_bytes_bucket{method="POST",route="sleep10",le="1.048576e+06"} 1 373 request_message_bytes_bucket{method="POST",route="sleep10",le="2.62144e+06"} 1 374 request_message_bytes_bucket{method="POST",route="sleep10",le="5.24288e+06"} 1 375 request_message_bytes_bucket{method="POST",route="sleep10",le="1.048576e+07"} 1 376 request_message_bytes_bucket{method="POST",route="sleep10",le="2.62144e+07"} 1 377 request_message_bytes_bucket{method="POST",route="sleep10",le="5.24288e+07"} 1 378 request_message_bytes_bucket{method="POST",route="sleep10",le="1.048576e+08"} 1 379 request_message_bytes_bucket{method="POST",route="sleep10",le="2.62144e+08"} 1 380 request_message_bytes_bucket{method="POST",route="sleep10",le="+Inf"} 1 381 request_message_bytes_sum{method="POST",route="sleep10"} 4 382 request_message_bytes_count{method="POST",route="sleep10"} 1 383 384 request_message_bytes_bucket{method="GET",route="succeed",le="1.048576e+06"} 1 385 request_message_bytes_bucket{method="GET",route="succeed",le="2.62144e+06"} 1 386 request_message_bytes_bucket{method="GET",route="succeed",le="5.24288e+06"} 1 387 request_message_bytes_bucket{method="GET",route="succeed",le="1.048576e+07"} 1 388 request_message_bytes_bucket{method="GET",route="succeed",le="2.62144e+07"} 1 389 request_message_bytes_bucket{method="GET",route="succeed",le="5.24288e+07"} 1 390 request_message_bytes_bucket{method="GET",route="succeed",le="1.048576e+08"} 1 391 request_message_bytes_bucket{method="GET",route="succeed",le="2.62144e+08"} 1 392 request_message_bytes_bucket{method="GET",route="succeed",le="+Inf"} 1 393 request_message_bytes_sum{method="GET",route="succeed"} 0 394 request_message_bytes_count{method="GET",route="succeed"} 1 395 396 # HELP response_message_bytes Size (in bytes) of messages sent in response. 397 # TYPE response_message_bytes histogram 398 response_message_bytes_bucket{method="GET",route="error500",le="1.048576e+06"} 1 399 response_message_bytes_bucket{method="GET",route="error500",le="2.62144e+06"} 1 400 response_message_bytes_bucket{method="GET",route="error500",le="5.24288e+06"} 1 401 response_message_bytes_bucket{method="GET",route="error500",le="1.048576e+07"} 1 402 response_message_bytes_bucket{method="GET",route="error500",le="2.62144e+07"} 1 403 response_message_bytes_bucket{method="GET",route="error500",le="5.24288e+07"} 1 404 response_message_bytes_bucket{method="GET",route="error500",le="1.048576e+08"} 1 405 response_message_bytes_bucket{method="GET",route="error500",le="2.62144e+08"} 1 406 response_message_bytes_bucket{method="GET",route="error500",le="+Inf"} 1 407 response_message_bytes_sum{method="GET",route="error500"} 0 408 response_message_bytes_count{method="GET",route="error500"} 1 409 410 response_message_bytes_bucket{method="POST",route="sleep10",le="1.048576e+06"} 1 411 response_message_bytes_bucket{method="POST",route="sleep10",le="2.62144e+06"} 1 412 response_message_bytes_bucket{method="POST",route="sleep10",le="5.24288e+06"} 1 413 response_message_bytes_bucket{method="POST",route="sleep10",le="1.048576e+07"} 1 414 response_message_bytes_bucket{method="POST",route="sleep10",le="2.62144e+07"} 1 415 response_message_bytes_bucket{method="POST",route="sleep10",le="5.24288e+07"} 1 416 response_message_bytes_bucket{method="POST",route="sleep10",le="1.048576e+08"} 1 417 response_message_bytes_bucket{method="POST",route="sleep10",le="2.62144e+08"} 1 418 response_message_bytes_bucket{method="POST",route="sleep10",le="+Inf"} 1 419 response_message_bytes_sum{method="POST",route="sleep10"} 0 420 response_message_bytes_count{method="POST",route="sleep10"} 1 421 422 response_message_bytes_bucket{method="GET",route="succeed",le="1.048576e+06"} 1 423 response_message_bytes_bucket{method="GET",route="succeed",le="2.62144e+06"} 1 424 response_message_bytes_bucket{method="GET",route="succeed",le="5.24288e+06"} 1 425 response_message_bytes_bucket{method="GET",route="succeed",le="1.048576e+07"} 1 426 response_message_bytes_bucket{method="GET",route="succeed",le="2.62144e+07"} 1 427 response_message_bytes_bucket{method="GET",route="succeed",le="5.24288e+07"} 1 428 response_message_bytes_bucket{method="GET",route="succeed",le="1.048576e+08"} 1 429 response_message_bytes_bucket{method="GET",route="succeed",le="2.62144e+08"} 1 430 response_message_bytes_bucket{method="GET",route="succeed",le="+Inf"} 1 431 response_message_bytes_sum{method="GET",route="succeed"} 2 432 response_message_bytes_count{method="GET",route="succeed"} 1 433 434 # HELP tcp_connections Current number of accepted TCP connections. 435 # TYPE tcp_connections gauge 436 tcp_connections{protocol="http"} 0 437 tcp_connections{protocol="grpc"} 0 438 `), "request_message_bytes", "response_message_bytes", "inflight_requests", "tcp_connections")) 439 } 440 441 func TestRunReturnsError(t *testing.T) { 442 cfg := Config{ 443 HTTPListenNetwork: DefaultNetwork, 444 HTTPListenAddress: "localhost", 445 HTTPListenPort: 9090, 446 GRPCListenNetwork: DefaultNetwork, 447 GRPCListenAddress: "localhost", 448 GRPCListenPort: 9191, 449 } 450 t.Run("http", func(t *testing.T) { 451 cfg.MetricsNamespace = "testing_http" 452 srv, err := New(cfg) 453 require.NoError(t, err) 454 455 errChan := make(chan error, 1) 456 go func() { 457 errChan <- srv.Run() 458 }() 459 460 require.NoError(t, srv.httpListener.Close()) 461 require.NotNil(t, <-errChan) 462 463 // So that address is freed for further tests. 464 srv.GRPC.Stop() 465 }) 466 467 t.Run("grpc", func(t *testing.T) { 468 cfg.MetricsNamespace = "testing_grpc" 469 srv, err := New(cfg) 470 require.NoError(t, err) 471 472 errChan := make(chan error, 1) 473 go func() { 474 errChan <- srv.Run() 475 }() 476 477 require.NoError(t, srv.grpcListener.Close()) 478 require.NotNil(t, <-errChan) 479 }) 480 } 481 482 // Test to see what the logging of a 500 error looks like 483 func TestMiddlewareLogging(t *testing.T) { 484 var level logging.Level 485 require.NoError(t, level.Set("info")) 486 cfg := Config{ 487 HTTPListenNetwork: DefaultNetwork, 488 HTTPListenAddress: "localhost", 489 HTTPListenPort: 9192, 490 GRPCListenNetwork: DefaultNetwork, 491 GRPCListenAddress: "localhost", 492 HTTPMiddleware: []middleware.Interface{middleware.Logging}, 493 MetricsNamespace: "testing_logging", 494 LogLevel: level, 495 DoNotAddDefaultHTTPMiddleware: true, 496 Router: &mux.Router{}, 497 } 498 server, err := New(cfg) 499 require.NoError(t, err) 500 501 server.HTTP.HandleFunc("/error500", func(w http.ResponseWriter, r *http.Request) { 502 w.WriteHeader(500) 503 }) 504 505 go server.Run() 506 defer server.Shutdown() 507 508 req, err := http.NewRequest("GET", "http://127.0.0.1:9192/error500", nil) 509 require.NoError(t, err) 510 _, err = http.DefaultClient.Do(req) 511 require.NoError(t, err) 512 } 513 514 func TestTLSServer(t *testing.T) { 515 var level logging.Level 516 require.NoError(t, level.Set("info")) 517 518 cmd := exec.Command("bash", "certs/genCerts.sh", "certs", "1") 519 err := cmd.Run() 520 require.NoError(t, err) 521 522 cfg := Config{ 523 HTTPListenNetwork: DefaultNetwork, 524 HTTPListenAddress: "localhost", 525 HTTPListenPort: 9193, 526 HTTPTLSConfig: TLSConfig{ 527 TLSCertPath: "certs/server.crt", 528 TLSKeyPath: "certs/server.key", 529 ClientAuth: "RequireAndVerifyClientCert", 530 ClientCAs: "certs/root.crt", 531 }, 532 GRPCTLSConfig: TLSConfig{ 533 TLSCertPath: "certs/server.crt", 534 TLSKeyPath: "certs/server.key", 535 ClientAuth: "VerifyClientCertIfGiven", 536 ClientCAs: "certs/root.crt", 537 }, 538 MetricsNamespace: "testing_tls", 539 GRPCListenNetwork: DefaultNetwork, 540 GRPCListenAddress: "localhost", 541 GRPCListenPort: 9194, 542 } 543 server, err := New(cfg) 544 require.NoError(t, err) 545 546 server.HTTP.HandleFunc("/testhttps", func(w http.ResponseWriter, r *http.Request) { 547 w.Write([]byte("Hello World!")) 548 }) 549 550 fakeServer := FakeServer{} 551 RegisterFakeServerServer(server.GRPC, fakeServer) 552 553 go server.Run() 554 defer server.Shutdown() 555 556 clientCert, err := tls.LoadX509KeyPair("certs/client.crt", "certs/client.key") 557 require.NoError(t, err) 558 559 caCert, err := os.ReadFile(cfg.HTTPTLSConfig.ClientCAs) 560 require.NoError(t, err) 561 562 caCertPool := x509.NewCertPool() 563 caCertPool.AppendCertsFromPEM(caCert) 564 565 tlsConfig := &tls.Config{ 566 InsecureSkipVerify: true, 567 Certificates: []tls.Certificate{clientCert}, 568 RootCAs: caCertPool, 569 } 570 tr := &http.Transport{ 571 TLSClientConfig: tlsConfig, 572 } 573 574 client := &http.Client{Transport: tr} 575 res, err := client.Get("https://localhost:9193/testhttps") 576 require.NoError(t, err) 577 defer res.Body.Close() 578 579 require.Equal(t, res.StatusCode, http.StatusOK) 580 581 body, err := io.ReadAll(res.Body) 582 require.NoError(t, err) 583 expected := []byte("Hello World!") 584 require.Equal(t, expected, body) 585 586 conn, err := grpc.Dial("localhost:9194", grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig))) 587 require.NoError(t, err) 588 defer conn.Close() 589 590 empty := protobuf.Empty{} 591 grpcClient := NewFakeServerClient(conn) 592 grpcRes, err := grpcClient.Succeed(context.Background(), &empty) 593 require.NoError(t, err) 594 require.EqualValues(t, &empty, grpcRes) 595 } 596 597 type FakeLogger struct { 598 sourceIPs string 599 } 600 601 func (f *FakeLogger) Debugf(_ string, _ ...interface{}) {} 602 func (f *FakeLogger) Debugln(_ ...interface{}) {} 603 604 func (f *FakeLogger) Infof(_ string, _ ...interface{}) {} 605 func (f *FakeLogger) Infoln(_ ...interface{}) {} 606 607 func (f *FakeLogger) Errorf(_ string, _ ...interface{}) {} 608 func (f *FakeLogger) Errorln(_ ...interface{}) {} 609 610 func (f *FakeLogger) Warnf(_ string, _ ...interface{}) {} 611 func (f *FakeLogger) Warnln(_ ...interface{}) {} 612 613 func (f *FakeLogger) WithField(key string, value interface{}) logging.Interface { 614 if key == "sourceIPs" { 615 f.sourceIPs = value.(string) 616 } 617 618 return f 619 } 620 621 func (f *FakeLogger) WithFields(_ logging.Fields) logging.Interface { 622 return f 623 } 624 625 func TestLogSourceIPs(t *testing.T) { 626 var level logging.Level 627 require.NoError(t, level.Set("debug")) 628 fake := FakeLogger{} 629 cfg := Config{ 630 HTTPListenNetwork: DefaultNetwork, 631 HTTPListenAddress: "localhost", 632 HTTPListenPort: 9195, 633 GRPCListenNetwork: DefaultNetwork, 634 GRPCListenAddress: "localhost", 635 HTTPMiddleware: []middleware.Interface{middleware.Logging}, 636 MetricsNamespace: "testing_mux", 637 LogLevel: level, 638 Log: &fake, 639 LogSourceIPs: true, 640 } 641 server, err := New(cfg) 642 require.NoError(t, err) 643 644 server.HTTP.HandleFunc("/error500", func(w http.ResponseWriter, r *http.Request) { 645 w.WriteHeader(500) 646 }) 647 648 go server.Run() 649 defer server.Shutdown() 650 651 require.Empty(t, fake.sourceIPs) 652 653 req, err := http.NewRequest("GET", "http://127.0.0.1:9195/error500", nil) 654 require.NoError(t, err) 655 _, err = http.DefaultClient.Do(req) 656 require.NoError(t, err) 657 658 require.Equal(t, fake.sourceIPs, "127.0.0.1") 659 } 660 661 func TestStopWithDisabledSignalHandling(t *testing.T) { 662 cfg := Config{ 663 HTTPListenNetwork: DefaultNetwork, 664 HTTPListenAddress: "localhost", 665 HTTPListenPort: 9198, 666 GRPCListenNetwork: DefaultNetwork, 667 GRPCListenAddress: "localhost", 668 GRPCListenPort: 9199, 669 } 670 671 var test = func(t *testing.T, metricsNamespace string, handler SignalHandler) { 672 cfg.SignalHandler = handler 673 cfg.MetricsNamespace = metricsNamespace 674 srv, err := New(cfg) 675 require.NoError(t, err) 676 677 errChan := make(chan error, 1) 678 go func() { 679 errChan <- srv.Run() 680 }() 681 682 srv.Stop() 683 require.Nil(t, <-errChan) 684 685 // So that addresses is freed for further tests. 686 srv.Shutdown() 687 } 688 689 t.Run("signals_enabled", func(t *testing.T) { 690 test(t, "signals_enabled", nil) 691 }) 692 693 t.Run("signals_disabled", func(t *testing.T) { 694 test(t, "signals_disabled", dummyHandler{quit: make(chan struct{})}) 695 }) 696 } 697 698 type dummyHandler struct { 699 quit chan struct{} 700 } 701 702 func (dh dummyHandler) Loop() { 703 <-dh.quit 704 } 705 706 func (dh dummyHandler) Stop() { 707 close(dh.quit) 708 }