Ejemplo n.º 1
0
func TestRelay(t *testing.T) {
	withRelayedEcho(t, func(_, _, client *Channel, ts *testutils.TestServer) {
		tests := []struct {
			header string
			body   string
		}{
			{"fake-header", "fake-body"},                        // fits in one frame
			{"fake-header", strings.Repeat("fake-body", 10000)}, // requires continuation
		}
		sc := client.GetSubChannel("test")
		for _, tt := range tests {
			ctx, cancel := NewContext(time.Second)
			defer cancel()

			arg2, arg3, _, err := raw.CallSC(ctx, sc, "echo", []byte(tt.header), []byte(tt.body))
			require.NoError(t, err, "Relayed call failed.")
			assert.Equal(t, tt.header, string(arg2), "Header was mangled during relay.")
			assert.Equal(t, tt.body, string(arg3), "Body was mangled during relay.")
		}

		calls := relaytest.NewMockStats()
		peer := relay.Peer{HostPort: ts.Server().PeerInfo().HostPort}
		for _ = range tests {
			calls.Add("client", "test", "echo").SetPeer(peer).Succeeded().End()
		}
		ts.AssertRelayStats(calls)
	})
}
Ejemplo n.º 2
0
func TestMockIgnoresDown(t *testing.T) {
	mockHB, err := mockhyperbahn.New()
	require.NoError(t, err, "Failed to set up mock hyperbahm")

	var (
		moe1Called atomic.Bool
		moe2Called atomic.Bool
	)

	moe1 := newAdvertisedEchoServer(t, "moe", mockHB, func() { moe1Called.Store(true) })
	defer moe1.Close()
	moe2 := newAdvertisedEchoServer(t, "moe", mockHB, func() { moe2Called.Store(true) })
	defer moe2.Close()
	client := newAdvertisedEchoServer(t, "client", mockHB, nil)

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

	for i := 0; i < 20; i++ {
		_, _, _, err = raw.CallSC(ctx, client.GetSubChannel("moe"), "echo", nil, nil)
		assert.NoError(t, err, "Call failed")
	}

	require.True(t, moe1Called.Load(), "moe1 not called")
	require.True(t, moe2Called.Load(), "moe2 not called")

	// If moe2 is brought down, all calls should now be sent to moe1.
	moe2.Close()

	// Wait for the mock HB to have 0 connections to moe
	ok := testutils.WaitFor(time.Second, func() bool {
		in, out := mockHB.Channel().Peers().GetOrAdd(moe2.PeerInfo().HostPort).NumConnections()
		return in+out == 0
	})
	require.True(t, ok, "Failed waiting for mock HB to have 0 connections")

	// Make sure that all calls succeed (they should all go to moe2)
	moe1Called.Store(false)
	moe2Called.Store(false)
	for i := 0; i < 20; i++ {
		_, _, _, err = raw.CallSC(ctx, client.GetSubChannel("moe"), "echo", nil, nil)
		assert.NoError(t, err, "Call failed")
	}

	require.True(t, moe1Called.Load(), "moe1 not called")
	require.False(t, moe2Called.Load(), "moe2 should not be called after Close")
}
Ejemplo n.º 3
0
func TestRelayHandlesClosedPeers(t *testing.T) {
	opts := serviceNameOpts("test").SetRelayOnly().
		// Disable logs as we are closing connections that can error in a lot of places.
		DisableLogVerification()
	testutils.WithTestServer(t, opts, func(ts *testutils.TestServer) {
		ctx, cancel := NewContext(300 * time.Millisecond)
		defer cancel()

		testutils.RegisterEcho(ts.Server(), nil)
		client := ts.NewClient(serviceNameOpts("client"))
		client.Peers().Add(ts.HostPort())

		sc := client.GetSubChannel("test")
		_, _, _, err := raw.CallSC(ctx, sc, "echo", []byte("fake-header"), []byte("fake-body"))
		require.NoError(t, err, "Relayed call failed.")

		ts.Server().Close()
		require.NotPanics(t, func() {
			raw.CallSC(ctx, sc, "echo", []byte("fake-header"), []byte("fake-body"))
		})
	})
}
Ejemplo n.º 4
0
func TestMockForwards(t *testing.T) {
	mockHB, err := mockhyperbahn.New()
	require.NoError(t, err, "Failed to set up mock hyperbahm")

	called := false
	server := newAdvertisedEchoServer(t, "svr", mockHB, func() {
		called = true
	})
	defer server.Close()
	client := newAdvertisedEchoServer(t, "client", mockHB, nil)
	defer client.Close()

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

	_, _, _, err = raw.CallSC(ctx, client.GetSubChannel("svr"), "echo", nil, nil)
	require.NoError(t, err, "Call failed")
	require.True(t, called, "Advertised server was not called")
}
Ejemplo n.º 5
0
func (c *internalClient) RawCallBuffer(latencies []time.Duration) error {
	return c.makeCalls(latencies, func() (time.Duration, error) {
		ctx, cancel := tchannel.NewContext(c.opts.timeout)
		defer cancel()

		started := time.Now()
		rArg2, rArg3, _, err := raw.CallSC(ctx, c.sc, "echo", c.argBytes, c.argBytes)
		duration := time.Since(started)

		if err != nil {
			return 0, err
		}
		if c.checkResult {
			if !bytes.Equal(rArg2, c.argBytes) || !bytes.Equal(rArg3, c.argBytes) {
				fmt.Println("Arg2", rArg2, "Expect", c.argBytes)
				fmt.Println("Arg3", rArg3, "Expect", c.argBytes)
				panic("echo call returned wrong results")
			}
		}
		return duration, nil
	})
}
Ejemplo n.º 6
0
func (pt *peerSelectionTest) makeCall(sc *SubChannel) {
	ctx, cancel := NewContext(time.Second)
	defer cancel()
	_, _, _, err := raw.CallSC(ctx, sc, "echo", nil, nil)
	assert.NoError(pt.t, err, "raw.Call failed")
}
Ejemplo n.º 7
0
func benchmarkCallsN(b *testing.B, c benchmarkConfig) {
	var (
		clients []*Channel
		servers []*Channel
	)
	lt := newLatencyTracker()

	if c.numBytes == 0 {
		c.numBytes = 100
	}
	data := testutils.RandBytes(c.numBytes)

	// Set up clients and servers.
	for i := 0; i < c.numServers; i++ {
		servers = append(servers, setupServer(b))
	}
	for i := 0; i < c.numClients; i++ {
		clients = append(clients, testutils.NewClient(b, nil))
		for _, s := range servers {
			clients[i].Peers().Add(s.PeerInfo().HostPort)

			// Initialize a connection
			ctx, cancel := NewContext(50 * time.Millisecond)
			assert.NoError(b, clients[i].Ping(ctx, s.PeerInfo().HostPort), "Initial ping failed")
			cancel()
		}
	}

	// Make calls from clients to the servers
	call := func(sc *SubChannel) {
		ctx, cancel := NewContext(50 * time.Millisecond)
		start := time.Now()
		_, _, _, err := raw.CallSC(ctx, sc, "echo", nil, data)
		duration := time.Since(start)
		cancel()
		if assert.NoError(b, err, "Call failed") {
			lt.addLatency(duration)
		}
	}

	reqsLeft := testutils.Decrementor(c.numCalls)
	clientWorker := func(client *Channel, clientNum, workerNum int) {
		sc := client.GetSubChannel(benchService)
		for reqsLeft() {
			call(sc)
		}
	}
	clientRunner := func(client *Channel, clientNum int) {
		testutils.RunN(c.workersPerClient, func(i int) {
			clientWorker(client, clientNum, i)
		})
	}

	lt.reset()
	defer lt.report(b)
	b.ResetTimer()

	testutils.RunN(c.numClients, func(i int) {
		clientRunner(clients[i], i)
	})
}
Ejemplo n.º 8
0
func TestSetHandler(t *testing.T) {
	// Generate a Handler that expects only the given methods to be called.
	genHandler := func(methods ...string) Handler {
		allowedMethods := make(map[string]struct{}, len(methods))
		for _, m := range methods {
			allowedMethods[m] = struct{}{}
		}

		return HandlerFunc(func(ctx context.Context, call *InboundCall) {
			method := call.MethodString()
			assert.Contains(t, allowedMethods, method, "unexpected call to %q", method)
			err := raw.WriteResponse(call.Response(), &raw.Res{Arg3: []byte(method)})
			require.NoError(t, err)
		})
	}

	ch := testutils.NewServer(t, testutils.NewOpts().
		AddLogFilter("Couldn't find handler", 1, "serviceName", "svc2", "method", "bar"))
	defer ch.Close()

	// Catch-all handler for the main channel that accepts foo, bar, and baz,
	// and a single registered handler for a different subchannel.
	ch.GetSubChannel("svc1").SetHandler(genHandler("foo", "bar", "baz"))
	ch.GetSubChannel("svc2").Register(genHandler("foo"), "foo")

	client := testutils.NewClient(t, nil)
	client.Peers().Add(ch.PeerInfo().HostPort)
	defer client.Close()

	tests := []struct {
		Service    string
		Method     string
		ShouldFail bool
	}{
		{"svc1", "foo", false},
		{"svc1", "bar", false},
		{"svc1", "baz", false},

		{"svc2", "foo", false},
		{"svc2", "bar", true},
	}

	for _, tt := range tests {
		c := client.GetSubChannel(tt.Service)
		ctx, _ := NewContext(time.Second)
		_, data, _, err := raw.CallSC(ctx, c, tt.Method, nil, []byte("irrelevant"))

		if tt.ShouldFail {
			require.Error(t, err)
		} else {
			require.NoError(t, err)
			assert.Equal(t, tt.Method, string(data))
		}
	}

	st := ch.IntrospectState(nil)
	assert.Equal(t, "overriden", st.SubChannels["svc1"].Handler.Type.String())
	assert.Nil(t, st.SubChannels["svc1"].Handler.Methods)

	assert.Equal(t, "methods", st.SubChannels["svc2"].Handler.Type.String())
	assert.Equal(t, []string{"foo"}, st.SubChannels["svc2"].Handler.Methods)
}