runDisconnectLabelTest sets up a pickfirst balancer and a basic OpenTelemetry environment to test the "grpc.disconnect_error" label on subchannel disconnections. It establishes a connection to a test server, makes an RPC, and then invokes triggerFunc to simulate a specific disconnection scenario. t
(t *testing.T, wantLabel string, triggerFunc func(*stubserver.StubServer, *controllableConn))
| 362 | // (e.g. graceful shutdown, connection reset) that results in the emission of the |
| 363 | // wantLabel metric. |
| 364 | func runDisconnectLabelTest(t *testing.T, wantLabel string, triggerFunc func(*stubserver.StubServer, *controllableConn)) { |
| 365 | ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) |
| 366 | defer cancel() |
| 367 | |
| 368 | ss := stubserver.StartTestService(t, nil) |
| 369 | defer ss.Stop() |
| 370 | |
| 371 | r := manual.NewBuilderWithScheme("whatever") |
| 372 | r.InitialState(resolver.State{ |
| 373 | ServiceConfig: internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(pfConfig), |
| 374 | Addresses: []resolver.Address{{Addr: ss.Address}}, |
| 375 | }) |
| 376 | |
| 377 | reader := metric.NewManualReader() |
| 378 | provider := metric.NewMeterProvider(metric.WithReader(reader)) |
| 379 | mo := opentelemetry.MetricsOptions{ |
| 380 | MeterProvider: provider, |
| 381 | Metrics: opentelemetry.DefaultMetrics().Add("grpc.subchannel.disconnections"), |
| 382 | OptionalLabels: []string{"grpc.disconnect_error"}, |
| 383 | } |
| 384 | |
| 385 | connCh := make(chan *controllableConn, 1) |
| 386 | dialer := func(ctx context.Context, addr string) (net.Conn, error) { |
| 387 | conn, err := (&net.Dialer{}).DialContext(ctx, "tcp", addr) |
| 388 | if err != nil { |
| 389 | return nil, err |
| 390 | } |
| 391 | cc := &controllableConn{Conn: conn} |
| 392 | select { |
| 393 | case connCh <- cc: |
| 394 | case <-ctx.Done(): |
| 395 | return nil, ctx.Err() |
| 396 | } |
| 397 | return cc, nil |
| 398 | } |
| 399 | |
| 400 | grpcTarget := r.Scheme() + ":///" |
| 401 | cc, err := grpc.NewClient(grpcTarget, opentelemetry.DialOption(opentelemetry.Options{MetricsOptions: mo}), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithResolvers(r), grpc.WithContextDialer(dialer)) |
| 402 | if err != nil { |
| 403 | t.Fatalf("NewClient() failed: %v", err) |
| 404 | } |
| 405 | defer cc.Close() |
| 406 | |
| 407 | tsc := testgrpc.NewTestServiceClient(cc) |
| 408 | // Ensure connected |
| 409 | if _, err := tsc.EmptyCall(ctx, &testpb.Empty{}); err != nil { |
| 410 | t.Fatalf("EmptyCall() failed: %v", err) |
| 411 | } |
| 412 | |
| 413 | var lc *controllableConn |
| 414 | select { |
| 415 | case lc = <-connCh: |
| 416 | case <-ctx.Done(): |
| 417 | t.Fatalf("Timed out waiting for connection from dialer: %v", ctx.Err()) |
| 418 | } |
| 419 | |
| 420 | // Trigger disconnection |
| 421 | triggerFunc(ss, lc) |
no test coverage detected