diff --git a/pkg/jrpctest/suites.go b/pkg/jrpctest/suites.go index 9f7be5a3900102b3b41147ddd534450731dcdb91..e040cda9271ef7981cde331a81700091b26c63dd 100644 --- a/pkg/jrpctest/suites.go +++ b/pkg/jrpctest/suites.go @@ -148,11 +148,74 @@ func RunBasicTestSuite(t *testing.T, args BasicTestSuiteArgs) { t.Fatal(err) } }) + + makeTest("context cancel", func(t *testing.T, server *jrpc.Server, client jrpc.Conn) { + maxContextCancelTimeout := 300 * time.Millisecond + // The actual test starts here. + var ( + wg sync.WaitGroup + nreqs = 10 + ncallers = 10 + ) + caller := func(index int) { + defer wg.Done() + for i := 0; i < nreqs; i++ { + var ( + ctx context.Context + cancel func() + timeout = time.Duration(rand.Int63n(int64(maxContextCancelTimeout))) + ) + if index < ncallers/2 { + // For half of the callers, create a context without deadline + // and cancel it later. + ctx, cancel = context.WithCancel(context.Background()) + time.AfterFunc(timeout, cancel) + } else { + // For the other half, create a context with a deadline instead. This is + // different because the context deadline is used to set the socket write + // deadline. + ctx, cancel = context.WithTimeout(context.Background(), timeout) + } + + // Now perform a call with the context. + // The key thing here is that no call will ever complete successfully. + err := jrpc.CallInto(ctx, client, nil, "test_block") + switch { + case err == nil: + _, hasDeadline := ctx.Deadline() + t.Errorf("no error for call with %v wait time (deadline: %v)", timeout, hasDeadline) + // default: + // t.Logf("got expected error with %v wait time: %v", timeout, err) + } + cancel() + } + } + wg.Add(ncallers) + for i := 0; i < ncallers; i++ { + go caller(i) + } + wg.Wait() + }) +} + +type ServerRemaker func(address string) (*jrpc.Server, ClientMaker, func()) + +type ReconnectTestSuiteArgs struct { + ServerMaker ServerMaker +} + +func RunReconnectSuite(t *testing.T, args BasicTestSuiteArgs) { + server, dialer, cn := args.ServerMaker() + defer cn() + defer server.Stop() + client := dialer() + defer client.Close() + } // This test checks that requests made through Call can be canceled by canceling // the context. -func CancelTester(t *testing.T, server *jrpc.Server, client jrpc.Conn) { +func cancelTester(t *testing.T, server *jrpc.Server, client jrpc.Conn) { maxContextCancelTimeout := 300 * time.Millisecond // The actual test starts here.