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