github.com/uchennaokeke444/nomad@v0.11.8/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  }