Test Discovery and Balancing End-to-End

We’re ready to update our agent’s tests to test everything end-to-end: the client configuring the resolver and picker, the resolver discovering the servers, and the picker picking subconnections per RPC.

Open your agent tests in internal/agent/agent_test.go and add this import:

ClientSideServiceDiscovery/internal/agent/agent_test.go
 "github.com/travisjeffery/proglog/internal/loadbalance"

Then update the client function to use your resolver and picker:

ClientSideServiceDiscovery/internal/agent/agent_test.go
 func​ client(
  t *testing.T,
  agent *agent.Agent,
  tlsConfig *tls.Config,
 ) api.LogClient {
  tlsCreds := credentials.NewTLS(tlsConfig)
  opts := []grpc.DialOption{
  grpc.WithTransportCredentials(tlsCreds),
  }
  rpcAddr, err := agent.Config.RPCAddr()
  require.NoError(t, err)
» conn, err := grpc.Dial(fmt.Sprintf(
»"%s:///%s"​,
» loadbalance.Name,
» rpcAddr,
» ), opts...)
  require.NoError(t, err)
  client := api.NewLogClient(conn)
 return​ client
 }

The highlighted lines specify our scheme in the URL so gRPC knows to use our resolver.

Run the agent’s tests by running $ go run ./internal/agent, and you’ll see that the leader client consume call fails now. Why? Before, each client connected to one server. So the leader client connected to the leader. When we produced records, they were immediately available for consuming with the leader client because it consumed from the leader server—we didn’t have to wait for the leader to replicate the record. Now, each client connects to every server and produces to the leader and consumes from the followers, so we must wait for the leader to replicate the record to the followers.

Update your test to wait for the servers to replicate the record before consuming with the leader client. Move time.Sleep that appears before line 14 to appear before line 4:

ClientSideServiceDiscovery/internal/agent/agent_test.go
1: // wait until replication has finished
time.Sleep(3 * time.Second)
consumeResponse, err := leaderClient.Consume(
5:  context.Background(),
&api.ConsumeRequest{
Offset: produceResponse.Offset,
},
)
10: require.NoError(t, err)
require.Equal(t, consumeResponse.Record.Value, []​byte​(​"foo"​))
followerClient := client(t, agents[1], peerTLSConfig)
consumeResponse, err = followerClient.Consume(
15:  context.Background(),
&api.ConsumeRequest{
Offset: produceResponse.Offset,
},
)
20: require.NoError(t, err)
require.Equal(t, consumeResponse.Record.Value, []​byte​(​"foo"​))

Run your tests again with $ make test and watch them pass!