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