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  }