github.com/jrxfive/nomad@v0.6.1-0.20170802162750-1fef470e89bf/nomad/node_endpoint_test.go (about)

     1  package nomad
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	memdb "github.com/hashicorp/go-memdb"
    11  	"github.com/hashicorp/net-rpc-msgpackrpc"
    12  	"github.com/hashicorp/nomad/nomad/mock"
    13  	"github.com/hashicorp/nomad/nomad/structs"
    14  	"github.com/hashicorp/nomad/testutil"
    15  	vapi "github.com/hashicorp/vault/api"
    16  )
    17  
    18  func TestClientEndpoint_Register(t *testing.T) {
    19  	t.Parallel()
    20  	s1 := testServer(t, nil)
    21  	defer s1.Shutdown()
    22  	codec := rpcClient(t, s1)
    23  	testutil.WaitForLeader(t, s1.RPC)
    24  
    25  	// Create the register request
    26  	node := mock.Node()
    27  	req := &structs.NodeRegisterRequest{
    28  		Node:         node,
    29  		WriteRequest: structs.WriteRequest{Region: "global"},
    30  	}
    31  
    32  	// Fetch the response
    33  	var resp structs.GenericResponse
    34  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", req, &resp); err != nil {
    35  		t.Fatalf("err: %v", err)
    36  	}
    37  	if resp.Index == 0 {
    38  		t.Fatalf("bad index: %d", resp.Index)
    39  	}
    40  
    41  	// Check for the node in the FSM
    42  	state := s1.fsm.State()
    43  	ws := memdb.NewWatchSet()
    44  	out, err := state.NodeByID(ws, node.ID)
    45  	if err != nil {
    46  		t.Fatalf("err: %v", err)
    47  	}
    48  	if out == nil {
    49  		t.Fatalf("expected node")
    50  	}
    51  	if out.CreateIndex != resp.Index {
    52  		t.Fatalf("index mis-match")
    53  	}
    54  	if out.ComputedClass == "" {
    55  		t.Fatal("ComputedClass not set")
    56  	}
    57  }
    58  
    59  func TestClientEndpoint_Register_NoSecret(t *testing.T) {
    60  	t.Parallel()
    61  	s1 := testServer(t, nil)
    62  	defer s1.Shutdown()
    63  	codec := rpcClient(t, s1)
    64  	testutil.WaitForLeader(t, s1.RPC)
    65  
    66  	// Create the register request
    67  	node := mock.Node()
    68  	node.SecretID = ""
    69  	req := &structs.NodeRegisterRequest{
    70  		Node:         node,
    71  		WriteRequest: structs.WriteRequest{Region: "global"},
    72  	}
    73  
    74  	// Fetch the response
    75  	var resp structs.GenericResponse
    76  	err := msgpackrpc.CallWithCodec(codec, "Node.Register", req, &resp)
    77  	if err == nil || !strings.Contains(err.Error(), "secret") {
    78  		t.Fatalf("Expecting error regarding missing secret id: %v", err)
    79  	}
    80  
    81  	// Update the node to be pre-0.5
    82  	node.Attributes["nomad.version"] = "0.4.1"
    83  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", req, &resp); err != nil {
    84  		t.Fatalf("Not expecting err: %v", err)
    85  	}
    86  	if resp.Index == 0 {
    87  		t.Fatalf("bad index: %d", resp.Index)
    88  	}
    89  
    90  	// Check for the node in the FSM
    91  	state := s1.fsm.State()
    92  	ws := memdb.NewWatchSet()
    93  	out, err := state.NodeByID(ws, node.ID)
    94  	if err != nil {
    95  		t.Fatalf("err: %v", err)
    96  	}
    97  	if out == nil {
    98  		t.Fatalf("expected node")
    99  	}
   100  	if out.CreateIndex != resp.Index {
   101  		t.Fatalf("index mis-match")
   102  	}
   103  	if out.ComputedClass == "" {
   104  		t.Fatal("ComputedClass not set")
   105  	}
   106  }
   107  
   108  func TestClientEndpoint_Register_SecretMismatch(t *testing.T) {
   109  	t.Parallel()
   110  	s1 := testServer(t, nil)
   111  	defer s1.Shutdown()
   112  	codec := rpcClient(t, s1)
   113  	testutil.WaitForLeader(t, s1.RPC)
   114  
   115  	// Create the register request
   116  	node := mock.Node()
   117  	req := &structs.NodeRegisterRequest{
   118  		Node:         node,
   119  		WriteRequest: structs.WriteRequest{Region: "global"},
   120  	}
   121  
   122  	// Fetch the response
   123  	var resp structs.GenericResponse
   124  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", req, &resp); err != nil {
   125  		t.Fatalf("err: %v", err)
   126  	}
   127  
   128  	// Update the nodes SecretID
   129  	node.SecretID = structs.GenerateUUID()
   130  	err := msgpackrpc.CallWithCodec(codec, "Node.Register", req, &resp)
   131  	if err == nil || !strings.Contains(err.Error(), "Not registering") {
   132  		t.Fatalf("Expecting error regarding mismatching secret id: %v", err)
   133  	}
   134  }
   135  
   136  func TestClientEndpoint_Deregister(t *testing.T) {
   137  	t.Parallel()
   138  	s1 := testServer(t, nil)
   139  	defer s1.Shutdown()
   140  	codec := rpcClient(t, s1)
   141  	testutil.WaitForLeader(t, s1.RPC)
   142  
   143  	// Create the register request
   144  	node := mock.Node()
   145  	reg := &structs.NodeRegisterRequest{
   146  		Node:         node,
   147  		WriteRequest: structs.WriteRequest{Region: "global"},
   148  	}
   149  
   150  	// Fetch the response
   151  	var resp structs.GenericResponse
   152  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   153  		t.Fatalf("err: %v", err)
   154  	}
   155  
   156  	// Deregister
   157  	dereg := &structs.NodeDeregisterRequest{
   158  		NodeID:       node.ID,
   159  		WriteRequest: structs.WriteRequest{Region: "global"},
   160  	}
   161  	var resp2 structs.GenericResponse
   162  	if err := msgpackrpc.CallWithCodec(codec, "Node.Deregister", dereg, &resp2); err != nil {
   163  		t.Fatalf("err: %v", err)
   164  	}
   165  	if resp2.Index == 0 {
   166  		t.Fatalf("bad index: %d", resp2.Index)
   167  	}
   168  
   169  	// Check for the node in the FSM
   170  	state := s1.fsm.State()
   171  	ws := memdb.NewWatchSet()
   172  	out, err := state.NodeByID(ws, node.ID)
   173  	if err != nil {
   174  		t.Fatalf("err: %v", err)
   175  	}
   176  	if out != nil {
   177  		t.Fatalf("unexpected node")
   178  	}
   179  }
   180  
   181  func TestClientEndpoint_Deregister_Vault(t *testing.T) {
   182  	t.Parallel()
   183  	s1 := testServer(t, nil)
   184  	defer s1.Shutdown()
   185  	codec := rpcClient(t, s1)
   186  	testutil.WaitForLeader(t, s1.RPC)
   187  
   188  	// Create the register request
   189  	node := mock.Node()
   190  	reg := &structs.NodeRegisterRequest{
   191  		Node:         node,
   192  		WriteRequest: structs.WriteRequest{Region: "global"},
   193  	}
   194  
   195  	// Fetch the response
   196  	var resp structs.GenericResponse
   197  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   198  		t.Fatalf("err: %v", err)
   199  	}
   200  
   201  	// Swap the servers Vault Client
   202  	tvc := &TestVaultClient{}
   203  	s1.vault = tvc
   204  
   205  	// Put some Vault accessors in the state store for that node
   206  	state := s1.fsm.State()
   207  	va1 := mock.VaultAccessor()
   208  	va1.NodeID = node.ID
   209  	va2 := mock.VaultAccessor()
   210  	va2.NodeID = node.ID
   211  	state.UpsertVaultAccessor(100, []*structs.VaultAccessor{va1, va2})
   212  
   213  	// Deregister
   214  	dereg := &structs.NodeDeregisterRequest{
   215  		NodeID:       node.ID,
   216  		WriteRequest: structs.WriteRequest{Region: "global"},
   217  	}
   218  	var resp2 structs.GenericResponse
   219  	if err := msgpackrpc.CallWithCodec(codec, "Node.Deregister", dereg, &resp2); err != nil {
   220  		t.Fatalf("err: %v", err)
   221  	}
   222  	if resp2.Index == 0 {
   223  		t.Fatalf("bad index: %d", resp2.Index)
   224  	}
   225  
   226  	// Check for the node in the FSM
   227  	ws := memdb.NewWatchSet()
   228  	out, err := state.NodeByID(ws, node.ID)
   229  	if err != nil {
   230  		t.Fatalf("err: %v", err)
   231  	}
   232  	if out != nil {
   233  		t.Fatalf("unexpected node")
   234  	}
   235  
   236  	// Check that the endpoint revoked the tokens
   237  	if l := len(tvc.RevokedTokens); l != 2 {
   238  		t.Fatalf("Deregister revoked %d tokens; want 2", l)
   239  	}
   240  }
   241  
   242  func TestClientEndpoint_UpdateStatus(t *testing.T) {
   243  	t.Parallel()
   244  	s1 := testServer(t, nil)
   245  	defer s1.Shutdown()
   246  	codec := rpcClient(t, s1)
   247  	testutil.WaitForLeader(t, s1.RPC)
   248  
   249  	// Create the register request
   250  	node := mock.Node()
   251  	reg := &structs.NodeRegisterRequest{
   252  		Node:         node,
   253  		WriteRequest: structs.WriteRequest{Region: "global"},
   254  	}
   255  
   256  	// Fetch the response
   257  	var resp structs.NodeUpdateResponse
   258  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   259  		t.Fatalf("err: %v", err)
   260  	}
   261  
   262  	// Check for heartbeat interval
   263  	ttl := resp.HeartbeatTTL
   264  	if ttl < s1.config.MinHeartbeatTTL || ttl > 2*s1.config.MinHeartbeatTTL {
   265  		t.Fatalf("bad: %#v", ttl)
   266  	}
   267  
   268  	// Update the status
   269  	dereg := &structs.NodeUpdateStatusRequest{
   270  		NodeID:       node.ID,
   271  		Status:       structs.NodeStatusInit,
   272  		WriteRequest: structs.WriteRequest{Region: "global"},
   273  	}
   274  	var resp2 structs.NodeUpdateResponse
   275  	if err := msgpackrpc.CallWithCodec(codec, "Node.UpdateStatus", dereg, &resp2); err != nil {
   276  		t.Fatalf("err: %v", err)
   277  	}
   278  	if resp2.Index == 0 {
   279  		t.Fatalf("bad index: %d", resp2.Index)
   280  	}
   281  
   282  	// Check for heartbeat interval
   283  	ttl = resp2.HeartbeatTTL
   284  	if ttl < s1.config.MinHeartbeatTTL || ttl > 2*s1.config.MinHeartbeatTTL {
   285  		t.Fatalf("bad: %#v", ttl)
   286  	}
   287  
   288  	// Check for the node in the FSM
   289  	state := s1.fsm.State()
   290  	ws := memdb.NewWatchSet()
   291  	out, err := state.NodeByID(ws, node.ID)
   292  	if err != nil {
   293  		t.Fatalf("err: %v", err)
   294  	}
   295  	if out == nil {
   296  		t.Fatalf("expected node")
   297  	}
   298  	if out.ModifyIndex != resp2.Index {
   299  		t.Fatalf("index mis-match")
   300  	}
   301  }
   302  
   303  func TestClientEndpoint_UpdateStatus_Vault(t *testing.T) {
   304  	t.Parallel()
   305  	s1 := testServer(t, nil)
   306  	defer s1.Shutdown()
   307  	codec := rpcClient(t, s1)
   308  	testutil.WaitForLeader(t, s1.RPC)
   309  
   310  	// Create the register request
   311  	node := mock.Node()
   312  	reg := &structs.NodeRegisterRequest{
   313  		Node:         node,
   314  		WriteRequest: structs.WriteRequest{Region: "global"},
   315  	}
   316  
   317  	// Fetch the response
   318  	var resp structs.NodeUpdateResponse
   319  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   320  		t.Fatalf("err: %v", err)
   321  	}
   322  
   323  	// Check for heartbeat interval
   324  	ttl := resp.HeartbeatTTL
   325  	if ttl < s1.config.MinHeartbeatTTL || ttl > 2*s1.config.MinHeartbeatTTL {
   326  		t.Fatalf("bad: %#v", ttl)
   327  	}
   328  
   329  	// Swap the servers Vault Client
   330  	tvc := &TestVaultClient{}
   331  	s1.vault = tvc
   332  
   333  	// Put some Vault accessors in the state store for that node
   334  	state := s1.fsm.State()
   335  	va1 := mock.VaultAccessor()
   336  	va1.NodeID = node.ID
   337  	va2 := mock.VaultAccessor()
   338  	va2.NodeID = node.ID
   339  	state.UpsertVaultAccessor(100, []*structs.VaultAccessor{va1, va2})
   340  
   341  	// Update the status to be down
   342  	dereg := &structs.NodeUpdateStatusRequest{
   343  		NodeID:       node.ID,
   344  		Status:       structs.NodeStatusDown,
   345  		WriteRequest: structs.WriteRequest{Region: "global"},
   346  	}
   347  	var resp2 structs.NodeUpdateResponse
   348  	if err := msgpackrpc.CallWithCodec(codec, "Node.UpdateStatus", dereg, &resp2); err != nil {
   349  		t.Fatalf("err: %v", err)
   350  	}
   351  	if resp2.Index == 0 {
   352  		t.Fatalf("bad index: %d", resp2.Index)
   353  	}
   354  
   355  	// Check that the endpoint revoked the tokens
   356  	if l := len(tvc.RevokedTokens); l != 2 {
   357  		t.Fatalf("Deregister revoked %d tokens; want 2", l)
   358  	}
   359  }
   360  
   361  func TestClientEndpoint_Register_GetEvals(t *testing.T) {
   362  	t.Parallel()
   363  	s1 := testServer(t, nil)
   364  	defer s1.Shutdown()
   365  	codec := rpcClient(t, s1)
   366  	testutil.WaitForLeader(t, s1.RPC)
   367  
   368  	// Register a system job.
   369  	job := mock.SystemJob()
   370  	state := s1.fsm.State()
   371  	if err := state.UpsertJob(1, job); err != nil {
   372  		t.Fatalf("err: %v", err)
   373  	}
   374  
   375  	// Create the register request going directly to ready
   376  	node := mock.Node()
   377  	node.Status = structs.NodeStatusReady
   378  	reg := &structs.NodeRegisterRequest{
   379  		Node:         node,
   380  		WriteRequest: structs.WriteRequest{Region: "global"},
   381  	}
   382  
   383  	// Fetch the response
   384  	var resp structs.NodeUpdateResponse
   385  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   386  		t.Fatalf("err: %v", err)
   387  	}
   388  
   389  	// Check for heartbeat interval
   390  	ttl := resp.HeartbeatTTL
   391  	if ttl < s1.config.MinHeartbeatTTL || ttl > 2*s1.config.MinHeartbeatTTL {
   392  		t.Fatalf("bad: %#v", ttl)
   393  	}
   394  
   395  	// Check for an eval caused by the system job.
   396  	if len(resp.EvalIDs) != 1 {
   397  		t.Fatalf("expected one eval; got %#v", resp.EvalIDs)
   398  	}
   399  
   400  	evalID := resp.EvalIDs[0]
   401  	ws := memdb.NewWatchSet()
   402  	eval, err := state.EvalByID(ws, evalID)
   403  	if err != nil {
   404  		t.Fatalf("could not get eval %v", evalID)
   405  	}
   406  
   407  	if eval.Type != "system" {
   408  		t.Fatalf("unexpected eval type; got %v; want %q", eval.Type, "system")
   409  	}
   410  
   411  	// Check for the node in the FSM
   412  	out, err := state.NodeByID(ws, node.ID)
   413  	if err != nil {
   414  		t.Fatalf("err: %v", err)
   415  	}
   416  	if out == nil {
   417  		t.Fatalf("expected node")
   418  	}
   419  	if out.ModifyIndex != resp.Index {
   420  		t.Fatalf("index mis-match")
   421  	}
   422  
   423  	// Transistion it to down and then ready
   424  	node.Status = structs.NodeStatusDown
   425  	reg = &structs.NodeRegisterRequest{
   426  		Node:         node,
   427  		WriteRequest: structs.WriteRequest{Region: "global"},
   428  	}
   429  
   430  	// Fetch the response
   431  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   432  		t.Fatalf("err: %v", err)
   433  	}
   434  
   435  	if len(resp.EvalIDs) != 1 {
   436  		t.Fatalf("expected one eval; got %#v", resp.EvalIDs)
   437  	}
   438  
   439  	node.Status = structs.NodeStatusReady
   440  	reg = &structs.NodeRegisterRequest{
   441  		Node:         node,
   442  		WriteRequest: structs.WriteRequest{Region: "global"},
   443  	}
   444  
   445  	// Fetch the response
   446  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   447  		t.Fatalf("err: %v", err)
   448  	}
   449  
   450  	if len(resp.EvalIDs) != 1 {
   451  		t.Fatalf("expected one eval; got %#v", resp.EvalIDs)
   452  	}
   453  }
   454  
   455  func TestClientEndpoint_UpdateStatus_GetEvals(t *testing.T) {
   456  	t.Parallel()
   457  	s1 := testServer(t, nil)
   458  	defer s1.Shutdown()
   459  	codec := rpcClient(t, s1)
   460  	testutil.WaitForLeader(t, s1.RPC)
   461  
   462  	// Register a system job.
   463  	job := mock.SystemJob()
   464  	state := s1.fsm.State()
   465  	if err := state.UpsertJob(1, job); err != nil {
   466  		t.Fatalf("err: %v", err)
   467  	}
   468  
   469  	// Create the register request
   470  	node := mock.Node()
   471  	node.Status = structs.NodeStatusInit
   472  	reg := &structs.NodeRegisterRequest{
   473  		Node:         node,
   474  		WriteRequest: structs.WriteRequest{Region: "global"},
   475  	}
   476  
   477  	// Fetch the response
   478  	var resp structs.NodeUpdateResponse
   479  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   480  		t.Fatalf("err: %v", err)
   481  	}
   482  
   483  	// Check for heartbeat interval
   484  	ttl := resp.HeartbeatTTL
   485  	if ttl < s1.config.MinHeartbeatTTL || ttl > 2*s1.config.MinHeartbeatTTL {
   486  		t.Fatalf("bad: %#v", ttl)
   487  	}
   488  
   489  	// Update the status
   490  	update := &structs.NodeUpdateStatusRequest{
   491  		NodeID:       node.ID,
   492  		Status:       structs.NodeStatusReady,
   493  		WriteRequest: structs.WriteRequest{Region: "global"},
   494  	}
   495  	var resp2 structs.NodeUpdateResponse
   496  	if err := msgpackrpc.CallWithCodec(codec, "Node.UpdateStatus", update, &resp2); err != nil {
   497  		t.Fatalf("err: %v", err)
   498  	}
   499  	if resp2.Index == 0 {
   500  		t.Fatalf("bad index: %d", resp2.Index)
   501  	}
   502  
   503  	// Check for an eval caused by the system job.
   504  	if len(resp2.EvalIDs) != 1 {
   505  		t.Fatalf("expected one eval; got %#v", resp2.EvalIDs)
   506  	}
   507  
   508  	evalID := resp2.EvalIDs[0]
   509  	ws := memdb.NewWatchSet()
   510  	eval, err := state.EvalByID(ws, evalID)
   511  	if err != nil {
   512  		t.Fatalf("could not get eval %v", evalID)
   513  	}
   514  
   515  	if eval.Type != "system" {
   516  		t.Fatalf("unexpected eval type; got %v; want %q", eval.Type, "system")
   517  	}
   518  
   519  	// Check for heartbeat interval
   520  	ttl = resp2.HeartbeatTTL
   521  	if ttl < s1.config.MinHeartbeatTTL || ttl > 2*s1.config.MinHeartbeatTTL {
   522  		t.Fatalf("bad: %#v", ttl)
   523  	}
   524  
   525  	// Check for the node in the FSM
   526  	out, err := state.NodeByID(ws, node.ID)
   527  	if err != nil {
   528  		t.Fatalf("err: %v", err)
   529  	}
   530  	if out == nil {
   531  		t.Fatalf("expected node")
   532  	}
   533  	if out.ModifyIndex != resp2.Index {
   534  		t.Fatalf("index mis-match")
   535  	}
   536  }
   537  
   538  func TestClientEndpoint_UpdateStatus_HeartbeatOnly(t *testing.T) {
   539  	t.Parallel()
   540  	s1 := testServer(t, nil)
   541  	defer s1.Shutdown()
   542  
   543  	s2 := testServer(t, func(c *Config) {
   544  		c.DevDisableBootstrap = true
   545  	})
   546  	defer s2.Shutdown()
   547  
   548  	s3 := testServer(t, func(c *Config) {
   549  		c.DevDisableBootstrap = true
   550  	})
   551  	defer s3.Shutdown()
   552  	servers := []*Server{s1, s2, s3}
   553  	testJoin(t, s1, s2, s3)
   554  
   555  	for _, s := range servers {
   556  		testutil.WaitForResult(func() (bool, error) {
   557  			peers, _ := s.numPeers()
   558  			return peers == 3, nil
   559  		}, func(err error) {
   560  			t.Fatalf("should have 3 peers")
   561  		})
   562  	}
   563  
   564  	codec := rpcClient(t, s1)
   565  	testutil.WaitForLeader(t, s1.RPC)
   566  
   567  	// Create the register request
   568  	node := mock.Node()
   569  	reg := &structs.NodeRegisterRequest{
   570  		Node:         node,
   571  		WriteRequest: structs.WriteRequest{Region: "global"},
   572  	}
   573  
   574  	// Fetch the response
   575  	var resp structs.NodeUpdateResponse
   576  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   577  		t.Fatalf("err: %v", err)
   578  	}
   579  
   580  	// Check for heartbeat interval
   581  	ttl := resp.HeartbeatTTL
   582  	if ttl < s1.config.MinHeartbeatTTL || ttl > 2*s1.config.MinHeartbeatTTL {
   583  		t.Fatalf("bad: %#v", ttl)
   584  	}
   585  
   586  	// Check for heartbeat servers
   587  	serverAddrs := resp.Servers
   588  	if len(serverAddrs) == 0 {
   589  		t.Fatalf("bad: %#v", serverAddrs)
   590  	}
   591  
   592  	// Update the status, static state
   593  	dereg := &structs.NodeUpdateStatusRequest{
   594  		NodeID:       node.ID,
   595  		Status:       node.Status,
   596  		WriteRequest: structs.WriteRequest{Region: "global"},
   597  	}
   598  	var resp2 structs.NodeUpdateResponse
   599  	if err := msgpackrpc.CallWithCodec(codec, "Node.UpdateStatus", dereg, &resp2); err != nil {
   600  		t.Fatalf("err: %v", err)
   601  	}
   602  	if resp2.Index != 0 {
   603  		t.Fatalf("bad index: %d", resp2.Index)
   604  	}
   605  
   606  	// Check for heartbeat interval
   607  	ttl = resp2.HeartbeatTTL
   608  	if ttl < s1.config.MinHeartbeatTTL || ttl > 2*s1.config.MinHeartbeatTTL {
   609  		t.Fatalf("bad: %#v", ttl)
   610  	}
   611  }
   612  
   613  func TestClientEndpoint_UpdateDrain(t *testing.T) {
   614  	t.Parallel()
   615  	s1 := testServer(t, nil)
   616  	defer s1.Shutdown()
   617  	codec := rpcClient(t, s1)
   618  	testutil.WaitForLeader(t, s1.RPC)
   619  
   620  	// Create the register request
   621  	node := mock.Node()
   622  	reg := &structs.NodeRegisterRequest{
   623  		Node:         node,
   624  		WriteRequest: structs.WriteRequest{Region: "global"},
   625  	}
   626  
   627  	// Fetch the response
   628  	var resp structs.NodeUpdateResponse
   629  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   630  		t.Fatalf("err: %v", err)
   631  	}
   632  
   633  	// Update the status
   634  	dereg := &structs.NodeUpdateDrainRequest{
   635  		NodeID:       node.ID,
   636  		Drain:        true,
   637  		WriteRequest: structs.WriteRequest{Region: "global"},
   638  	}
   639  	var resp2 structs.NodeDrainUpdateResponse
   640  	if err := msgpackrpc.CallWithCodec(codec, "Node.UpdateDrain", dereg, &resp2); err != nil {
   641  		t.Fatalf("err: %v", err)
   642  	}
   643  	if resp2.Index == 0 {
   644  		t.Fatalf("bad index: %d", resp2.Index)
   645  	}
   646  
   647  	// Check for the node in the FSM
   648  	state := s1.fsm.State()
   649  	ws := memdb.NewWatchSet()
   650  	out, err := state.NodeByID(ws, node.ID)
   651  	if err != nil {
   652  		t.Fatalf("err: %v", err)
   653  	}
   654  	if !out.Drain {
   655  		t.Fatalf("bad: %#v", out)
   656  	}
   657  }
   658  
   659  // This test ensures that Nomad marks client state of allocations which are in
   660  // pending/running state to lost when a node is marked as down.
   661  func TestClientEndpoint_Drain_Down(t *testing.T) {
   662  	t.Parallel()
   663  	s1 := testServer(t, nil)
   664  	defer s1.Shutdown()
   665  	codec := rpcClient(t, s1)
   666  	testutil.WaitForLeader(t, s1.RPC)
   667  
   668  	// Register a node
   669  	node := mock.Node()
   670  	reg := &structs.NodeRegisterRequest{
   671  		Node:         node,
   672  		WriteRequest: structs.WriteRequest{Region: "global"},
   673  	}
   674  	// Fetch the response
   675  	var resp structs.NodeUpdateResponse
   676  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   677  		t.Fatalf("err: %v", err)
   678  	}
   679  
   680  	// Register a service job
   681  	var jobResp structs.JobRegisterResponse
   682  	job := mock.Job()
   683  	job.TaskGroups[0].Count = 1
   684  	jobReq := &structs.JobRegisterRequest{
   685  		Job:          job,
   686  		WriteRequest: structs.WriteRequest{Region: "global"},
   687  	}
   688  	if err := msgpackrpc.CallWithCodec(codec, "Job.Register", jobReq, &jobResp); err != nil {
   689  		t.Fatalf("err: %v", err)
   690  	}
   691  
   692  	// Register a system job
   693  	var jobResp1 structs.JobRegisterResponse
   694  	job1 := mock.Job()
   695  	job1.TaskGroups[0].Count = 1
   696  	job1.Type = structs.JobTypeSystem
   697  	jobReq1 := &structs.JobRegisterRequest{
   698  		Job:          job1,
   699  		WriteRequest: structs.WriteRequest{Region: "global"},
   700  	}
   701  	if err := msgpackrpc.CallWithCodec(codec, "Job.Register", jobReq1, &jobResp1); err != nil {
   702  		t.Fatalf("err: %v", err)
   703  	}
   704  
   705  	// Wait for the scheduler to create an allocation
   706  	testutil.WaitForResult(func() (bool, error) {
   707  		ws := memdb.NewWatchSet()
   708  		allocs, err := s1.fsm.state.AllocsByJob(ws, job.ID, true)
   709  		if err != nil {
   710  			return false, err
   711  		}
   712  		allocs1, err := s1.fsm.state.AllocsByJob(ws, job1.ID, true)
   713  		if err != nil {
   714  			return false, err
   715  		}
   716  		return len(allocs) > 0 && len(allocs1) > 0, nil
   717  	}, func(err error) {
   718  		t.Fatalf("err: %v", err)
   719  	})
   720  
   721  	// Drain the node
   722  	dereg := &structs.NodeUpdateDrainRequest{
   723  		NodeID:       node.ID,
   724  		Drain:        true,
   725  		WriteRequest: structs.WriteRequest{Region: "global"},
   726  	}
   727  	var resp2 structs.NodeDrainUpdateResponse
   728  	if err := msgpackrpc.CallWithCodec(codec, "Node.UpdateDrain", dereg, &resp2); err != nil {
   729  		t.Fatalf("err: %v", err)
   730  	}
   731  
   732  	// Mark the node as down
   733  	node.Status = structs.NodeStatusDown
   734  	reg = &structs.NodeRegisterRequest{
   735  		Node:         node,
   736  		WriteRequest: structs.WriteRequest{Region: "global"},
   737  	}
   738  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   739  		t.Fatalf("err: %v", err)
   740  	}
   741  
   742  	// Ensure that the allocation has transitioned to lost
   743  	testutil.WaitForResult(func() (bool, error) {
   744  		ws := memdb.NewWatchSet()
   745  		summary, err := s1.fsm.state.JobSummaryByID(ws, job.ID)
   746  		if err != nil {
   747  			return false, err
   748  		}
   749  		expectedSummary := &structs.JobSummary{
   750  			JobID: job.ID,
   751  			Summary: map[string]structs.TaskGroupSummary{
   752  				"web": structs.TaskGroupSummary{
   753  					Queued: 1,
   754  					Lost:   1,
   755  				},
   756  			},
   757  			Children:    new(structs.JobChildrenSummary),
   758  			CreateIndex: jobResp.JobModifyIndex,
   759  			ModifyIndex: summary.ModifyIndex,
   760  		}
   761  		if !reflect.DeepEqual(summary, expectedSummary) {
   762  			return false, fmt.Errorf("expected: %#v, actual: %#v", expectedSummary, summary)
   763  		}
   764  
   765  		summary1, err := s1.fsm.state.JobSummaryByID(ws, job1.ID)
   766  		if err != nil {
   767  			return false, err
   768  		}
   769  		expectedSummary1 := &structs.JobSummary{
   770  			JobID: job1.ID,
   771  			Summary: map[string]structs.TaskGroupSummary{
   772  				"web": structs.TaskGroupSummary{
   773  					Lost: 1,
   774  				},
   775  			},
   776  			Children:    new(structs.JobChildrenSummary),
   777  			CreateIndex: jobResp1.JobModifyIndex,
   778  			ModifyIndex: summary1.ModifyIndex,
   779  		}
   780  		if !reflect.DeepEqual(summary1, expectedSummary1) {
   781  			return false, fmt.Errorf("expected: %#v, actual: %#v", expectedSummary1, summary1)
   782  		}
   783  		return true, nil
   784  	}, func(err error) {
   785  		t.Fatalf("err: %v", err)
   786  	})
   787  }
   788  
   789  func TestClientEndpoint_GetNode(t *testing.T) {
   790  	t.Parallel()
   791  	s1 := testServer(t, nil)
   792  	defer s1.Shutdown()
   793  	codec := rpcClient(t, s1)
   794  	testutil.WaitForLeader(t, s1.RPC)
   795  
   796  	// Create the register request
   797  	node := mock.Node()
   798  	reg := &structs.NodeRegisterRequest{
   799  		Node:         node,
   800  		WriteRequest: structs.WriteRequest{Region: "global"},
   801  	}
   802  
   803  	// Fetch the response
   804  	var resp structs.GenericResponse
   805  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   806  		t.Fatalf("err: %v", err)
   807  	}
   808  	node.CreateIndex = resp.Index
   809  	node.ModifyIndex = resp.Index
   810  
   811  	// Lookup the node
   812  	get := &structs.NodeSpecificRequest{
   813  		NodeID:       node.ID,
   814  		QueryOptions: structs.QueryOptions{Region: "global"},
   815  	}
   816  	var resp2 structs.SingleNodeResponse
   817  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetNode", get, &resp2); err != nil {
   818  		t.Fatalf("err: %v", err)
   819  	}
   820  	if resp2.Index != resp.Index {
   821  		t.Fatalf("Bad index: %d %d", resp2.Index, resp.Index)
   822  	}
   823  
   824  	if resp2.Node.ComputedClass == "" {
   825  		t.Fatalf("bad ComputedClass: %#v", resp2.Node)
   826  	}
   827  
   828  	// Update the status updated at value
   829  	node.StatusUpdatedAt = resp2.Node.StatusUpdatedAt
   830  	node.SecretID = ""
   831  	if !reflect.DeepEqual(node, resp2.Node) {
   832  		t.Fatalf("bad: %#v \n %#v", node, resp2.Node)
   833  	}
   834  
   835  	// Lookup non-existing node
   836  	get.NodeID = "12345678-abcd-efab-cdef-123456789abc"
   837  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetNode", get, &resp2); err != nil {
   838  		t.Fatalf("err: %v", err)
   839  	}
   840  	if resp2.Index != resp.Index {
   841  		t.Fatalf("Bad index: %d %d", resp2.Index, resp.Index)
   842  	}
   843  	if resp2.Node != nil {
   844  		t.Fatalf("unexpected node")
   845  	}
   846  }
   847  
   848  func TestClientEndpoint_GetNode_Blocking(t *testing.T) {
   849  	t.Parallel()
   850  	s1 := testServer(t, nil)
   851  	defer s1.Shutdown()
   852  	state := s1.fsm.State()
   853  	codec := rpcClient(t, s1)
   854  	testutil.WaitForLeader(t, s1.RPC)
   855  
   856  	// Create the node
   857  	node1 := mock.Node()
   858  	node2 := mock.Node()
   859  
   860  	// First create an unrelated node.
   861  	time.AfterFunc(100*time.Millisecond, func() {
   862  		if err := state.UpsertNode(100, node1); err != nil {
   863  			t.Fatalf("err: %v", err)
   864  		}
   865  	})
   866  
   867  	// Upsert the node we are watching later
   868  	time.AfterFunc(200*time.Millisecond, func() {
   869  		if err := state.UpsertNode(200, node2); err != nil {
   870  			t.Fatalf("err: %v", err)
   871  		}
   872  	})
   873  
   874  	// Lookup the node
   875  	req := &structs.NodeSpecificRequest{
   876  		NodeID: node2.ID,
   877  		QueryOptions: structs.QueryOptions{
   878  			Region:        "global",
   879  			MinQueryIndex: 150,
   880  		},
   881  	}
   882  	var resp structs.SingleNodeResponse
   883  	start := time.Now()
   884  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetNode", req, &resp); err != nil {
   885  		t.Fatalf("err: %v", err)
   886  	}
   887  
   888  	if elapsed := time.Since(start); elapsed < 200*time.Millisecond {
   889  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp)
   890  	}
   891  	if resp.Index != 200 {
   892  		t.Fatalf("Bad index: %d %d", resp.Index, 200)
   893  	}
   894  	if resp.Node == nil || resp.Node.ID != node2.ID {
   895  		t.Fatalf("bad: %#v", resp.Node)
   896  	}
   897  
   898  	// Node update triggers watches
   899  	time.AfterFunc(100*time.Millisecond, func() {
   900  		nodeUpdate := mock.Node()
   901  		nodeUpdate.ID = node2.ID
   902  		nodeUpdate.Status = structs.NodeStatusDown
   903  		if err := state.UpsertNode(300, nodeUpdate); err != nil {
   904  			t.Fatalf("err: %v", err)
   905  		}
   906  	})
   907  
   908  	req.QueryOptions.MinQueryIndex = 250
   909  	var resp2 structs.SingleNodeResponse
   910  	start = time.Now()
   911  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetNode", req, &resp2); err != nil {
   912  		t.Fatalf("err: %v", err)
   913  	}
   914  
   915  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
   916  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp)
   917  	}
   918  	if resp2.Index != 300 {
   919  		t.Fatalf("Bad index: %d %d", resp2.Index, 300)
   920  	}
   921  	if resp2.Node == nil || resp2.Node.Status != structs.NodeStatusDown {
   922  		t.Fatalf("bad: %#v", resp2.Node)
   923  	}
   924  
   925  	// Node delete triggers watches
   926  	time.AfterFunc(100*time.Millisecond, func() {
   927  		if err := state.DeleteNode(400, node2.ID); err != nil {
   928  			t.Fatalf("err: %v", err)
   929  		}
   930  	})
   931  
   932  	req.QueryOptions.MinQueryIndex = 350
   933  	var resp3 structs.SingleNodeResponse
   934  	start = time.Now()
   935  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetNode", req, &resp3); err != nil {
   936  		t.Fatalf("err: %v", err)
   937  	}
   938  
   939  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
   940  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp)
   941  	}
   942  	if resp3.Index != 400 {
   943  		t.Fatalf("Bad index: %d %d", resp2.Index, 400)
   944  	}
   945  	if resp3.Node != nil {
   946  		t.Fatalf("bad: %#v", resp3.Node)
   947  	}
   948  }
   949  
   950  func TestClientEndpoint_GetAllocs(t *testing.T) {
   951  	t.Parallel()
   952  	s1 := testServer(t, nil)
   953  	defer s1.Shutdown()
   954  	codec := rpcClient(t, s1)
   955  	testutil.WaitForLeader(t, s1.RPC)
   956  
   957  	// Create the register request
   958  	node := mock.Node()
   959  	reg := &structs.NodeRegisterRequest{
   960  		Node:         node,
   961  		WriteRequest: structs.WriteRequest{Region: "global"},
   962  	}
   963  
   964  	// Fetch the response
   965  	var resp structs.GenericResponse
   966  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
   967  		t.Fatalf("err: %v", err)
   968  	}
   969  	node.CreateIndex = resp.Index
   970  	node.ModifyIndex = resp.Index
   971  
   972  	// Inject fake evaluations
   973  	alloc := mock.Alloc()
   974  	alloc.NodeID = node.ID
   975  	state := s1.fsm.State()
   976  	state.UpsertJobSummary(99, mock.JobSummary(alloc.JobID))
   977  	err := state.UpsertAllocs(100, []*structs.Allocation{alloc})
   978  	if err != nil {
   979  		t.Fatalf("err: %v", err)
   980  	}
   981  
   982  	// Lookup the allocs
   983  	get := &structs.NodeSpecificRequest{
   984  		NodeID:       node.ID,
   985  		QueryOptions: structs.QueryOptions{Region: "global"},
   986  	}
   987  	var resp2 structs.NodeAllocsResponse
   988  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetAllocs", get, &resp2); err != nil {
   989  		t.Fatalf("err: %v", err)
   990  	}
   991  	if resp2.Index != 100 {
   992  		t.Fatalf("Bad index: %d %d", resp2.Index, 100)
   993  	}
   994  
   995  	if len(resp2.Allocs) != 1 || resp2.Allocs[0].ID != alloc.ID {
   996  		t.Fatalf("bad: %#v", resp2.Allocs)
   997  	}
   998  
   999  	// Lookup non-existing node
  1000  	get.NodeID = "foobarbaz"
  1001  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetAllocs", get, &resp2); err != nil {
  1002  		t.Fatalf("err: %v", err)
  1003  	}
  1004  	if resp2.Index != 100 {
  1005  		t.Fatalf("Bad index: %d %d", resp2.Index, 100)
  1006  	}
  1007  	if len(resp2.Allocs) != 0 {
  1008  		t.Fatalf("unexpected node")
  1009  	}
  1010  }
  1011  
  1012  func TestClientEndpoint_GetClientAllocs(t *testing.T) {
  1013  	t.Parallel()
  1014  	s1 := testServer(t, nil)
  1015  	defer s1.Shutdown()
  1016  	codec := rpcClient(t, s1)
  1017  	testutil.WaitForLeader(t, s1.RPC)
  1018  
  1019  	// Create the register request
  1020  	node := mock.Node()
  1021  	reg := &structs.NodeRegisterRequest{
  1022  		Node:         node,
  1023  		WriteRequest: structs.WriteRequest{Region: "global"},
  1024  	}
  1025  
  1026  	// Fetch the response
  1027  	var resp structs.GenericResponse
  1028  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
  1029  		t.Fatalf("err: %v", err)
  1030  	}
  1031  	node.CreateIndex = resp.Index
  1032  	node.ModifyIndex = resp.Index
  1033  
  1034  	// Inject fake evaluations
  1035  	alloc := mock.Alloc()
  1036  	alloc.NodeID = node.ID
  1037  	state := s1.fsm.State()
  1038  	state.UpsertJobSummary(99, mock.JobSummary(alloc.JobID))
  1039  	err := state.UpsertAllocs(100, []*structs.Allocation{alloc})
  1040  	if err != nil {
  1041  		t.Fatalf("err: %v", err)
  1042  	}
  1043  
  1044  	// Lookup the allocs
  1045  	get := &structs.NodeSpecificRequest{
  1046  		NodeID:       node.ID,
  1047  		SecretID:     node.SecretID,
  1048  		QueryOptions: structs.QueryOptions{Region: "global"},
  1049  	}
  1050  	var resp2 structs.NodeClientAllocsResponse
  1051  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetClientAllocs", get, &resp2); err != nil {
  1052  		t.Fatalf("err: %v", err)
  1053  	}
  1054  	if resp2.Index != 100 {
  1055  		t.Fatalf("Bad index: %d %d", resp2.Index, 100)
  1056  	}
  1057  
  1058  	if len(resp2.Allocs) != 1 || resp2.Allocs[alloc.ID] != 100 {
  1059  		t.Fatalf("bad: %#v", resp2.Allocs)
  1060  	}
  1061  
  1062  	// Lookup node with bad SecretID
  1063  	get.SecretID = "foobarbaz"
  1064  	var resp3 structs.NodeClientAllocsResponse
  1065  	err = msgpackrpc.CallWithCodec(codec, "Node.GetClientAllocs", get, &resp3)
  1066  	if err == nil || !strings.Contains(err.Error(), "does not match") {
  1067  		t.Fatalf("err: %v", err)
  1068  	}
  1069  
  1070  	// Lookup non-existing node
  1071  	get.NodeID = structs.GenerateUUID()
  1072  	var resp4 structs.NodeClientAllocsResponse
  1073  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetClientAllocs", get, &resp4); err != nil {
  1074  		t.Fatalf("err: %v", err)
  1075  	}
  1076  	if resp4.Index != 100 {
  1077  		t.Fatalf("Bad index: %d %d", resp3.Index, 100)
  1078  	}
  1079  	if len(resp4.Allocs) != 0 {
  1080  		t.Fatalf("unexpected node %#v", resp3.Allocs)
  1081  	}
  1082  }
  1083  
  1084  func TestClientEndpoint_GetClientAllocs_Blocking(t *testing.T) {
  1085  	t.Parallel()
  1086  	s1 := testServer(t, nil)
  1087  	defer s1.Shutdown()
  1088  	codec := rpcClient(t, s1)
  1089  	testutil.WaitForLeader(t, s1.RPC)
  1090  
  1091  	// Create the register request
  1092  	node := mock.Node()
  1093  	reg := &structs.NodeRegisterRequest{
  1094  		Node:         node,
  1095  		WriteRequest: structs.WriteRequest{Region: "global"},
  1096  	}
  1097  
  1098  	// Fetch the response
  1099  	var resp structs.GenericResponse
  1100  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
  1101  		t.Fatalf("err: %v", err)
  1102  	}
  1103  	node.CreateIndex = resp.Index
  1104  	node.ModifyIndex = resp.Index
  1105  
  1106  	// Inject fake evaluations async
  1107  	alloc := mock.Alloc()
  1108  	alloc.NodeID = node.ID
  1109  	state := s1.fsm.State()
  1110  	state.UpsertJobSummary(99, mock.JobSummary(alloc.JobID))
  1111  	start := time.Now()
  1112  	time.AfterFunc(100*time.Millisecond, func() {
  1113  		err := state.UpsertAllocs(100, []*structs.Allocation{alloc})
  1114  		if err != nil {
  1115  			t.Fatalf("err: %v", err)
  1116  		}
  1117  	})
  1118  
  1119  	// Lookup the allocs in a blocking query
  1120  	req := &structs.NodeSpecificRequest{
  1121  		NodeID:   node.ID,
  1122  		SecretID: node.SecretID,
  1123  		QueryOptions: structs.QueryOptions{
  1124  			Region:        "global",
  1125  			MinQueryIndex: 50,
  1126  			MaxQueryTime:  time.Second,
  1127  		},
  1128  	}
  1129  	var resp2 structs.NodeClientAllocsResponse
  1130  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetClientAllocs", req, &resp2); err != nil {
  1131  		t.Fatalf("err: %v", err)
  1132  	}
  1133  
  1134  	// Should block at least 100ms
  1135  	if time.Since(start) < 100*time.Millisecond {
  1136  		t.Fatalf("too fast")
  1137  	}
  1138  
  1139  	if resp2.Index != 100 {
  1140  		t.Fatalf("Bad index: %d %d", resp2.Index, 100)
  1141  	}
  1142  
  1143  	if len(resp2.Allocs) != 1 || resp2.Allocs[alloc.ID] != 100 {
  1144  		t.Fatalf("bad: %#v", resp2.Allocs)
  1145  	}
  1146  
  1147  	// Alloc updates fire watches
  1148  	time.AfterFunc(100*time.Millisecond, func() {
  1149  		allocUpdate := mock.Alloc()
  1150  		allocUpdate.NodeID = alloc.NodeID
  1151  		allocUpdate.ID = alloc.ID
  1152  		allocUpdate.ClientStatus = structs.AllocClientStatusRunning
  1153  		state.UpsertJobSummary(199, mock.JobSummary(allocUpdate.JobID))
  1154  		err := state.UpsertAllocs(200, []*structs.Allocation{allocUpdate})
  1155  		if err != nil {
  1156  			t.Fatalf("err: %v", err)
  1157  		}
  1158  	})
  1159  
  1160  	req.QueryOptions.MinQueryIndex = 150
  1161  	var resp3 structs.NodeClientAllocsResponse
  1162  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetClientAllocs", req, &resp3); err != nil {
  1163  		t.Fatalf("err: %v", err)
  1164  	}
  1165  
  1166  	if time.Since(start) < 100*time.Millisecond {
  1167  		t.Fatalf("too fast")
  1168  	}
  1169  	if resp3.Index != 200 {
  1170  		t.Fatalf("Bad index: %d %d", resp3.Index, 200)
  1171  	}
  1172  	if len(resp3.Allocs) != 1 || resp3.Allocs[alloc.ID] != 200 {
  1173  		t.Fatalf("bad: %#v", resp3.Allocs)
  1174  	}
  1175  }
  1176  
  1177  func TestClientEndpoint_GetAllocs_Blocking(t *testing.T) {
  1178  	t.Parallel()
  1179  	s1 := testServer(t, nil)
  1180  	defer s1.Shutdown()
  1181  	codec := rpcClient(t, s1)
  1182  	testutil.WaitForLeader(t, s1.RPC)
  1183  
  1184  	// Create the register request
  1185  	node := mock.Node()
  1186  	reg := &structs.NodeRegisterRequest{
  1187  		Node:         node,
  1188  		WriteRequest: structs.WriteRequest{Region: "global"},
  1189  	}
  1190  
  1191  	// Fetch the response
  1192  	var resp structs.GenericResponse
  1193  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
  1194  		t.Fatalf("err: %v", err)
  1195  	}
  1196  	node.CreateIndex = resp.Index
  1197  	node.ModifyIndex = resp.Index
  1198  
  1199  	// Inject fake evaluations async
  1200  	alloc := mock.Alloc()
  1201  	alloc.NodeID = node.ID
  1202  	state := s1.fsm.State()
  1203  	state.UpsertJobSummary(99, mock.JobSummary(alloc.JobID))
  1204  	start := time.Now()
  1205  	time.AfterFunc(100*time.Millisecond, func() {
  1206  		err := state.UpsertAllocs(100, []*structs.Allocation{alloc})
  1207  		if err != nil {
  1208  			t.Fatalf("err: %v", err)
  1209  		}
  1210  	})
  1211  
  1212  	// Lookup the allocs in a blocking query
  1213  	req := &structs.NodeSpecificRequest{
  1214  		NodeID: node.ID,
  1215  		QueryOptions: structs.QueryOptions{
  1216  			Region:        "global",
  1217  			MinQueryIndex: 50,
  1218  			MaxQueryTime:  time.Second,
  1219  		},
  1220  	}
  1221  	var resp2 structs.NodeAllocsResponse
  1222  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetAllocs", req, &resp2); err != nil {
  1223  		t.Fatalf("err: %v", err)
  1224  	}
  1225  
  1226  	// Should block at least 100ms
  1227  	if time.Since(start) < 100*time.Millisecond {
  1228  		t.Fatalf("too fast")
  1229  	}
  1230  
  1231  	if resp2.Index != 100 {
  1232  		t.Fatalf("Bad index: %d %d", resp2.Index, 100)
  1233  	}
  1234  
  1235  	if len(resp2.Allocs) != 1 || resp2.Allocs[0].ID != alloc.ID {
  1236  		t.Fatalf("bad: %#v", resp2.Allocs)
  1237  	}
  1238  
  1239  	// Alloc updates fire watches
  1240  	time.AfterFunc(100*time.Millisecond, func() {
  1241  		allocUpdate := mock.Alloc()
  1242  		allocUpdate.NodeID = alloc.NodeID
  1243  		allocUpdate.ID = alloc.ID
  1244  		allocUpdate.ClientStatus = structs.AllocClientStatusRunning
  1245  		state.UpsertJobSummary(199, mock.JobSummary(allocUpdate.JobID))
  1246  		err := state.UpdateAllocsFromClient(200, []*structs.Allocation{allocUpdate})
  1247  		if err != nil {
  1248  			t.Fatalf("err: %v", err)
  1249  		}
  1250  	})
  1251  
  1252  	req.QueryOptions.MinQueryIndex = 150
  1253  	var resp3 structs.NodeAllocsResponse
  1254  	if err := msgpackrpc.CallWithCodec(codec, "Node.GetAllocs", req, &resp3); err != nil {
  1255  		t.Fatalf("err: %v", err)
  1256  	}
  1257  
  1258  	if time.Since(start) < 100*time.Millisecond {
  1259  		t.Fatalf("too fast")
  1260  	}
  1261  	if resp3.Index != 200 {
  1262  		t.Fatalf("Bad index: %d %d", resp3.Index, 200)
  1263  	}
  1264  	if len(resp3.Allocs) != 1 || resp3.Allocs[0].ClientStatus != structs.AllocClientStatusRunning {
  1265  		t.Fatalf("bad: %#v", resp3.Allocs[0])
  1266  	}
  1267  }
  1268  
  1269  func TestClientEndpoint_UpdateAlloc(t *testing.T) {
  1270  	t.Parallel()
  1271  	s1 := testServer(t, nil)
  1272  	defer s1.Shutdown()
  1273  	codec := rpcClient(t, s1)
  1274  	testutil.WaitForLeader(t, s1.RPC)
  1275  
  1276  	// Create the register request
  1277  	node := mock.Node()
  1278  	reg := &structs.NodeRegisterRequest{
  1279  		Node:         node,
  1280  		WriteRequest: structs.WriteRequest{Region: "global"},
  1281  	}
  1282  
  1283  	// Fetch the response
  1284  	var resp structs.GenericResponse
  1285  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
  1286  		t.Fatalf("err: %v", err)
  1287  	}
  1288  
  1289  	// Inject fake evaluations
  1290  	alloc := mock.Alloc()
  1291  	alloc.NodeID = node.ID
  1292  	state := s1.fsm.State()
  1293  	state.UpsertJobSummary(99, mock.JobSummary(alloc.JobID))
  1294  	err := state.UpsertAllocs(100, []*structs.Allocation{alloc})
  1295  	if err != nil {
  1296  		t.Fatalf("err: %v", err)
  1297  	}
  1298  
  1299  	// Attempt update
  1300  	clientAlloc := new(structs.Allocation)
  1301  	*clientAlloc = *alloc
  1302  	clientAlloc.ClientStatus = structs.AllocClientStatusFailed
  1303  
  1304  	// Update the alloc
  1305  	update := &structs.AllocUpdateRequest{
  1306  		Alloc:        []*structs.Allocation{clientAlloc},
  1307  		WriteRequest: structs.WriteRequest{Region: "global"},
  1308  	}
  1309  	var resp2 structs.NodeAllocsResponse
  1310  	start := time.Now()
  1311  	if err := msgpackrpc.CallWithCodec(codec, "Node.UpdateAlloc", update, &resp2); err != nil {
  1312  		t.Fatalf("err: %v", err)
  1313  	}
  1314  	if resp2.Index == 0 {
  1315  		t.Fatalf("Bad index: %d", resp2.Index)
  1316  	}
  1317  	if diff := time.Since(start); diff < batchUpdateInterval {
  1318  		t.Fatalf("too fast: %v", diff)
  1319  	}
  1320  
  1321  	// Lookup the alloc
  1322  	ws := memdb.NewWatchSet()
  1323  	out, err := state.AllocByID(ws, alloc.ID)
  1324  	if err != nil {
  1325  		t.Fatalf("err: %v", err)
  1326  	}
  1327  	if out.ClientStatus != structs.AllocClientStatusFailed {
  1328  		t.Fatalf("Bad: %#v", out)
  1329  	}
  1330  }
  1331  
  1332  func TestClientEndpoint_BatchUpdate(t *testing.T) {
  1333  	t.Parallel()
  1334  	s1 := testServer(t, nil)
  1335  	defer s1.Shutdown()
  1336  	codec := rpcClient(t, s1)
  1337  	testutil.WaitForLeader(t, s1.RPC)
  1338  
  1339  	// Create the register request
  1340  	node := mock.Node()
  1341  	reg := &structs.NodeRegisterRequest{
  1342  		Node:         node,
  1343  		WriteRequest: structs.WriteRequest{Region: "global"},
  1344  	}
  1345  
  1346  	// Fetch the response
  1347  	var resp structs.GenericResponse
  1348  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
  1349  		t.Fatalf("err: %v", err)
  1350  	}
  1351  
  1352  	// Inject fake evaluations
  1353  	alloc := mock.Alloc()
  1354  	alloc.NodeID = node.ID
  1355  	state := s1.fsm.State()
  1356  	state.UpsertJobSummary(99, mock.JobSummary(alloc.JobID))
  1357  	err := state.UpsertAllocs(100, []*structs.Allocation{alloc})
  1358  	if err != nil {
  1359  		t.Fatalf("err: %v", err)
  1360  	}
  1361  
  1362  	// Attempt update
  1363  	clientAlloc := new(structs.Allocation)
  1364  	*clientAlloc = *alloc
  1365  	clientAlloc.ClientStatus = structs.AllocClientStatusFailed
  1366  
  1367  	// Call to do the batch update
  1368  	bf := NewBatchFuture()
  1369  	endpoint := s1.endpoints.Node
  1370  	endpoint.batchUpdate(bf, []*structs.Allocation{clientAlloc})
  1371  	if err := bf.Wait(); err != nil {
  1372  		t.Fatalf("err: %v", err)
  1373  	}
  1374  	if bf.Index() == 0 {
  1375  		t.Fatalf("Bad index: %d", bf.Index())
  1376  	}
  1377  
  1378  	// Lookup the alloc
  1379  	ws := memdb.NewWatchSet()
  1380  	out, err := state.AllocByID(ws, alloc.ID)
  1381  	if err != nil {
  1382  		t.Fatalf("err: %v", err)
  1383  	}
  1384  	if out.ClientStatus != structs.AllocClientStatusFailed {
  1385  		t.Fatalf("Bad: %#v", out)
  1386  	}
  1387  }
  1388  
  1389  func TestClientEndpoint_UpdateAlloc_Vault(t *testing.T) {
  1390  	t.Parallel()
  1391  	s1 := testServer(t, nil)
  1392  	defer s1.Shutdown()
  1393  	codec := rpcClient(t, s1)
  1394  	testutil.WaitForLeader(t, s1.RPC)
  1395  
  1396  	// Create the register request
  1397  	node := mock.Node()
  1398  	reg := &structs.NodeRegisterRequest{
  1399  		Node:         node,
  1400  		WriteRequest: structs.WriteRequest{Region: "global"},
  1401  	}
  1402  
  1403  	// Fetch the response
  1404  	var resp structs.GenericResponse
  1405  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
  1406  		t.Fatalf("err: %v", err)
  1407  	}
  1408  
  1409  	// Swap the servers Vault Client
  1410  	tvc := &TestVaultClient{}
  1411  	s1.vault = tvc
  1412  
  1413  	// Inject fake allocation and vault accessor
  1414  	alloc := mock.Alloc()
  1415  	alloc.NodeID = node.ID
  1416  	state := s1.fsm.State()
  1417  	state.UpsertJobSummary(99, mock.JobSummary(alloc.JobID))
  1418  	if err := state.UpsertAllocs(100, []*structs.Allocation{alloc}); err != nil {
  1419  		t.Fatalf("err: %v", err)
  1420  	}
  1421  
  1422  	va := mock.VaultAccessor()
  1423  	va.NodeID = node.ID
  1424  	va.AllocID = alloc.ID
  1425  	if err := state.UpsertVaultAccessor(101, []*structs.VaultAccessor{va}); err != nil {
  1426  		t.Fatalf("err: %v", err)
  1427  	}
  1428  
  1429  	// Attempt update
  1430  	clientAlloc := new(structs.Allocation)
  1431  	*clientAlloc = *alloc
  1432  	clientAlloc.ClientStatus = structs.AllocClientStatusFailed
  1433  
  1434  	// Update the alloc
  1435  	update := &structs.AllocUpdateRequest{
  1436  		Alloc:        []*structs.Allocation{clientAlloc},
  1437  		WriteRequest: structs.WriteRequest{Region: "global"},
  1438  	}
  1439  	var resp2 structs.NodeAllocsResponse
  1440  	start := time.Now()
  1441  	if err := msgpackrpc.CallWithCodec(codec, "Node.UpdateAlloc", update, &resp2); err != nil {
  1442  		t.Fatalf("err: %v", err)
  1443  	}
  1444  	if resp2.Index == 0 {
  1445  		t.Fatalf("Bad index: %d", resp2.Index)
  1446  	}
  1447  	if diff := time.Since(start); diff < batchUpdateInterval {
  1448  		t.Fatalf("too fast: %v", diff)
  1449  	}
  1450  
  1451  	// Lookup the alloc
  1452  	ws := memdb.NewWatchSet()
  1453  	out, err := state.AllocByID(ws, alloc.ID)
  1454  	if err != nil {
  1455  		t.Fatalf("err: %v", err)
  1456  	}
  1457  	if out.ClientStatus != structs.AllocClientStatusFailed {
  1458  		t.Fatalf("Bad: %#v", out)
  1459  	}
  1460  
  1461  	if l := len(tvc.RevokedTokens); l != 1 {
  1462  		t.Fatalf("Deregister revoked %d tokens; want 1", l)
  1463  	}
  1464  }
  1465  
  1466  func TestClientEndpoint_CreateNodeEvals(t *testing.T) {
  1467  	t.Parallel()
  1468  	s1 := testServer(t, nil)
  1469  	defer s1.Shutdown()
  1470  	testutil.WaitForLeader(t, s1.RPC)
  1471  
  1472  	// Inject fake evaluations
  1473  	alloc := mock.Alloc()
  1474  	state := s1.fsm.State()
  1475  	state.UpsertJobSummary(1, mock.JobSummary(alloc.JobID))
  1476  	if err := state.UpsertAllocs(2, []*structs.Allocation{alloc}); err != nil {
  1477  		t.Fatalf("err: %v", err)
  1478  	}
  1479  
  1480  	// Inject a fake system job.
  1481  	job := mock.SystemJob()
  1482  	if err := state.UpsertJob(3, job); err != nil {
  1483  		t.Fatalf("err: %v", err)
  1484  	}
  1485  
  1486  	// Create some evaluations
  1487  	ids, index, err := s1.endpoints.Node.createNodeEvals(alloc.NodeID, 1)
  1488  	if err != nil {
  1489  		t.Fatalf("err: %v", err)
  1490  	}
  1491  	if index == 0 {
  1492  		t.Fatalf("bad: %d", index)
  1493  	}
  1494  	if len(ids) != 2 {
  1495  		t.Fatalf("bad: %s", ids)
  1496  	}
  1497  
  1498  	// Lookup the evaluations
  1499  	ws := memdb.NewWatchSet()
  1500  	evalByType := make(map[string]*structs.Evaluation, 2)
  1501  	for _, id := range ids {
  1502  		eval, err := state.EvalByID(ws, id)
  1503  		if err != nil {
  1504  			t.Fatalf("err: %v", err)
  1505  		}
  1506  		if eval == nil {
  1507  			t.Fatalf("expected eval")
  1508  		}
  1509  
  1510  		if old, ok := evalByType[eval.Type]; ok {
  1511  			t.Fatalf("multiple evals of the same type: %v and %v", old, eval)
  1512  		}
  1513  
  1514  		evalByType[eval.Type] = eval
  1515  	}
  1516  
  1517  	if len(evalByType) != 2 {
  1518  		t.Fatalf("Expected a service and system job; got %#v", evalByType)
  1519  	}
  1520  
  1521  	// Ensure the evals are correct.
  1522  	for schedType, eval := range evalByType {
  1523  		expPriority := alloc.Job.Priority
  1524  		expJobID := alloc.JobID
  1525  		if schedType == "system" {
  1526  			expPriority = job.Priority
  1527  			expJobID = job.ID
  1528  		}
  1529  
  1530  		if eval.CreateIndex != index {
  1531  			t.Fatalf("CreateIndex mis-match on type %v: %#v", schedType, eval)
  1532  		}
  1533  		if eval.TriggeredBy != structs.EvalTriggerNodeUpdate {
  1534  			t.Fatalf("TriggeredBy incorrect on type %v: %#v", schedType, eval)
  1535  		}
  1536  		if eval.NodeID != alloc.NodeID {
  1537  			t.Fatalf("NodeID incorrect on type %v: %#v", schedType, eval)
  1538  		}
  1539  		if eval.NodeModifyIndex != 1 {
  1540  			t.Fatalf("NodeModifyIndex incorrect on type %v: %#v", schedType, eval)
  1541  		}
  1542  		if eval.Status != structs.EvalStatusPending {
  1543  			t.Fatalf("Status incorrect on type %v: %#v", schedType, eval)
  1544  		}
  1545  		if eval.Priority != expPriority {
  1546  			t.Fatalf("Priority incorrect on type %v: %#v", schedType, eval)
  1547  		}
  1548  		if eval.JobID != expJobID {
  1549  			t.Fatalf("JobID incorrect on type %v: %#v", schedType, eval)
  1550  		}
  1551  	}
  1552  }
  1553  
  1554  func TestClientEndpoint_Evaluate(t *testing.T) {
  1555  	t.Parallel()
  1556  	s1 := testServer(t, func(c *Config) {
  1557  		c.NumSchedulers = 0 // Prevent automatic dequeue
  1558  	})
  1559  	defer s1.Shutdown()
  1560  	codec := rpcClient(t, s1)
  1561  	testutil.WaitForLeader(t, s1.RPC)
  1562  
  1563  	// Inject fake evaluations
  1564  	alloc := mock.Alloc()
  1565  	node := mock.Node()
  1566  	node.ID = alloc.NodeID
  1567  	state := s1.fsm.State()
  1568  	err := state.UpsertNode(1, node)
  1569  	if err != nil {
  1570  		t.Fatalf("err: %v", err)
  1571  	}
  1572  	state.UpsertJobSummary(2, mock.JobSummary(alloc.JobID))
  1573  	err = state.UpsertAllocs(3, []*structs.Allocation{alloc})
  1574  	if err != nil {
  1575  		t.Fatalf("err: %v", err)
  1576  	}
  1577  
  1578  	// Re-evaluate
  1579  	req := &structs.NodeEvaluateRequest{
  1580  		NodeID:       alloc.NodeID,
  1581  		WriteRequest: structs.WriteRequest{Region: "global"},
  1582  	}
  1583  
  1584  	// Fetch the response
  1585  	var resp structs.NodeUpdateResponse
  1586  	if err := msgpackrpc.CallWithCodec(codec, "Node.Evaluate", req, &resp); err != nil {
  1587  		t.Fatalf("err: %v", err)
  1588  	}
  1589  	if resp.Index == 0 {
  1590  		t.Fatalf("bad index: %d", resp.Index)
  1591  	}
  1592  
  1593  	// Create some evaluations
  1594  	ids := resp.EvalIDs
  1595  	if len(ids) != 1 {
  1596  		t.Fatalf("bad: %s", ids)
  1597  	}
  1598  
  1599  	// Lookup the evaluation
  1600  	ws := memdb.NewWatchSet()
  1601  	eval, err := state.EvalByID(ws, ids[0])
  1602  	if err != nil {
  1603  		t.Fatalf("err: %v", err)
  1604  	}
  1605  	if eval == nil {
  1606  		t.Fatalf("expected eval")
  1607  	}
  1608  	if eval.CreateIndex != resp.Index {
  1609  		t.Fatalf("index mis-match")
  1610  	}
  1611  
  1612  	if eval.Priority != alloc.Job.Priority {
  1613  		t.Fatalf("bad: %#v", eval)
  1614  	}
  1615  	if eval.Type != alloc.Job.Type {
  1616  		t.Fatalf("bad: %#v", eval)
  1617  	}
  1618  	if eval.TriggeredBy != structs.EvalTriggerNodeUpdate {
  1619  		t.Fatalf("bad: %#v", eval)
  1620  	}
  1621  	if eval.JobID != alloc.JobID {
  1622  		t.Fatalf("bad: %#v", eval)
  1623  	}
  1624  	if eval.NodeID != alloc.NodeID {
  1625  		t.Fatalf("bad: %#v", eval)
  1626  	}
  1627  	if eval.NodeModifyIndex != 1 {
  1628  		t.Fatalf("bad: %#v", eval)
  1629  	}
  1630  	if eval.Status != structs.EvalStatusPending {
  1631  		t.Fatalf("bad: %#v", eval)
  1632  	}
  1633  }
  1634  
  1635  func TestClientEndpoint_ListNodes(t *testing.T) {
  1636  	t.Parallel()
  1637  	s1 := testServer(t, nil)
  1638  	defer s1.Shutdown()
  1639  	codec := rpcClient(t, s1)
  1640  	testutil.WaitForLeader(t, s1.RPC)
  1641  
  1642  	// Create the register request
  1643  	node := mock.Node()
  1644  	reg := &structs.NodeRegisterRequest{
  1645  		Node:         node,
  1646  		WriteRequest: structs.WriteRequest{Region: "global"},
  1647  	}
  1648  
  1649  	// Fetch the response
  1650  	var resp structs.GenericResponse
  1651  	if err := msgpackrpc.CallWithCodec(codec, "Node.Register", reg, &resp); err != nil {
  1652  		t.Fatalf("err: %v", err)
  1653  	}
  1654  	node.CreateIndex = resp.Index
  1655  	node.ModifyIndex = resp.Index
  1656  
  1657  	// Lookup the node
  1658  	get := &structs.NodeListRequest{
  1659  		QueryOptions: structs.QueryOptions{Region: "global"},
  1660  	}
  1661  	var resp2 structs.NodeListResponse
  1662  	if err := msgpackrpc.CallWithCodec(codec, "Node.List", get, &resp2); err != nil {
  1663  		t.Fatalf("err: %v", err)
  1664  	}
  1665  	if resp2.Index != resp.Index {
  1666  		t.Fatalf("Bad index: %d %d", resp2.Index, resp.Index)
  1667  	}
  1668  
  1669  	if len(resp2.Nodes) != 1 {
  1670  		t.Fatalf("bad: %#v", resp2.Nodes)
  1671  	}
  1672  	if resp2.Nodes[0].ID != node.ID {
  1673  		t.Fatalf("bad: %#v", resp2.Nodes[0])
  1674  	}
  1675  
  1676  	// Lookup the node with prefix
  1677  	get = &structs.NodeListRequest{
  1678  		QueryOptions: structs.QueryOptions{Region: "global", Prefix: node.ID[:4]},
  1679  	}
  1680  	var resp3 structs.NodeListResponse
  1681  	if err := msgpackrpc.CallWithCodec(codec, "Node.List", get, &resp3); err != nil {
  1682  		t.Fatalf("err: %v", err)
  1683  	}
  1684  	if resp3.Index != resp.Index {
  1685  		t.Fatalf("Bad index: %d %d", resp3.Index, resp2.Index)
  1686  	}
  1687  
  1688  	if len(resp3.Nodes) != 1 {
  1689  		t.Fatalf("bad: %#v", resp3.Nodes)
  1690  	}
  1691  	if resp3.Nodes[0].ID != node.ID {
  1692  		t.Fatalf("bad: %#v", resp3.Nodes[0])
  1693  	}
  1694  }
  1695  
  1696  func TestClientEndpoint_ListNodes_Blocking(t *testing.T) {
  1697  	t.Parallel()
  1698  	s1 := testServer(t, nil)
  1699  	defer s1.Shutdown()
  1700  	state := s1.fsm.State()
  1701  	codec := rpcClient(t, s1)
  1702  	testutil.WaitForLeader(t, s1.RPC)
  1703  
  1704  	// Create the node
  1705  	node := mock.Node()
  1706  
  1707  	// Node upsert triggers watches
  1708  	time.AfterFunc(100*time.Millisecond, func() {
  1709  		if err := state.UpsertNode(2, node); err != nil {
  1710  			t.Fatalf("err: %v", err)
  1711  		}
  1712  	})
  1713  
  1714  	req := &structs.NodeListRequest{
  1715  		QueryOptions: structs.QueryOptions{
  1716  			Region:        "global",
  1717  			MinQueryIndex: 1,
  1718  		},
  1719  	}
  1720  	start := time.Now()
  1721  	var resp structs.NodeListResponse
  1722  	if err := msgpackrpc.CallWithCodec(codec, "Node.List", req, &resp); err != nil {
  1723  		t.Fatalf("err: %v", err)
  1724  	}
  1725  
  1726  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
  1727  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp)
  1728  	}
  1729  	if resp.Index != 2 {
  1730  		t.Fatalf("Bad index: %d %d", resp.Index, 2)
  1731  	}
  1732  	if len(resp.Nodes) != 1 || resp.Nodes[0].ID != node.ID {
  1733  		t.Fatalf("bad: %#v", resp.Nodes)
  1734  	}
  1735  
  1736  	// Node drain updates trigger watches.
  1737  	time.AfterFunc(100*time.Millisecond, func() {
  1738  		if err := state.UpdateNodeDrain(3, node.ID, true); err != nil {
  1739  			t.Fatalf("err: %v", err)
  1740  		}
  1741  	})
  1742  
  1743  	req.MinQueryIndex = 2
  1744  	var resp2 structs.NodeListResponse
  1745  	start = time.Now()
  1746  	if err := msgpackrpc.CallWithCodec(codec, "Node.List", req, &resp2); err != nil {
  1747  		t.Fatalf("err: %v", err)
  1748  	}
  1749  
  1750  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
  1751  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp2)
  1752  	}
  1753  	if resp2.Index != 3 {
  1754  		t.Fatalf("Bad index: %d %d", resp2.Index, 3)
  1755  	}
  1756  	if len(resp2.Nodes) != 1 || !resp2.Nodes[0].Drain {
  1757  		t.Fatalf("bad: %#v", resp2.Nodes)
  1758  	}
  1759  
  1760  	// Node status update triggers watches
  1761  	time.AfterFunc(100*time.Millisecond, func() {
  1762  		if err := state.UpdateNodeStatus(4, node.ID, structs.NodeStatusDown); err != nil {
  1763  			t.Fatalf("err: %v", err)
  1764  		}
  1765  	})
  1766  
  1767  	req.MinQueryIndex = 3
  1768  	var resp3 structs.NodeListResponse
  1769  	start = time.Now()
  1770  	if err := msgpackrpc.CallWithCodec(codec, "Node.List", req, &resp3); err != nil {
  1771  		t.Fatalf("err: %v", err)
  1772  	}
  1773  
  1774  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
  1775  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp3)
  1776  	}
  1777  	if resp3.Index != 4 {
  1778  		t.Fatalf("Bad index: %d %d", resp3.Index, 4)
  1779  	}
  1780  	if len(resp3.Nodes) != 1 || resp3.Nodes[0].Status != structs.NodeStatusDown {
  1781  		t.Fatalf("bad: %#v", resp3.Nodes)
  1782  	}
  1783  
  1784  	// Node delete triggers watches.
  1785  	time.AfterFunc(100*time.Millisecond, func() {
  1786  		if err := state.DeleteNode(5, node.ID); err != nil {
  1787  			t.Fatalf("err: %v", err)
  1788  		}
  1789  	})
  1790  
  1791  	req.MinQueryIndex = 4
  1792  	var resp4 structs.NodeListResponse
  1793  	start = time.Now()
  1794  	if err := msgpackrpc.CallWithCodec(codec, "Node.List", req, &resp4); err != nil {
  1795  		t.Fatalf("err: %v", err)
  1796  	}
  1797  
  1798  	if elapsed := time.Since(start); elapsed < 100*time.Millisecond {
  1799  		t.Fatalf("should block (returned in %s) %#v", elapsed, resp4)
  1800  	}
  1801  	if resp4.Index != 5 {
  1802  		t.Fatalf("Bad index: %d %d", resp4.Index, 5)
  1803  	}
  1804  	if len(resp4.Nodes) != 0 {
  1805  		t.Fatalf("bad: %#v", resp4.Nodes)
  1806  	}
  1807  }
  1808  
  1809  func TestBatchFuture(t *testing.T) {
  1810  	t.Parallel()
  1811  	bf := NewBatchFuture()
  1812  
  1813  	// Async respond to the future
  1814  	expect := fmt.Errorf("testing")
  1815  	go func() {
  1816  		time.Sleep(10 * time.Millisecond)
  1817  		bf.Respond(1000, expect)
  1818  	}()
  1819  
  1820  	// Block for the result
  1821  	start := time.Now()
  1822  	err := bf.Wait()
  1823  	diff := time.Since(start)
  1824  	if diff < 5*time.Millisecond {
  1825  		t.Fatalf("too fast")
  1826  	}
  1827  
  1828  	// Check the results
  1829  	if err != expect {
  1830  		t.Fatalf("bad: %s", err)
  1831  	}
  1832  	if bf.Index() != 1000 {
  1833  		t.Fatalf("bad: %d", bf.Index())
  1834  	}
  1835  }
  1836  
  1837  func TestClientEndpoint_DeriveVaultToken_Bad(t *testing.T) {
  1838  	t.Parallel()
  1839  	s1 := testServer(t, nil)
  1840  	defer s1.Shutdown()
  1841  	state := s1.fsm.State()
  1842  	codec := rpcClient(t, s1)
  1843  	testutil.WaitForLeader(t, s1.RPC)
  1844  
  1845  	// Create the node
  1846  	node := mock.Node()
  1847  	if err := state.UpsertNode(2, node); err != nil {
  1848  		t.Fatalf("err: %v", err)
  1849  	}
  1850  
  1851  	// Create an alloc
  1852  	alloc := mock.Alloc()
  1853  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1854  	tasks := []string{task.Name}
  1855  	if err := state.UpsertAllocs(3, []*structs.Allocation{alloc}); err != nil {
  1856  		t.Fatalf("err: %v", err)
  1857  	}
  1858  
  1859  	req := &structs.DeriveVaultTokenRequest{
  1860  		NodeID:   node.ID,
  1861  		SecretID: structs.GenerateUUID(),
  1862  		AllocID:  alloc.ID,
  1863  		Tasks:    tasks,
  1864  		QueryOptions: structs.QueryOptions{
  1865  			Region: "global",
  1866  		},
  1867  	}
  1868  
  1869  	var resp structs.DeriveVaultTokenResponse
  1870  	if err := msgpackrpc.CallWithCodec(codec, "Node.DeriveVaultToken", req, &resp); err != nil {
  1871  		t.Fatalf("bad: %v", err)
  1872  	}
  1873  
  1874  	if resp.Error == nil || !strings.Contains(resp.Error.Error(), "SecretID mismatch") {
  1875  		t.Fatalf("Expected SecretID mismatch: %v", resp.Error)
  1876  	}
  1877  
  1878  	// Put the correct SecretID
  1879  	req.SecretID = node.SecretID
  1880  
  1881  	// Now we should get an error about the allocation not running on the node
  1882  	if err := msgpackrpc.CallWithCodec(codec, "Node.DeriveVaultToken", req, &resp); err != nil {
  1883  		t.Fatalf("bad: %v", err)
  1884  	}
  1885  	if resp.Error == nil || !strings.Contains(resp.Error.Error(), "not running on Node") {
  1886  		t.Fatalf("Expected not running on node error: %v", resp.Error)
  1887  	}
  1888  
  1889  	// Update to be running on the node
  1890  	alloc.NodeID = node.ID
  1891  	if err := state.UpsertAllocs(4, []*structs.Allocation{alloc}); err != nil {
  1892  		t.Fatalf("err: %v", err)
  1893  	}
  1894  
  1895  	// Now we should get an error about the job not needing any Vault secrets
  1896  	if err := msgpackrpc.CallWithCodec(codec, "Node.DeriveVaultToken", req, &resp); err != nil {
  1897  		t.Fatalf("bad: %v", err)
  1898  	}
  1899  	if resp.Error == nil || !strings.Contains(resp.Error.Error(), "does not require") {
  1900  		t.Fatalf("Expected no policies error: %v", resp.Error)
  1901  	}
  1902  
  1903  	// Update to be terminal
  1904  	alloc.DesiredStatus = structs.AllocDesiredStatusStop
  1905  	if err := state.UpsertAllocs(5, []*structs.Allocation{alloc}); err != nil {
  1906  		t.Fatalf("err: %v", err)
  1907  	}
  1908  
  1909  	// Now we should get an error about the job not needing any Vault secrets
  1910  	if err := msgpackrpc.CallWithCodec(codec, "Node.DeriveVaultToken", req, &resp); err != nil {
  1911  		t.Fatalf("bad: %v", err)
  1912  	}
  1913  	if resp.Error == nil || !strings.Contains(resp.Error.Error(), "terminal") {
  1914  		t.Fatalf("Expected terminal allocation error: %v", resp.Error)
  1915  	}
  1916  }
  1917  
  1918  func TestClientEndpoint_DeriveVaultToken(t *testing.T) {
  1919  	t.Parallel()
  1920  	s1 := testServer(t, nil)
  1921  	defer s1.Shutdown()
  1922  	state := s1.fsm.State()
  1923  	codec := rpcClient(t, s1)
  1924  	testutil.WaitForLeader(t, s1.RPC)
  1925  
  1926  	// Enable vault and allow authenticated
  1927  	tr := true
  1928  	s1.config.VaultConfig.Enabled = &tr
  1929  	s1.config.VaultConfig.AllowUnauthenticated = &tr
  1930  
  1931  	// Replace the Vault Client on the server
  1932  	tvc := &TestVaultClient{}
  1933  	s1.vault = tvc
  1934  
  1935  	// Create the node
  1936  	node := mock.Node()
  1937  	if err := state.UpsertNode(2, node); err != nil {
  1938  		t.Fatalf("err: %v", err)
  1939  	}
  1940  
  1941  	// Create an alloc an allocation that has vault policies required
  1942  	alloc := mock.Alloc()
  1943  	alloc.NodeID = node.ID
  1944  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1945  	tasks := []string{task.Name}
  1946  	task.Vault = &structs.Vault{Policies: []string{"a", "b"}}
  1947  	if err := state.UpsertAllocs(3, []*structs.Allocation{alloc}); err != nil {
  1948  		t.Fatalf("err: %v", err)
  1949  	}
  1950  
  1951  	// Return a secret for the task
  1952  	token := structs.GenerateUUID()
  1953  	accessor := structs.GenerateUUID()
  1954  	ttl := 10
  1955  	secret := &vapi.Secret{
  1956  		WrapInfo: &vapi.SecretWrapInfo{
  1957  			Token:           token,
  1958  			WrappedAccessor: accessor,
  1959  			TTL:             ttl,
  1960  		},
  1961  	}
  1962  	tvc.SetCreateTokenSecret(alloc.ID, task.Name, secret)
  1963  
  1964  	req := &structs.DeriveVaultTokenRequest{
  1965  		NodeID:   node.ID,
  1966  		SecretID: node.SecretID,
  1967  		AllocID:  alloc.ID,
  1968  		Tasks:    tasks,
  1969  		QueryOptions: structs.QueryOptions{
  1970  			Region: "global",
  1971  		},
  1972  	}
  1973  
  1974  	var resp structs.DeriveVaultTokenResponse
  1975  	if err := msgpackrpc.CallWithCodec(codec, "Node.DeriveVaultToken", req, &resp); err != nil {
  1976  		t.Fatalf("bad: %v", err)
  1977  	}
  1978  	if resp.Error != nil {
  1979  		t.Fatalf("bad: %v", resp.Error)
  1980  	}
  1981  
  1982  	// Check the state store and ensure that we created a VaultAccessor
  1983  	ws := memdb.NewWatchSet()
  1984  	va, err := state.VaultAccessor(ws, accessor)
  1985  	if err != nil {
  1986  		t.Fatalf("bad: %v", err)
  1987  	}
  1988  	if va == nil {
  1989  		t.Fatalf("bad: %v", va)
  1990  	}
  1991  
  1992  	if va.CreateIndex == 0 {
  1993  		t.Fatalf("bad: %v", va)
  1994  	}
  1995  
  1996  	va.CreateIndex = 0
  1997  	expected := &structs.VaultAccessor{
  1998  		AllocID:     alloc.ID,
  1999  		Task:        task.Name,
  2000  		NodeID:      alloc.NodeID,
  2001  		Accessor:    accessor,
  2002  		CreationTTL: ttl,
  2003  	}
  2004  
  2005  	if !reflect.DeepEqual(expected, va) {
  2006  		t.Fatalf("Got %#v; want %#v", va, expected)
  2007  	}
  2008  }
  2009  
  2010  func TestClientEndpoint_DeriveVaultToken_VaultError(t *testing.T) {
  2011  	t.Parallel()
  2012  	s1 := testServer(t, nil)
  2013  	defer s1.Shutdown()
  2014  	state := s1.fsm.State()
  2015  	codec := rpcClient(t, s1)
  2016  	testutil.WaitForLeader(t, s1.RPC)
  2017  
  2018  	// Enable vault and allow authenticated
  2019  	tr := true
  2020  	s1.config.VaultConfig.Enabled = &tr
  2021  	s1.config.VaultConfig.AllowUnauthenticated = &tr
  2022  
  2023  	// Replace the Vault Client on the server
  2024  	tvc := &TestVaultClient{}
  2025  	s1.vault = tvc
  2026  
  2027  	// Create the node
  2028  	node := mock.Node()
  2029  	if err := state.UpsertNode(2, node); err != nil {
  2030  		t.Fatalf("err: %v", err)
  2031  	}
  2032  
  2033  	// Create an alloc an allocation that has vault policies required
  2034  	alloc := mock.Alloc()
  2035  	alloc.NodeID = node.ID
  2036  	task := alloc.Job.TaskGroups[0].Tasks[0]
  2037  	tasks := []string{task.Name}
  2038  	task.Vault = &structs.Vault{Policies: []string{"a", "b"}}
  2039  	if err := state.UpsertAllocs(3, []*structs.Allocation{alloc}); err != nil {
  2040  		t.Fatalf("err: %v", err)
  2041  	}
  2042  
  2043  	// Return an error when creating the token
  2044  	tvc.SetCreateTokenError(alloc.ID, task.Name,
  2045  		structs.NewRecoverableError(fmt.Errorf("recover"), true))
  2046  
  2047  	req := &structs.DeriveVaultTokenRequest{
  2048  		NodeID:   node.ID,
  2049  		SecretID: node.SecretID,
  2050  		AllocID:  alloc.ID,
  2051  		Tasks:    tasks,
  2052  		QueryOptions: structs.QueryOptions{
  2053  			Region: "global",
  2054  		},
  2055  	}
  2056  
  2057  	var resp structs.DeriveVaultTokenResponse
  2058  	err := msgpackrpc.CallWithCodec(codec, "Node.DeriveVaultToken", req, &resp)
  2059  	if err != nil {
  2060  		t.Fatalf("bad: %v", err)
  2061  	}
  2062  	if resp.Error == nil || !resp.Error.IsRecoverable() {
  2063  		t.Fatalf("bad: %+v", resp.Error)
  2064  	}
  2065  }