func TestClientWithMisbehavedServer(t *testing.T) { server, ct := setUp(t, 0, math.MaxUint32, misbehaved) callHdr := &CallHdr{ Host: "localhost", Method: "foo", } conn, ok := ct.(*http2Client) if !ok { t.Fatalf("Failed to convert %v to *http2Client", ct) } // Test the logic for the violation of stream flow control window size restriction. s, err := ct.NewStream(context.Background(), callHdr) if err != nil { t.Fatalf("Failed to open stream: %v", err) } if err := ct.Write(s, expectedRequest, &Options{Last: true, Delay: false}); err != nil { t.Fatalf("Failed to write: %v", err) } // Read without window update. for { p := make([]byte, http2MaxFrameLen) if _, err = s.dec.Read(p); err != nil { break } } if s.fc.pendingData != initialWindowSize || s.fc.pendingUpdate != 0 || conn.fc.pendingData != initialWindowSize || conn.fc.pendingUpdate != 0 { t.Fatalf("Client mistakenly updates inbound flow control params: got %d, %d, %d, %d; want %d, %d, %d, %d", s.fc.pendingData, s.fc.pendingUpdate, conn.fc.pendingData, conn.fc.pendingUpdate, initialWindowSize, 0, initialWindowSize, 0) } if err != io.EOF || s.statusCode != codes.Internal { t.Fatalf("Got err %v and the status code %d, want <EOF> and the code %d", err, s.statusCode, codes.Internal) } conn.CloseStream(s, err) if s.fc.pendingData != 0 || s.fc.pendingUpdate != 0 || conn.fc.pendingData != 0 || conn.fc.pendingUpdate != initialWindowSize { t.Fatalf("Client mistakenly resets inbound flow control params: got %d, %d, %d, %d; want 0, 0, 0, %d", s.fc.pendingData, s.fc.pendingUpdate, conn.fc.pendingData, conn.fc.pendingUpdate, initialWindowSize) } // Test the logic for the violation of the connection flow control window size restriction. // // Generate enough streams to drain the connection window. callHdr = &CallHdr{ Host: "localhost", Method: "foo.MaxFrame", } for i := 0; i < int(initialConnWindowSize/initialWindowSize+10); i++ { s, err := ct.NewStream(context.Background(), callHdr) if err != nil { break } if err := ct.Write(s, expectedRequest, &Options{Last: true, Delay: false}); err != nil { break } } // http2Client.errChan is closed due to connection flow control window size violation. <-conn.Error() ct.Close() server.stop() }
func TestAPIServiceListInspectImages(t *testing.T) { ctx := testutils.NewRktRunCtx() defer ctx.Cleanup() svc := startAPIService(t, ctx) defer stopAPIService(t, svc) c, conn := newAPIClientOrFail(t, "localhost:15441") defer conn.Close() resp, err := c.ListImages(context.Background(), &v1alpha.ListImagesRequest{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } if len(resp.Images) != 0 { t.Errorf("Unexpected result: %v, should see zero images", resp.Images) } patchImportAndFetchHash("rkt-inspect-sleep.aci", []string{"--exec=/inspect"}, t, ctx) // ListImages(detail=false). resp, err = c.ListImages(context.Background(), &v1alpha.ListImagesRequest{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } if len(resp.Images) == 0 { t.Errorf("Unexpected result: %v, should see non-zero images", resp.Images) } for _, m := range resp.Images { checkImageBasics(t, ctx, m) // Test InspectImage(). inspectResp, err := c.InspectImage(context.Background(), &v1alpha.InspectImageRequest{Id: m.Id}) if err != nil { t.Fatalf("Unexpected error: %v", err) } checkImageDetails(t, ctx, inspectResp.Image) } // ListImages(detail=true). resp, err = c.ListImages(context.Background(), &v1alpha.ListImagesRequest{Detail: true}) if err != nil { t.Fatalf("Unexpected error: %v", err) } if len(resp.Images) == 0 { t.Errorf("Unexpected result: %v, should see non-zero images", resp.Images) } for _, m := range resp.Images { checkImageDetails(t, ctx, m) } }
func TestAPIServiceListInspectPods(t *testing.T) { ctx := testutils.NewRktRunCtx() defer ctx.Cleanup() svc := startAPIService(t, ctx) defer stopAPIService(t, svc) c, conn := newAPIClientOrFail(t, "localhost:15441") defer conn.Close() resp, err := c.ListPods(context.Background(), &v1alpha.ListPodsRequest{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } if len(resp.Pods) != 0 { t.Errorf("Unexpected result: %v, should see zero pods", resp.Pods) } patchImportAndRun("rkt-inspect-print.aci", []string{"--exec=/inspect --print-msg=HELLO_API --exit-code=42"}, t, ctx) // ListPods(detail=false). resp, err = c.ListPods(context.Background(), &v1alpha.ListPodsRequest{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } if len(resp.Pods) == 0 { t.Errorf("Unexpected result: %v, should see non-zero pods", resp.Pods) } for _, p := range resp.Pods { checkPodBasics(t, ctx, p) // Test InspectPod(). inspectResp, err := c.InspectPod(context.Background(), &v1alpha.InspectPodRequest{Id: p.Id}) if err != nil { t.Fatalf("Unexpected error: %v", err) } checkPodDetails(t, ctx, inspectResp.Pod) } // ListPods(detail=true). resp, err = c.ListPods(context.Background(), &v1alpha.ListPodsRequest{Detail: true}) if err != nil { t.Fatalf("Unexpected error: %v", err) } if len(resp.Pods) == 0 { t.Errorf("Unexpected result: %v, should see non-zero pods", resp.Pods) } for _, p := range resp.Pods { checkPodDetails(t, ctx, p) } }
func benchInspectPod(b *testing.B, c v1alpha.PublicAPIClient) { resp, err := c.ListPods(context.Background(), &v1alpha.ListPodsRequest{}) if err != nil { b.Fatalf("Unexpected error: %v", err) } b.ResetTimer() for i := 0; i < b.N; i++ { _, err := c.InspectPod(context.Background(), &v1alpha.InspectPodRequest{Id: resp.Pods[0].Id}) if err != nil { b.Error(err) } } b.StopTimer() }
func TestLargeMessage(t *testing.T) { server, ct := setUp(t, 0, math.MaxUint32, normal) callHdr := &CallHdr{ Host: "localhost", Method: "foo.Large", } var wg sync.WaitGroup for i := 0; i < 2; i++ { wg.Add(1) go func() { defer wg.Done() s, err := ct.NewStream(context.Background(), callHdr) if err != nil { t.Errorf("failed to open stream: %v", err) } if err := ct.Write(s, expectedRequestLarge, &Options{Last: true, Delay: false}); err != nil { t.Errorf("failed to send data: %v", err) } p := make([]byte, len(expectedResponseLarge)) _, recvErr := io.ReadFull(s, p) if recvErr != nil || !bytes.Equal(p, expectedResponseLarge) { t.Errorf("Error: %v, want <nil>; Result len: %d, want len %d", recvErr, len(p), len(expectedResponseLarge)) } _, recvErr = io.ReadFull(s, p) if recvErr != io.EOF { t.Errorf("Error: %v; want <EOF>", recvErr) } }() } wg.Wait() ct.Close() server.stop() }
func performOneRPC(ct ClientTransport) { callHdr := &CallHdr{ Host: "localhost", Method: "foo.Small", } s, err := ct.NewStream(context.Background(), callHdr) if err != nil { return } opts := Options{ Last: true, Delay: false, } if err := ct.Write(s, expectedRequest, &opts); err == nil { time.Sleep(5 * time.Millisecond) // The following s.Recv()'s could error out because the // underlying transport is gone. // // Read response p := make([]byte, len(expectedResponse)) io.ReadFull(s, p) // Read io.EOF io.ReadFull(s, p) } }
func testExceedMaxStreamsLimit(t *testing.T, e env) { // Only allows 1 live stream per server transport. s, cc := setUp(nil, 1, "", e) tc := testpb.NewTestServiceClient(cc) defer tearDown(s, cc) done := make(chan struct{}) ch := make(chan int) go func() { for { select { case <-time.After(5 * time.Millisecond): ch <- 0 case <-time.After(5 * time.Second): close(done) return } } }() // Loop until a stream creation hangs due to the new max stream setting. for { select { case <-ch: ctx, _ := context.WithTimeout(context.Background(), time.Second) if _, err := tc.StreamingInputCall(ctx); err != nil { if grpc.Code(err) == codes.DeadlineExceeded { return } t.Fatalf("%v.StreamingInputCall(_) = %v, want <nil>", tc, err) } case <-done: t.Fatalf("Client has not received the max stream setting in 5 seconds.") } } }
func testClientStreaming(t *testing.T, e env) { s, cc := setUp(nil, math.MaxUint32, "", e) tc := testpb.NewTestServiceClient(cc) defer tearDown(s, cc) stream, err := tc.StreamingInputCall(context.Background()) if err != nil { t.Fatalf("%v.StreamingInputCall(_) = _, %v, want <nil>", tc, err) } var sum int for _, s := range reqSizes { pl := newPayload(testpb.PayloadType_COMPRESSABLE, int32(s)) req := &testpb.StreamingInputCallRequest{ Payload: pl, } if err := stream.Send(req); err != nil { t.Fatalf("%v.Send(%v) = %v, want <nil>", stream, req, err) } sum += s } reply, err := stream.CloseAndRecv() if err != nil { t.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil) } if reply.GetAggregatedPayloadSize() != int32(sum) { t.Fatalf("%v.CloseAndRecv().GetAggregatePayloadSize() = %v; want %v", stream, reply.GetAggregatedPayloadSize(), sum) } }
func doClientStreaming(tc testpb.TestServiceClient) { stream, err := tc.StreamingInputCall(context.Background()) if err != nil { grpclog.Fatalf("%v.StreamingInputCall(_) = _, %v", tc, err) } var sum int for _, s := range reqSizes { pl := newPayload(testpb.PayloadType_COMPRESSABLE, s) req := &testpb.StreamingInputCallRequest{ Payload: pl, } if err := stream.Send(req); err != nil { grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err) } sum += s grpclog.Printf("Sent a request of size %d, aggregated size %d", s, sum) } reply, err := stream.CloseAndRecv() if err != nil { grpclog.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil) } if reply.GetAggregatedPayloadSize() != int32(sum) { grpclog.Fatalf("%v.CloseAndRecv().GetAggregatePayloadSize() = %v; want %v", stream, reply.GetAggregatedPayloadSize(), sum) } grpclog.Println("ClientStreaming done") }
func doPerRPCCreds(tc testpb.TestServiceClient) { jsonKey := getServiceAccountJSONKey() pl := newPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize) req := &testpb.SimpleRequest{ ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), ResponseSize: proto.Int32(int32(largeRespSize)), Payload: pl, FillUsername: proto.Bool(true), FillOauthScope: proto.Bool(true), } token := getToken() kv := map[string]string{"authorization": token.TokenType + " " + token.AccessToken} ctx := metadata.NewContext(context.Background(), metadata.MD{"authorization": []string{kv["authorization"]}}) reply, err := tc.UnaryCall(ctx, req) if err != nil { grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) } user := reply.GetUsername() scope := reply.GetOauthScope() if !strings.Contains(string(jsonKey), user) { grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey) } if !strings.Contains(*oauthScope, scope) { grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, *oauthScope) } grpclog.Println("PerRPCCreds done") }
func testEmptyUnaryWithUserAgent(t *testing.T, e env) { s, cc := setUp(nil, math.MaxUint32, testAppUA, e) // Wait until cc is connected. if ok := cc.WaitForStateChange(time.Second, grpc.Idle); !ok { t.Fatalf("cc.WaitForStateChange(_, %s) = %t, want true", grpc.Idle, ok) } if ok := cc.WaitForStateChange(10*time.Second, grpc.Connecting); !ok { t.Fatalf("cc.WaitForStateChange(_, %s) = %t, want true", grpc.Connecting, ok) } if cc.State() != grpc.Ready { t.Fatalf("cc.State() = %s, want %s", cc.State(), grpc.Ready) } if ok := cc.WaitForStateChange(time.Second, grpc.Ready); ok { t.Fatalf("cc.WaitForStateChange(_, %s) = %t, want false", grpc.Ready, ok) } tc := testpb.NewTestServiceClient(cc) var header metadata.MD reply, err := tc.EmptyCall(context.Background(), &testpb.Empty{}, grpc.Header(&header)) if err != nil || !proto.Equal(&testpb.Empty{}, reply) { t.Fatalf("TestService/EmptyCall(_, _) = %v, %v, want %v, <nil>", reply, err, &testpb.Empty{}) } if v, ok := header["ua"]; !ok || v[0] != testAppUA { t.Fatalf("header[\"ua\"] = %q, %t, want %q, true", v, ok, testAppUA) } tearDown(s, cc) if ok := cc.WaitForStateChange(5*time.Second, grpc.Ready); !ok { t.Fatalf("cc.WaitForStateChange(_, %s) = %t, want true", grpc.Ready, ok) } if cc.State() != grpc.Shutdown { t.Fatalf("cc.State() = %s, want %s", cc.State(), grpc.Shutdown) } }
func testTimeoutOnDeadServer(t *testing.T, e env) { s, cc := setUp(nil, math.MaxUint32, "", e) tc := testpb.NewTestServiceClient(cc) if ok := cc.WaitForStateChange(time.Second, grpc.Idle); !ok { t.Fatalf("cc.WaitForStateChange(_, %s) = %t, want true", grpc.Idle, ok) } if ok := cc.WaitForStateChange(time.Second, grpc.Connecting); !ok { t.Fatalf("cc.WaitForStateChange(_, %s) = %t, want true", grpc.Connecting, ok) } if cc.State() != grpc.Ready { t.Fatalf("cc.State() = %s, want %s", cc.State(), grpc.Ready) } if ok := cc.WaitForStateChange(time.Millisecond, grpc.Ready); ok { t.Fatalf("cc.WaitForStateChange(_, %s) = %t, want false", grpc.Ready, ok) } s.Stop() // Set -1 as the timeout to make sure if transportMonitor gets error // notification in time the failure path of the 1st invoke of // ClientConn.wait hits the deadline exceeded error. ctx, _ := context.WithTimeout(context.Background(), -1) if _, err := tc.EmptyCall(ctx, &testpb.Empty{}); grpc.Code(err) != codes.DeadlineExceeded { t.Fatalf("TestService/EmptyCall(%v, _) = _, error %v, want _, error code: %d", ctx, err, codes.DeadlineExceeded) } if ok := cc.WaitForStateChange(time.Second, grpc.Ready); !ok { t.Fatalf("cc.WaitForStateChange(_, %s) = %t, want true", grpc.Ready, ok) } state := cc.State() if state != grpc.Connecting && state != grpc.TransientFailure { t.Fatalf("cc.State() = %s, want %s or %s", state, grpc.Connecting, grpc.TransientFailure) } cc.Close() }
func doCancelAfterFirstResponse(tc testpb.TestServiceClient) { ctx, cancel := context.WithCancel(context.Background()) stream, err := tc.FullDuplexCall(ctx) if err != nil { grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err) } respParam := []*testpb.ResponseParameters{ { Size: proto.Int32(31415), }, } pl := newPayload(testpb.PayloadType_COMPRESSABLE, 27182) req := &testpb.StreamingOutputCallRequest{ ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), ResponseParameters: respParam, Payload: pl, } if err := stream.Send(req); err != nil { grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err) } if _, err := stream.Recv(); err != nil { grpclog.Fatalf("%v.Recv() = %v", stream, err) } cancel() if _, err := stream.Recv(); grpc.Code(err) != codes.Canceled { grpclog.Fatalf("%v compleled with error code %d, want %d", stream, grpc.Code(err), codes.Canceled) } grpclog.Println("CancelAfterFirstResponse done") }
func main() { conn, err := grpc.Dial("localhost:15441", grpc.WithInsecure()) if err != nil { fmt.Println(err) os.Exit(1) } c := v1alpha.NewPublicAPIClient(conn) defer conn.Close() // List pods. podResp, err := c.ListPods(context.Background(), &v1alpha.ListPodsRequest{ // Specify the request: Fetch and print only running pods and their details. Detail: true, Filters: []*v1alpha.PodFilter{ { States: []v1alpha.PodState{v1alpha.PodState_POD_STATE_RUNNING}, }, }, }) if err != nil { fmt.Println(err) os.Exit(2) } for _, p := range podResp.Pods { fmt.Printf("Pod %q is running\n", p.Id) } // List images. imgResp, err := c.ListImages(context.Background(), &v1alpha.ListImagesRequest{ // In this request, we fetch the details of images whose names are prefixed with "coreos.com". Detail: true, Filters: []*v1alpha.ImageFilter{ { Prefixes: []string{"coreos.com"}, }, }, }) if err != nil { fmt.Println(err) os.Exit(3) } for _, im := range imgResp.Images { fmt.Printf("Found image %q\n", im.Name) } }
func TestStreamContext(t *testing.T) { expectedStream := Stream{} ctx := newContextWithStream(context.Background(), &expectedStream) s, ok := StreamFromContext(ctx) if !ok || !reflect.DeepEqual(expectedStream, *s) { t.Fatalf("GetStreamFromContext(%v) = %v, %t, want: %v, true", ctx, *s, ok, expectedStream) } }
func healthCheck(t time.Duration, cc *grpc.ClientConn, serviceName string) (*healthpb.HealthCheckResponse, error) { ctx, _ := context.WithTimeout(context.Background(), t) hc := healthpb.NewHealthCheckClient(cc) req := &healthpb.HealthCheckRequest{ Service: serviceName, } return hc.Check(ctx, req) }
func TestNoTimeout(t *testing.T) { ctx := context.Background() resp, err := doRequest(ctx) if resp == nil || err != nil { t.Fatalf("error received from client: %v %v", err, resp) } }
// printFeature gets the feature for the given point. func printFeature(client pb.RouteGuideClient, point *pb.Point) { grpclog.Printf("Getting feature for point (%d, %d)", point.Latitude, point.Longitude) feature, err := client.GetFeature(context.Background(), point) if err != nil { grpclog.Fatalf("%v.GetFeatures(_) = _, %v: ", client, err) } grpclog.Println(feature) }
func testFailedEmptyUnary(t *testing.T, e env) { s, cc := setUp(nil, math.MaxUint32, "", e) tc := testpb.NewTestServiceClient(cc) defer tearDown(s, cc) ctx := metadata.NewContext(context.Background(), testMetadata) if _, err := tc.EmptyCall(ctx, &testpb.Empty{}); err != grpc.Errorf(codes.DataLoss, "got extra metadata") { t.Fatalf("TestService/EmptyCall(_, _) = _, %v, want _, %v", err, grpc.Errorf(codes.DataLoss, "got extra metadata")) } }
func doEmptyUnaryCall(tc testpb.TestServiceClient) { reply, err := tc.EmptyCall(context.Background(), &testpb.Empty{}) if err != nil { grpclog.Fatal("/TestService/EmptyCall RPC failed: ", err) } if !proto.Equal(&testpb.Empty{}, reply) { grpclog.Fatalf("/TestService/EmptyCall receives %v, want %v", reply, testpb.Empty{}) } grpclog.Println("EmptyUnaryCall done") }
func benchListPods(b *testing.B, c v1alpha.PublicAPIClient, detail bool) { b.ResetTimer() for i := 0; i < b.N; i++ { _, err := c.ListPods(context.Background(), &v1alpha.ListPodsRequest{Detail: detail}) if err != nil { b.Error(err) } } b.StopTimer() }
// DoUnaryCall performs an unary RPC with given stub and request and response sizes. func DoUnaryCall(tc testpb.TestServiceClient, reqSize, respSize int) { pl := newPayload(testpb.PayloadType_COMPRESSABLE, reqSize) req := &testpb.SimpleRequest{ ResponseType: pl.Type, ResponseSize: int32(respSize), Payload: pl, } if _, err := tc.UnaryCall(context.Background(), req); err != nil { grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) } }
func getToken() *oauth2.Token { jsonKey := getServiceAccountJSONKey() config, err := google.JWTConfigFromJSON(jsonKey, *oauthScope) if err != nil { grpclog.Fatalf("Failed to get the config: %v", err) } token, err := config.TokenSource(context.Background()).Token() if err != nil { grpclog.Fatalf("Failed to get the token: %v", err) } return token }
func testMetadataStreamingRPC(t *testing.T, e env) { s, cc := setUp(nil, math.MaxUint32, "", e) tc := testpb.NewTestServiceClient(cc) defer tearDown(s, cc) ctx := metadata.NewContext(context.Background(), testMetadata) stream, err := tc.FullDuplexCall(ctx) if err != nil { t.Fatalf("%v.FullDuplexCall(_) = _, %v, want <nil>", tc, err) } go func() { headerMD, err := stream.Header() if e.security == "tls" { delete(headerMD, "transport_security_type") } if err != nil || !reflect.DeepEqual(testMetadata, headerMD) { t.Errorf("#1 %v.Header() = %v, %v, want %v, <nil>", stream, headerMD, err, testMetadata) } // test the cached value. headerMD, err = stream.Header() if err != nil || !reflect.DeepEqual(testMetadata, headerMD) { t.Errorf("#2 %v.Header() = %v, %v, want %v, <nil>", stream, headerMD, err, testMetadata) } var index int for index < len(reqSizes) { respParam := []*testpb.ResponseParameters{ { Size: proto.Int32(int32(respSizes[index])), }, } req := &testpb.StreamingOutputCallRequest{ ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(), ResponseParameters: respParam, Payload: newPayload(testpb.PayloadType_COMPRESSABLE, int32(reqSizes[index])), } if err := stream.Send(req); err != nil { t.Errorf("%v.Send(%v) = %v, want <nil>", stream, req, err) return } index++ } // Tell the server we're done sending args. stream.CloseSend() }() for { if _, err := stream.Recv(); err != nil { break } } trailerMD := stream.Trailer() if !reflect.DeepEqual(testMetadata, trailerMD) { t.Fatalf("%v.Trailer() = %v, want %v", stream, trailerMD, testMetadata) } }
func doCancelAfterBegin(tc testpb.TestServiceClient) { ctx, cancel := context.WithCancel(metadata.NewContext(context.Background(), testMetadata)) stream, err := tc.StreamingInputCall(ctx) if err != nil { grpclog.Fatalf("%v.StreamingInputCall(_) = _, %v", tc, err) } cancel() _, err = stream.CloseAndRecv() if grpc.Code(err) != codes.Canceled { grpclog.Fatalf("%v.CloseAndRecv() got error code %d, want %d", stream, grpc.Code(err), codes.Canceled) } grpclog.Println("CancelAfterBegin done") }
func doEmptyStream(tc testpb.TestServiceClient) { stream, err := tc.FullDuplexCall(context.Background()) if err != nil { grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err) } if err := stream.CloseSend(); err != nil { grpclog.Fatalf("%v.CloseSend() got %v, want %v", stream, err, nil) } if _, err := stream.Recv(); err != io.EOF { grpclog.Fatalf("%v failed to complete the empty stream test: %v", stream, err) } grpclog.Println("Emptystream done") }
func ExampleWithTimeout() { // Pass a context with a timeout to tell a blocking function that it // should abandon its work after the timeout elapses. ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond) select { case <-time.After(200 * time.Millisecond): fmt.Println("overslept") case <-ctx.Done(): fmt.Println(ctx.Err()) // prints "context deadline exceeded" } // Output: // context deadline exceeded }
func TestClientSendAndReceive(t *testing.T) { server, ct := setUp(t, 0, math.MaxUint32, normal) callHdr := &CallHdr{ Host: "localhost", Method: "foo.Small", } s1, err1 := ct.NewStream(context.Background(), callHdr) if err1 != nil { t.Fatalf("failed to open stream: %v", err1) } if s1.id != 1 { t.Fatalf("wrong stream id: %d", s1.id) } s2, err2 := ct.NewStream(context.Background(), callHdr) if err2 != nil { t.Fatalf("failed to open stream: %v", err2) } if s2.id != 3 { t.Fatalf("wrong stream id: %d", s2.id) } opts := Options{ Last: true, Delay: false, } if err := ct.Write(s1, expectedRequest, &opts); err != nil { t.Fatalf("failed to send data: %v", err) } p := make([]byte, len(expectedResponse)) _, recvErr := io.ReadFull(s1, p) if recvErr != nil || !bytes.Equal(p, expectedResponse) { t.Fatalf("Error: %v, want <nil>; Result: %v, want %v", recvErr, p, expectedResponse) } _, recvErr = io.ReadFull(s1, p) if recvErr != io.EOF { t.Fatalf("Error: %v; want <EOF>", recvErr) } ct.Close() server.stop() }
// NewETCDNR creates an etcd NameResolver. func NewETCDNR(cfg etcdcl.Config) (naming.Resolver, error) { c, err := etcdcl.New(cfg) if err != nil { return nil, err } kAPI := etcdcl.NewKeysAPI(c) ctx, cancel := context.WithCancel(context.Background()) return &etcdNR{ kAPI: kAPI, recv: newRecvBuffer(), ctx: ctx, cancel: cancel, }, nil }
func TestCancelAfterRequest(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) resp, err := doRequest(ctx) // Cancel before reading the body. // Request.Body should still be readable after the context is canceled. cancel() b, err := ioutil.ReadAll(resp.Body) if err != nil || string(b) != requestBody { t.Fatalf("could not read body: %q %v", b, err) } }