diff --git a/consul/rpc_test.go b/consul/rpc_test.go new file mode 100644 index 0000000000..e77f6ea10f --- /dev/null +++ b/consul/rpc_test.go @@ -0,0 +1,72 @@ +package consul + +import ( + "os" + "testing" + "time" + + "github.com/hashicorp/consul/consul/structs" + "github.com/hashicorp/consul/testutil" + "github.com/hashicorp/net-rpc-msgpackrpc" +) + +func TestRPC_NoLeader_Fail(t *testing.T) { + dir1, s1 := testServerWithConfig(t, func(c *Config) { + c.RPCHoldTimeout = 1 * time.Millisecond + }) + defer os.RemoveAll(dir1) + defer s1.Shutdown() + codec := rpcClient(t, s1) + defer codec.Close() + + arg := structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + } + var out struct{} + + // Make sure we eventually fail with a no leader error, which we should + // see given the short timeout. + err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out) + if err.Error() != structs.ErrNoLeader.Error() { + t.Fatalf("bad: %v", err) + } + + // Now make sure it goes through. + testutil.WaitForLeader(t, s1.RPC, "dc1") + err = msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out) + if err != nil { + t.Fatalf("bad: %v", err) + } +} + +func TestRPC_NoLeader_Retry(t *testing.T) { + dir1, s1 := testServerWithConfig(t, func(c *Config) { + c.RPCHoldTimeout = 10 * time.Second + }) + defer os.RemoveAll(dir1) + defer s1.Shutdown() + codec := rpcClient(t, s1) + defer codec.Close() + + arg := structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + } + var out struct{} + + // This isn't sure-fire but tries to check that we don't have a + // leader going into the RPC, so we exercise the retry logic. + if ok, _ := s1.getLeader(); ok { + t.Fatalf("should not have a leader yet") + } + + // The timeout is long enough to ride out any reasonable leader + // election. + err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out) + if err != nil { + t.Fatalf("bad: %v", err) + } +}