Пример #1
0
func TestActiveCallReq(t *testing.T) {
	t.Skip("Test skipped due to unreliable way to test for protocol errors")

	ctx, cancel := NewContext(time.Second)
	defer cancel()

	// Note: This test cannot use log verification as the duplicate ID causes a log.
	// It does not use a verified server, as it leaks a message exchange due to the
	// modification of IDs in the relay.
	opts := testutils.NewOpts().DisableLogVerification()
	testutils.WithServer(t, opts, func(ch *Channel, hostPort string) {
		gotCall := make(chan struct{})
		unblock := make(chan struct{})

		testutils.RegisterFunc(ch, "blocked", func(ctx context.Context, args *raw.Args) (*raw.Res, error) {
			gotCall <- struct{}{}
			<-unblock
			return &raw.Res{}, nil
		})

		relayFunc := func(outgoing bool, frame *Frame) *Frame {
			if outgoing && frame.Header.ID == 3 {
				frame.Header.ID = 2
			}
			return frame
		}

		relayHostPort, closeRelay := testutils.FrameRelay(t, hostPort, relayFunc)
		defer closeRelay()

		firstComplete := make(chan struct{})
		go func() {
			// This call will block until we close unblock.
			raw.Call(ctx, ch, relayHostPort, ch.PeerInfo().ServiceName, "blocked", nil, nil)
			close(firstComplete)
		}()

		// Wait for the first call to be received by the server
		<-gotCall

		// Make a new call, which should fail
		_, _, _, err := raw.Call(ctx, ch, relayHostPort, ch.PeerInfo().ServiceName, "blocked", nil, nil)
		assert.Error(t, err, "Expect error")
		assert.True(t, strings.Contains(err.Error(), "already active"),
			"expected already active error, got %v", err)

		close(unblock)
		<-firstComplete
	})
}
Пример #2
0
func TestActiveCallReq(t *testing.T) {
	ctx, cancel := NewContext(time.Second)
	defer cancel()

	// Note: This test leaks a message exchange due to the modification of IDs in the relay.
	require.NoError(t, testutils.WithServer(nil, func(ch *Channel, hostPort string) {
		gotCall := make(chan struct{})
		unblock := make(chan struct{})

		testutils.RegisterFunc(t, ch, "blocked", func(ctx context.Context, args *raw.Args) (*raw.Res, error) {
			gotCall <- struct{}{}
			<-unblock
			return &raw.Res{}, nil
		})

		relayFunc := func(outgoing bool, frame *Frame) *Frame {
			if outgoing && frame.Header.ID == 2 {
				frame.Header.ID = 3
			}
			return frame
		}

		relayHostPort, closeRelay := testutils.FrameRelay(t, hostPort, relayFunc)
		defer closeRelay()

		go func() {
			// This call will block until we close unblock.
			raw.Call(ctx, ch, relayHostPort, ch.PeerInfo().ServiceName, "blocked", nil, nil)
		}()

		// Wait for the first call to be received by the server
		<-gotCall

		// Make a new call, which should fail
		_, _, _, err := raw.Call(ctx, ch, relayHostPort, ch.PeerInfo().ServiceName, "blocked", nil, nil)
		assert.Error(t, err, "Expect error")
		assert.True(t, strings.Contains(err.Error(), "already active"),
			"expected already active error, got %v", err)

		close(unblock)
	}))
}
Пример #3
0
func TestConnectTimeout(t *testing.T) {
	opts := testutils.NewOpts().DisableLogVerification()
	testutils.WithTestServer(t, opts, func(ts *testutils.TestServer) {
		// Set up a relay that will delay the initial init req.
		testComplete := make(chan struct{})

		relayFunc := func(outgoing bool, f *Frame) *Frame {
			select {
			case <-time.After(testutils.Timeout(200 * time.Millisecond)):
				return f
			case <-testComplete:
				// TODO: We should be able to forward the frame and have this test not fail.
				// Currently, it fails since the sequence of events is:
				// Server receives a TCP connection
				// Channel.Close() is called on the server
				// Server's TCP connection receives an init req
				// Since we don't currently track pending connections, the open TCP connection is not closed, and
				// we process the init req. This leaves an open connection at the end of the test.
				return nil
			}
		}
		relay, shutdown := testutils.FrameRelay(t, ts.HostPort(), relayFunc)
		defer shutdown()

		// Make a call with a long timeout, but short connect timeout.
		// We expect the call to fall almost immediately with ErrTimeout.
		ctx, cancel := NewContextBuilder(2 * time.Second).
			SetConnectTimeout(testutils.Timeout(100 * time.Millisecond)).
			Build()
		defer cancel()

		client := ts.NewClient(opts)
		err := client.Ping(ctx, relay)
		assert.Equal(t, ErrTimeout, err, "Ping should timeout due to timeout relay")

		// Note: we do not defer this, as we need to close(testComplete) before
		// we call shutdown since shutdown waits for the relay to close, which
		// is stuck waiting inside of our custom relay function.
		close(testComplete)
	})
}