// NewServer creates a new in-memory fake server implementing the logging service. // It returns the address of the server. func NewServer() (string, error) { srv, err := testutil.NewServer() if err != nil { return "", err } logpb.RegisterLoggingServiceV2Server(srv.Gsrv, &loggingHandler{ logs: make(map[string][]*logpb.LogEntry), }) logpb.RegisterConfigServiceV2Server(srv.Gsrv, &configHandler{ sinks: make(map[string]*logpb.LogSink), }) logpb.RegisterMetricsServiceV2Server(srv.Gsrv, &metricHandler{ metrics: make(map[string]*logpb.LogMetric), }) srv.Start() return srv.Addr, nil }
// makeRequests makes some requests. // req is an incoming request used to construct the trace. traceClient is the // client used to upload the trace. rt is the trace client's http client's // transport. This is used to retrieve the trace uploaded by the client, if // any. If expectTrace is true, we expect a trace will be uploaded. If // synchronous is true, the call to Finish is expected not to return before the // client has uploaded any traces. func makeRequests(t *testing.T, req *http.Request, traceClient *Client, rt *fakeRoundTripper, synchronous bool, expectTrace bool) *http.Request { span := traceClient.SpanFromRequest(req) ctx := NewContext(context.Background(), span) // An HTTP request. { req2, err := http.NewRequest("GET", "http://example.com/bar", nil) if err != nil { t.Fatal(err) } resp := &http.Response{StatusCode: 200} s := span.NewRemoteChild(req2) s.Finish(WithResponse(resp)) } // An autogenerated API call. { rt := &fakeRoundTripper{reqc: make(chan *http.Request, 1)} hc := &http.Client{Transport: rt} computeClient, err := compute.New(hc) if err != nil { t.Fatal(err) } _, err = computeClient.Zones.List(testProjectID).Context(ctx).Do() if err != nil { t.Fatal(err) } } // A cloud library call that uses the autogenerated API. { rt := &fakeRoundTripper{reqc: make(chan *http.Request, 1)} hc := &http.Client{Transport: rt} storageClient, err := storage.NewClient(context.Background(), option.WithHTTPClient(hc)) if err != nil { t.Fatal(err) } var objAttrsList []*storage.ObjectAttrs it := storageClient.Bucket("testbucket").Objects(ctx, nil) for { objAttrs, err := it.Next() if err != nil && err != iterator.Done { t.Fatal(err) } if err == iterator.Done { break } objAttrsList = append(objAttrsList, objAttrs) } } // A cloud library call that uses grpc internally. for _, fail := range []bool{false, true} { srv, err := testutil.NewServer() if err != nil { t.Fatalf("creating test datastore server: %v", err) } dspb.RegisterDatastoreServer(srv.Gsrv, &fakeDatastoreServer{fail: fail}) srv.Start() conn, err := grpc.Dial(srv.Addr, grpc.WithInsecure(), EnableGRPCTracingDialOption) if err != nil { t.Fatalf("connecting to test datastore server: %v", err) } datastoreClient, err := datastore.NewClient(ctx, testProjectID, option.WithGRPCConn(conn)) if err != nil { t.Fatalf("creating datastore client: %v", err) } k := datastore.NameKey("Entity", "stringID", nil) e := new(datastore.Entity) datastoreClient.Get(ctx, k, e) } done := make(chan struct{}) go func() { if synchronous { err := span.FinishWait() if err != nil { t.Errorf("Unexpected error from span.FinishWait: %v", err) } } else { span.Finish() } done <- struct{}{} }() if !expectTrace { <-done select { case <-rt.reqc: t.Errorf("Got a trace, expected none.") case <-time.After(5 * time.Millisecond): } return nil } else if !synchronous { <-done return <-rt.reqc } else { select { case <-done: t.Errorf("Synchronous Finish didn't wait for trace upload.") return <-rt.reqc case <-time.After(5 * time.Millisecond): r := <-rt.reqc <-done return r } } }