github.com/zoomfoo/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/nomad/status_endpoint_test.go (about) 1 package nomad 2 3 import ( 4 "testing" 5 6 "github.com/hashicorp/net-rpc-msgpackrpc" 7 "github.com/hashicorp/nomad/acl" 8 "github.com/hashicorp/nomad/helper/uuid" 9 "github.com/hashicorp/nomad/nomad/mock" 10 "github.com/hashicorp/nomad/nomad/structs" 11 "github.com/hashicorp/nomad/testutil" 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestStatusVersion(t *testing.T) { 17 t.Parallel() 18 s1 := TestServer(t, nil) 19 defer s1.Shutdown() 20 codec := rpcClient(t, s1) 21 22 arg := &structs.GenericRequest{ 23 QueryOptions: structs.QueryOptions{ 24 Region: "global", 25 AllowStale: true, 26 }, 27 } 28 var out structs.VersionResponse 29 if err := msgpackrpc.CallWithCodec(codec, "Status.Version", arg, &out); err != nil { 30 t.Fatalf("err: %v", err) 31 } 32 33 if out.Build == "" { 34 t.Fatalf("bad: %#v", out) 35 } 36 if out.Versions[structs.ProtocolVersion] != ProtocolVersionMax { 37 t.Fatalf("bad: %#v", out) 38 } 39 if out.Versions[structs.APIMajorVersion] != structs.ApiMajorVersion { 40 t.Fatalf("bad: %#v", out) 41 } 42 if out.Versions[structs.APIMinorVersion] != structs.ApiMinorVersion { 43 t.Fatalf("bad: %#v", out) 44 } 45 } 46 47 func TestStatusPing(t *testing.T) { 48 t.Parallel() 49 s1 := TestServer(t, nil) 50 defer s1.Shutdown() 51 codec := rpcClient(t, s1) 52 53 arg := struct{}{} 54 var out struct{} 55 if err := msgpackrpc.CallWithCodec(codec, "Status.Ping", arg, &out); err != nil { 56 t.Fatalf("err: %v", err) 57 } 58 } 59 60 func TestStatusLeader(t *testing.T) { 61 t.Parallel() 62 s1 := TestServer(t, nil) 63 defer s1.Shutdown() 64 codec := rpcClient(t, s1) 65 testutil.WaitForLeader(t, s1.RPC) 66 67 arg := &structs.GenericRequest{ 68 QueryOptions: structs.QueryOptions{ 69 Region: "global", 70 AllowStale: true, 71 }, 72 } 73 var leader string 74 if err := msgpackrpc.CallWithCodec(codec, "Status.Leader", arg, &leader); err != nil { 75 t.Fatalf("err: %v", err) 76 } 77 if leader == "" { 78 t.Fatalf("unexpected leader: %v", leader) 79 } 80 } 81 82 func TestStatusPeers(t *testing.T) { 83 t.Parallel() 84 s1 := TestServer(t, nil) 85 defer s1.Shutdown() 86 codec := rpcClient(t, s1) 87 88 arg := &structs.GenericRequest{ 89 QueryOptions: structs.QueryOptions{ 90 Region: "global", 91 AllowStale: true, 92 }, 93 } 94 var peers []string 95 if err := msgpackrpc.CallWithCodec(codec, "Status.Peers", arg, &peers); err != nil { 96 t.Fatalf("err: %v", err) 97 } 98 if len(peers) != 1 { 99 t.Fatalf("no peers: %v", peers) 100 } 101 } 102 103 func TestStatusMembers(t *testing.T) { 104 t.Parallel() 105 s1 := TestServer(t, nil) 106 defer s1.Shutdown() 107 codec := rpcClient(t, s1) 108 assert := assert.New(t) 109 110 arg := &structs.GenericRequest{ 111 QueryOptions: structs.QueryOptions{ 112 Region: "global", 113 AllowStale: true, 114 }, 115 } 116 117 var out structs.ServerMembersResponse 118 assert.Nil(msgpackrpc.CallWithCodec(codec, "Status.Members", arg, &out)) 119 assert.Len(out.Members, 1) 120 } 121 122 func TestStatusMembers_ACL(t *testing.T) { 123 t.Parallel() 124 s1, root := TestACLServer(t, nil) 125 defer s1.Shutdown() 126 codec := rpcClient(t, s1) 127 assert := assert.New(t) 128 state := s1.fsm.State() 129 130 // Create the namespace policy and tokens 131 validToken := mock.CreatePolicyAndToken(t, state, 1001, "test-valid", mock.NodePolicy(acl.PolicyRead)) 132 invalidToken := mock.CreatePolicyAndToken(t, state, 1003, "test-invalid", mock.AgentPolicy(acl.PolicyRead)) 133 134 arg := &structs.GenericRequest{ 135 QueryOptions: structs.QueryOptions{ 136 Region: "global", 137 AllowStale: true, 138 }, 139 } 140 141 // Try without a token and expect failure 142 { 143 var out structs.ServerMembersResponse 144 err := msgpackrpc.CallWithCodec(codec, "Status.Members", arg, &out) 145 assert.NotNil(err) 146 assert.Equal(err.Error(), structs.ErrPermissionDenied.Error()) 147 } 148 149 // Try with an invalid token and expect failure 150 { 151 arg.AuthToken = invalidToken.SecretID 152 var out structs.ServerMembersResponse 153 err := msgpackrpc.CallWithCodec(codec, "Status.Members", arg, &out) 154 assert.NotNil(err) 155 assert.Equal(err.Error(), structs.ErrPermissionDenied.Error()) 156 } 157 158 // Try with a valid token 159 { 160 arg.AuthToken = validToken.SecretID 161 var out structs.ServerMembersResponse 162 assert.Nil(msgpackrpc.CallWithCodec(codec, "Status.Members", arg, &out)) 163 assert.Len(out.Members, 1) 164 } 165 166 // Try with a management token 167 { 168 arg.AuthToken = root.SecretID 169 var out structs.ServerMembersResponse 170 assert.Nil(msgpackrpc.CallWithCodec(codec, "Status.Members", arg, &out)) 171 assert.Len(out.Members, 1) 172 } 173 } 174 175 func TestStatus_HasClientConn(t *testing.T) { 176 t.Parallel() 177 s1 := TestServer(t, nil) 178 defer s1.Shutdown() 179 codec := rpcClient(t, s1) 180 require := require.New(t) 181 182 arg := &structs.NodeSpecificRequest{ 183 QueryOptions: structs.QueryOptions{ 184 Region: "global", 185 AllowStale: true, 186 }, 187 } 188 189 // Try without setting a node id 190 var out structs.NodeConnQueryResponse 191 require.NotNil(msgpackrpc.CallWithCodec(codec, "Status.HasNodeConn", arg, &out)) 192 193 // Set a bad node id 194 arg.NodeID = uuid.Generate() 195 var out2 structs.NodeConnQueryResponse 196 require.Nil(msgpackrpc.CallWithCodec(codec, "Status.HasNodeConn", arg, &out2)) 197 require.False(out2.Connected) 198 199 // Create a connection on that node 200 s1.addNodeConn(&RPCContext{ 201 NodeID: arg.NodeID, 202 }) 203 var out3 structs.NodeConnQueryResponse 204 require.Nil(msgpackrpc.CallWithCodec(codec, "Status.HasNodeConn", arg, &out3)) 205 require.True(out3.Connected) 206 require.NotZero(out3.Established) 207 }