github.com/clly/consul@v1.4.5/agent/consul/state/catalog_test.go (about)

     1  package state
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"sort"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/hashicorp/consul/agent/structs"
    11  	"github.com/hashicorp/consul/api"
    12  	"github.com/hashicorp/consul/lib"
    13  	"github.com/hashicorp/consul/types"
    14  	"github.com/hashicorp/go-memdb"
    15  	uuid "github.com/hashicorp/go-uuid"
    16  	"github.com/pascaldekloe/goe/verify"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func makeRandomNodeID(t *testing.T) types.NodeID {
    22  	id, err := uuid.GenerateUUID()
    23  	if err != nil {
    24  		t.Fatalf("err: %v", err)
    25  	}
    26  	return types.NodeID(id)
    27  }
    28  
    29  func TestStateStore_GetNodeID(t *testing.T) {
    30  	s := testStateStore(t)
    31  	_, out, err := s.GetNodeID(types.NodeID("wrongId"))
    32  	if err == nil || out != nil || !strings.Contains(err.Error(), "node lookup by ID failed, wrong UUID") {
    33  		t.Fatalf("want an error, nil value, err:=%q ; out:=%q", err.Error(), out)
    34  	}
    35  	_, out, err = s.GetNodeID(types.NodeID("0123456789abcdefghijklmnopqrstuvwxyz"))
    36  	if err == nil || out != nil || !strings.Contains(err.Error(), "node lookup by ID failed, wrong UUID") {
    37  		t.Fatalf("want an error, nil value, err:=%q ; out:=%q", err, out)
    38  	}
    39  
    40  	_, out, err = s.GetNodeID(types.NodeID("00a916bc-a357-4a19-b886-59419fcee50Z"))
    41  	if err == nil || out != nil || !strings.Contains(err.Error(), "node lookup by ID failed, wrong UUID") {
    42  		t.Fatalf("want an error, nil value, err:=%q ; out:=%q", err, out)
    43  	}
    44  
    45  	_, out, err = s.GetNodeID(types.NodeID("00a916bc-a357-4a19-b886-59419fcee506"))
    46  	if err != nil || out != nil {
    47  		t.Fatalf("do not want any error nor returned value, err:=%q ; out:=%q", err, out)
    48  	}
    49  
    50  	nodeID := types.NodeID("00a916bc-a357-4a19-b886-59419fceeaaa")
    51  	req := &structs.RegisterRequest{
    52  		ID:      nodeID,
    53  		Node:    "node1",
    54  		Address: "1.2.3.4",
    55  	}
    56  	if err := s.EnsureRegistration(1, req); err != nil {
    57  		t.Fatalf("err: %s", err)
    58  	}
    59  
    60  	_, out, err = s.GetNodeID(nodeID)
    61  	if err != nil {
    62  		t.Fatalf("got err %s want nil", err)
    63  	}
    64  	if out == nil || out.ID != nodeID {
    65  		t.Fatalf("out should not be nil and contain nodeId, but was:=%#v", out)
    66  	}
    67  	// Case insensitive lookup should work as well
    68  	_, out, err = s.GetNodeID(types.NodeID("00a916bC-a357-4a19-b886-59419fceeAAA"))
    69  	if err != nil {
    70  		t.Fatalf("got err %s want nil", err)
    71  	}
    72  	if out == nil || out.ID != nodeID {
    73  		t.Fatalf("out should not be nil and contain nodeId, but was:=%#v", out)
    74  	}
    75  }
    76  
    77  func TestStateStore_ensureNoNodeWithSimilarNameTxn(t *testing.T) {
    78  	t.Parallel()
    79  	s := testStateStore(t)
    80  	nodeID := makeRandomNodeID(t)
    81  	req := &structs.RegisterRequest{
    82  		ID:              nodeID,
    83  		Node:            "node1",
    84  		Address:         "1.2.3.4",
    85  		TaggedAddresses: map[string]string{"hello": "world"},
    86  		NodeMeta:        map[string]string{"somekey": "somevalue"},
    87  	}
    88  	if err := s.EnsureRegistration(1, req); err != nil {
    89  		t.Fatalf("err: %s", err)
    90  	}
    91  	req = &structs.RegisterRequest{
    92  		ID:      types.NodeID(""),
    93  		Node:    "node2",
    94  		Address: "10.0.0.1",
    95  	}
    96  	if err := s.EnsureRegistration(2, req); err != nil {
    97  		t.Fatalf("err: %s", err)
    98  	}
    99  	tx := s.db.Txn(true)
   100  	defer tx.Abort()
   101  	node := &structs.Node{
   102  		ID:      makeRandomNodeID(t),
   103  		Node:    "NOdE1", // Name is similar but case is different
   104  		Address: "2.3.4.5",
   105  	}
   106  	// Lets conflict with node1 (has an ID)
   107  	if err := s.ensureNoNodeWithSimilarNameTxn(tx, node, false); err == nil {
   108  		t.Fatalf("Should return an error since another name with similar name exists")
   109  	}
   110  	if err := s.ensureNoNodeWithSimilarNameTxn(tx, node, true); err == nil {
   111  		t.Fatalf("Should return an error since another name with similar name exists")
   112  	}
   113  	// Lets conflict with node without ID
   114  	node.Node = "NoDe2"
   115  	if err := s.ensureNoNodeWithSimilarNameTxn(tx, node, false); err == nil {
   116  		t.Fatalf("Should return an error since another name with similar name exists")
   117  	}
   118  	if err := s.ensureNoNodeWithSimilarNameTxn(tx, node, true); err != nil {
   119  		t.Fatalf("Should not clash with another similar node name without ID, err:=%q", err)
   120  	}
   121  
   122  }
   123  
   124  func TestStateStore_EnsureRegistration(t *testing.T) {
   125  	t.Parallel()
   126  	s := testStateStore(t)
   127  
   128  	// Start with just a node.
   129  	nodeID := makeRandomNodeID(t)
   130  	req := &structs.RegisterRequest{
   131  		ID:              nodeID,
   132  		Node:            "node1",
   133  		Address:         "1.2.3.4",
   134  		TaggedAddresses: map[string]string{"hello": "world"},
   135  		NodeMeta:        map[string]string{"somekey": "somevalue"},
   136  	}
   137  	if err := s.EnsureRegistration(1, req); err != nil {
   138  		t.Fatalf("err: %s", err)
   139  	}
   140  
   141  	// Retrieve the node and verify its contents.
   142  	verifyNode := func() {
   143  		node := &structs.Node{
   144  			ID:              nodeID,
   145  			Node:            "node1",
   146  			Address:         "1.2.3.4",
   147  			TaggedAddresses: map[string]string{"hello": "world"},
   148  			Meta:            map[string]string{"somekey": "somevalue"},
   149  			RaftIndex:       structs.RaftIndex{CreateIndex: 1, ModifyIndex: 1},
   150  		}
   151  
   152  		_, out, err := s.GetNode("node1")
   153  		if err != nil {
   154  			t.Fatalf("got err %s want nil", err)
   155  		}
   156  		if got, want := out, node; !verify.Values(t, "GetNode", got, want) {
   157  			t.FailNow()
   158  		}
   159  
   160  		_, out2, err := s.GetNodeID(nodeID)
   161  		if err != nil {
   162  			t.Fatalf("got err %s want nil", err)
   163  		}
   164  		if out2 == nil {
   165  			t.Fatalf("out2 should not be nil")
   166  		}
   167  		if got, want := out, out2; !verify.Values(t, "GetNodeID", got, want) {
   168  			t.FailNow()
   169  		}
   170  	}
   171  	verifyNode()
   172  
   173  	// Add in a invalid service definition with too long Key value for Meta
   174  	req.Service = &structs.NodeService{
   175  		ID:      "redis1",
   176  		Service: "redis",
   177  		Address: "1.1.1.1",
   178  		Port:    8080,
   179  		Meta:    map[string]string{strings.Repeat("a", 129): "somevalue"},
   180  		Tags:    []string{"master"},
   181  	}
   182  	if err := s.EnsureRegistration(9, req); err == nil {
   183  		t.Fatalf("Service should not have been registered since Meta is invalid")
   184  	}
   185  
   186  	// Add in a service definition.
   187  	req.Service = &structs.NodeService{
   188  		ID:      "redis1",
   189  		Service: "redis",
   190  		Address: "1.1.1.1",
   191  		Port:    8080,
   192  		Tags:    []string{"master"},
   193  		Weights: &structs.Weights{Passing: 1, Warning: 1},
   194  	}
   195  	if err := s.EnsureRegistration(2, req); err != nil {
   196  		t.Fatalf("err: %s", err)
   197  	}
   198  
   199  	// Verify that the service got registered.
   200  	verifyService := func() {
   201  		svcmap := map[string]*structs.NodeService{
   202  			"redis1": &structs.NodeService{
   203  				ID:        "redis1",
   204  				Service:   "redis",
   205  				Address:   "1.1.1.1",
   206  				Port:      8080,
   207  				Tags:      []string{"master"},
   208  				Weights:   &structs.Weights{Passing: 1, Warning: 1},
   209  				RaftIndex: structs.RaftIndex{CreateIndex: 2, ModifyIndex: 2},
   210  			},
   211  		}
   212  
   213  		idx, out, err := s.NodeServices(nil, "node1")
   214  		if gotidx, wantidx := idx, uint64(2); err != nil || gotidx != wantidx {
   215  			t.Fatalf("got err, idx: %s, %d want nil, %d", err, gotidx, wantidx)
   216  		}
   217  		if got, want := out.Services, svcmap; !verify.Values(t, "NodeServices", got, want) {
   218  			t.FailNow()
   219  		}
   220  
   221  		idx, r, err := s.NodeService("node1", "redis1")
   222  		if gotidx, wantidx := idx, uint64(2); err != nil || gotidx != wantidx {
   223  			t.Fatalf("got err, idx: %s, %d want nil, %d", err, gotidx, wantidx)
   224  		}
   225  		if got, want := r, svcmap["redis1"]; !verify.Values(t, "NodeService", got, want) {
   226  			t.FailNow()
   227  		}
   228  	}
   229  	verifyNode()
   230  	verifyService()
   231  
   232  	// Add in a top-level check.
   233  	req.Check = &structs.HealthCheck{
   234  		Node:    "node1",
   235  		CheckID: "check1",
   236  		Name:    "check",
   237  	}
   238  	if err := s.EnsureRegistration(3, req); err != nil {
   239  		t.Fatalf("err: %s", err)
   240  	}
   241  
   242  	// Verify that the check got registered.
   243  	verifyCheck := func() {
   244  		checks := structs.HealthChecks{
   245  			&structs.HealthCheck{
   246  				Node:      "node1",
   247  				CheckID:   "check1",
   248  				Name:      "check",
   249  				Status:    "critical",
   250  				RaftIndex: structs.RaftIndex{CreateIndex: 3, ModifyIndex: 3},
   251  			},
   252  		}
   253  
   254  		idx, out, err := s.NodeChecks(nil, "node1")
   255  		if gotidx, wantidx := idx, uint64(3); err != nil || gotidx != wantidx {
   256  			t.Fatalf("got err, idx: %s, %d want nil, %d", err, gotidx, wantidx)
   257  		}
   258  		if got, want := out, checks; !verify.Values(t, "NodeChecks", got, want) {
   259  			t.FailNow()
   260  		}
   261  
   262  		idx, c, err := s.NodeCheck("node1", "check1")
   263  		if gotidx, wantidx := idx, uint64(3); err != nil || gotidx != wantidx {
   264  			t.Fatalf("got err, idx: %s, %d want nil, %d", err, gotidx, wantidx)
   265  		}
   266  		if got, want := c, checks[0]; !verify.Values(t, "NodeCheck", got, want) {
   267  			t.FailNow()
   268  		}
   269  	}
   270  	verifyNode()
   271  	verifyService()
   272  	verifyCheck()
   273  
   274  	// Add a service check which should populate the ServiceName
   275  	// and ServiceTags fields in the response.
   276  	req.Checks = structs.HealthChecks{
   277  		&structs.HealthCheck{
   278  			Node:      "node1",
   279  			CheckID:   "check2",
   280  			Name:      "check",
   281  			ServiceID: "redis1",
   282  		},
   283  	}
   284  	if err := s.EnsureRegistration(4, req); err != nil {
   285  		t.Fatalf("err: %s", err)
   286  	}
   287  
   288  	// Verify that the additional check got registered.
   289  	verifyNode()
   290  	verifyService()
   291  	verifyChecks := func() {
   292  		checks := structs.HealthChecks{
   293  			&structs.HealthCheck{
   294  				Node:      "node1",
   295  				CheckID:   "check1",
   296  				Name:      "check",
   297  				Status:    "critical",
   298  				RaftIndex: structs.RaftIndex{CreateIndex: 3, ModifyIndex: 3},
   299  			},
   300  			&structs.HealthCheck{
   301  				Node:        "node1",
   302  				CheckID:     "check2",
   303  				Name:        "check",
   304  				Status:      "critical",
   305  				ServiceID:   "redis1",
   306  				ServiceName: "redis",
   307  				ServiceTags: []string{"master"},
   308  				RaftIndex:   structs.RaftIndex{CreateIndex: 4, ModifyIndex: 4},
   309  			},
   310  		}
   311  
   312  		idx, out, err := s.NodeChecks(nil, "node1")
   313  		if gotidx, wantidx := idx, uint64(4); err != nil || gotidx != wantidx {
   314  			t.Fatalf("got err, idx: %s, %d want nil, %d", err, gotidx, wantidx)
   315  		}
   316  		if got, want := out, checks; !verify.Values(t, "NodeChecks", got, want) {
   317  			t.FailNow()
   318  		}
   319  	}
   320  	verifyChecks()
   321  
   322  	// Try to register a check for some other node (top-level check).
   323  	req.Check = &structs.HealthCheck{
   324  		Node:    "nope",
   325  		CheckID: "check1",
   326  		Name:    "check",
   327  	}
   328  	err := s.EnsureRegistration(5, req)
   329  	if err == nil || !strings.Contains(err.Error(), "does not match node") {
   330  		t.Fatalf("err: %s", err)
   331  	}
   332  	verifyNode()
   333  	verifyService()
   334  	verifyChecks()
   335  
   336  	// Try to register a check for some other node (checks array).
   337  	req.Check = nil
   338  	req.Checks = structs.HealthChecks{
   339  		&structs.HealthCheck{
   340  			Node:    "nope",
   341  			CheckID: "check2",
   342  			Name:    "check",
   343  		},
   344  	}
   345  	err = s.EnsureRegistration(6, req)
   346  	if err == nil || !strings.Contains(err.Error(), "does not match node") {
   347  		t.Fatalf("err: %s", err)
   348  	}
   349  	verifyNode()
   350  	verifyService()
   351  	verifyChecks()
   352  }
   353  
   354  func TestStateStore_EnsureRegistration_Restore(t *testing.T) {
   355  	s := testStateStore(t)
   356  
   357  	// Start with just a node.
   358  	req := &structs.RegisterRequest{
   359  		ID:      makeRandomNodeID(t),
   360  		Node:    "node1",
   361  		Address: "1.2.3.4",
   362  	}
   363  	nodeID := string(req.ID)
   364  	nodeName := string(req.Node)
   365  	restore := s.Restore()
   366  	if err := restore.Registration(1, req); err != nil {
   367  		t.Fatalf("err: %s", err)
   368  	}
   369  	restore.Commit()
   370  
   371  	// Retrieve the node and verify its contents.
   372  	verifyNode := func(nodeLookup string) {
   373  		_, out, err := s.GetNode(nodeLookup)
   374  		if err != nil {
   375  			t.Fatalf("err: %s", err)
   376  		}
   377  		if out == nil {
   378  			_, out, err = s.GetNodeID(types.NodeID(nodeLookup))
   379  			if err != nil {
   380  				t.Fatalf("err: %s", err)
   381  			}
   382  		}
   383  
   384  		if out == nil || out.Address != "1.2.3.4" ||
   385  			!(out.Node == nodeLookup || string(out.ID) == nodeLookup) ||
   386  			out.CreateIndex != 1 || out.ModifyIndex != 1 {
   387  			t.Fatalf("bad node returned: %#v", out)
   388  		}
   389  	}
   390  	verifyNode(nodeID)
   391  	verifyNode(nodeName)
   392  
   393  	// Add in a service definition.
   394  	req.Service = &structs.NodeService{
   395  		ID:      "redis1",
   396  		Service: "redis",
   397  		Address: "1.1.1.1",
   398  		Port:    8080,
   399  		Weights: &structs.Weights{Passing: 1, Warning: 1},
   400  	}
   401  	restore = s.Restore()
   402  	if err := restore.Registration(2, req); err != nil {
   403  		t.Fatalf("err: %s", err)
   404  	}
   405  	restore.Commit()
   406  
   407  	// Verify that the service got registered.
   408  	verifyService := func(nodeLookup string) {
   409  		idx, out, err := s.NodeServices(nil, nodeLookup)
   410  		if err != nil {
   411  			t.Fatalf("err: %s", err)
   412  		}
   413  		if idx != 2 {
   414  			t.Fatalf("bad index: %d", idx)
   415  		}
   416  		if len(out.Services) != 1 {
   417  			t.Fatalf("bad: %#v", out.Services)
   418  		}
   419  		s := out.Services["redis1"]
   420  		if s.ID != "redis1" || s.Service != "redis" ||
   421  			s.Address != "1.1.1.1" || s.Port != 8080 ||
   422  			s.CreateIndex != 2 || s.ModifyIndex != 2 {
   423  			t.Fatalf("bad service returned: %#v", s)
   424  		}
   425  	}
   426  
   427  	// Add in a top-level check.
   428  	req.Check = &structs.HealthCheck{
   429  		Node:    nodeName,
   430  		CheckID: "check1",
   431  		Name:    "check",
   432  	}
   433  	restore = s.Restore()
   434  	if err := restore.Registration(3, req); err != nil {
   435  		t.Fatalf("err: %s", err)
   436  	}
   437  	restore.Commit()
   438  
   439  	// Verify that the check got registered.
   440  	verifyCheck := func() {
   441  		idx, out, err := s.NodeChecks(nil, nodeName)
   442  		if err != nil {
   443  			t.Fatalf("err: %s", err)
   444  		}
   445  		if idx != 3 {
   446  			t.Fatalf("bad index: %d", idx)
   447  		}
   448  		if len(out) != 1 {
   449  			t.Fatalf("bad: %#v", out)
   450  		}
   451  		c := out[0]
   452  		if c.Node != nodeName || c.CheckID != "check1" || c.Name != "check" ||
   453  			c.CreateIndex != 3 || c.ModifyIndex != 3 {
   454  			t.Fatalf("bad check returned: %#v", c)
   455  		}
   456  	}
   457  	verifyNode(nodeID)
   458  	verifyNode(nodeName)
   459  	verifyService(nodeID)
   460  	verifyService(nodeName)
   461  	verifyCheck()
   462  
   463  	// Add in another check via the slice.
   464  	req.Checks = structs.HealthChecks{
   465  		&structs.HealthCheck{
   466  			Node:    nodeName,
   467  			CheckID: "check2",
   468  			Name:    "check",
   469  		},
   470  	}
   471  	restore = s.Restore()
   472  	if err := restore.Registration(4, req); err != nil {
   473  		t.Fatalf("err: %s", err)
   474  	}
   475  	restore.Commit()
   476  
   477  	// Verify that the additional check got registered.
   478  	verifyNode(nodeID)
   479  	verifyNode(nodeName)
   480  	verifyService(nodeID)
   481  	verifyService(nodeName)
   482  	func() {
   483  		idx, out, err := s.NodeChecks(nil, nodeName)
   484  		if err != nil {
   485  			t.Fatalf("err: %s", err)
   486  		}
   487  		if idx != 4 {
   488  			t.Fatalf("bad index: %d", idx)
   489  		}
   490  		if len(out) != 2 {
   491  			t.Fatalf("bad: %#v", out)
   492  		}
   493  		c1 := out[0]
   494  		if c1.Node != nodeName || c1.CheckID != "check1" || c1.Name != "check" ||
   495  			c1.CreateIndex != 3 || c1.ModifyIndex != 3 {
   496  			t.Fatalf("bad check returned, should not be modified: %#v", c1)
   497  		}
   498  
   499  		c2 := out[1]
   500  		if c2.Node != nodeName || c2.CheckID != "check2" || c2.Name != "check" ||
   501  			c2.CreateIndex != 4 || c2.ModifyIndex != 4 {
   502  			t.Fatalf("bad check returned: %#v", c2)
   503  		}
   504  	}()
   505  }
   506  
   507  func deprecatedEnsureNodeWithoutIDCanRegister(t *testing.T, s *Store, nodeName string, txIdx uint64) {
   508  	// All the following is deprecated, and should be removed in future Consul versions
   509  	in := &structs.Node{
   510  		Node:    nodeName,
   511  		Address: "1.1.1.9",
   512  		Meta: map[string]string{
   513  			"version": string(txIdx),
   514  		},
   515  	}
   516  	if err := s.EnsureNode(txIdx, in); err != nil {
   517  		t.Fatalf("err: %s", err)
   518  	}
   519  	idx, out, err := s.GetNode(nodeName)
   520  	if err != nil {
   521  		t.Fatalf("err: %s", err)
   522  	}
   523  	if idx != txIdx {
   524  		t.Fatalf("index should be %v, was: %v", txIdx, idx)
   525  	}
   526  	if out.Node != nodeName {
   527  		t.Fatalf("unexpected result out = %v, nodeName supposed to be %s", out, nodeName)
   528  	}
   529  }
   530  
   531  func TestStateStore_EnsureNodeDeprecated(t *testing.T) {
   532  	s := testStateStore(t)
   533  
   534  	firstNodeName := "node-without-id"
   535  	deprecatedEnsureNodeWithoutIDCanRegister(t, s, firstNodeName, 1)
   536  
   537  	newNodeID := types.NodeID("00a916bc-a357-4a19-b886-59419fcee50c")
   538  	// With this request, we basically add a node ID to existing node
   539  	// and change its address
   540  	in := &structs.Node{
   541  		ID:      newNodeID,
   542  		Node:    firstNodeName,
   543  		Address: "1.1.7.8",
   544  	}
   545  	if err := s.EnsureNode(4, in); err != nil {
   546  		t.Fatalf("err: %v", err)
   547  	}
   548  	// Retrieve the node again
   549  	idx, out, err := s.GetNode(firstNodeName)
   550  	if err != nil {
   551  		t.Fatalf("err: %s", err)
   552  	}
   553  
   554  	// Node has updated information
   555  	if idx != 4 || out.Node != firstNodeName || out.ID != newNodeID || out.Address != "1.1.7.8" {
   556  		t.Fatalf("[DEPRECATED] bad node returned: %#v", out)
   557  	}
   558  	if out.CreateIndex != 1 || out.ModifyIndex != 4 {
   559  		t.Fatalf("[DEPRECATED] bad CreateIndex/ModifyIndex returned: %#v", out)
   560  	}
   561  
   562  	// Now, lets update IP Address without providing any ID
   563  	// Only name of node will be used to match
   564  	in = &structs.Node{
   565  		Node:    firstNodeName,
   566  		Address: "1.1.7.10",
   567  	}
   568  	if err := s.EnsureNode(7, in); err != nil {
   569  		t.Fatalf("err: %v", err)
   570  	}
   571  	// Retrieve the node again
   572  	idx, out, err = s.GetNode(firstNodeName)
   573  	if err != nil {
   574  		t.Fatalf("err: %s", err)
   575  	}
   576  
   577  	// Node has updated information, its ID has been removed (deprecated, but working)
   578  	if idx != 7 || out.Node != firstNodeName || out.ID != "" || out.Address != "1.1.7.10" {
   579  		t.Fatalf("[DEPRECATED] bad node returned: %#v", out)
   580  	}
   581  	if out.CreateIndex != 1 || out.ModifyIndex != 7 {
   582  		t.Fatalf("[DEPRECATED] bad CreateIndex/ModifyIndex returned: %#v", out)
   583  	}
   584  }
   585  
   586  func TestNodeRenamingNodes(t *testing.T) {
   587  	s := testStateStore(t)
   588  
   589  	nodeID1 := types.NodeID("b789bf0a-d96b-4f70-a4a6-ac5dfaece53d")
   590  	nodeID2 := types.NodeID("27bee224-a4d7-45d0-9b8e-65b3c94a61ba")
   591  
   592  	// Node1 with ID
   593  	in1 := &structs.Node{
   594  		ID:      nodeID1,
   595  		Node:    "node1",
   596  		Address: "1.1.1.1",
   597  	}
   598  
   599  	if err := s.EnsureNode(1, in1); err != nil {
   600  		t.Fatalf("err: %s", err)
   601  	}
   602  
   603  	// Node2 with ID
   604  	in2 := &structs.Node{
   605  		ID:      nodeID2,
   606  		Node:    "node2",
   607  		Address: "1.1.1.2",
   608  	}
   609  
   610  	if err := s.EnsureNode(2, in2); err != nil {
   611  		t.Fatalf("err: %s", err)
   612  	}
   613  
   614  	// Node3 without ID
   615  	in3 := &structs.Node{
   616  		Node:    "node3",
   617  		Address: "1.1.1.3",
   618  	}
   619  
   620  	if err := s.EnsureNode(3, in3); err != nil {
   621  		t.Fatalf("err: %s", err)
   622  	}
   623  
   624  	if _, node, err := s.GetNodeID(nodeID1); err != nil || node == nil || node.ID != nodeID1 {
   625  		t.Fatalf("err: %s, node:= %q", err, node)
   626  	}
   627  
   628  	if _, node, err := s.GetNodeID(nodeID2); err != nil && node == nil || node.ID != nodeID2 {
   629  		t.Fatalf("err: %s", err)
   630  	}
   631  
   632  	// Renaming node2 into node1 should fail
   633  	in2Modify := &structs.Node{
   634  		ID:      nodeID2,
   635  		Node:    "node1",
   636  		Address: "1.1.1.2",
   637  	}
   638  	if err := s.EnsureNode(4, in2Modify); err == nil {
   639  		t.Fatalf("Renaming node2 into node1 should fail")
   640  	}
   641  
   642  	// Conflict with case insensitive matching as well
   643  	in2Modify = &structs.Node{
   644  		ID:      nodeID2,
   645  		Node:    "NoDe1",
   646  		Address: "1.1.1.2",
   647  	}
   648  	if err := s.EnsureNode(5, in2Modify); err == nil {
   649  		t.Fatalf("Renaming node2 into node1 should fail")
   650  	}
   651  
   652  	// Conflict with case insensitive on node without ID
   653  	in2Modify = &structs.Node{
   654  		ID:      nodeID2,
   655  		Node:    "NoDe3",
   656  		Address: "1.1.1.2",
   657  	}
   658  	if err := s.EnsureNode(6, in2Modify); err == nil {
   659  		t.Fatalf("Renaming node2 into node1 should fail")
   660  	}
   661  
   662  	// No conflict, should work
   663  	in2Modify = &structs.Node{
   664  		ID:      nodeID2,
   665  		Node:    "node2bis",
   666  		Address: "1.1.1.2",
   667  	}
   668  	if err := s.EnsureNode(6, in2Modify); err != nil {
   669  		t.Fatalf("Renaming node2 into node1 should fail")
   670  	}
   671  
   672  	// Retrieve the node again
   673  	idx, out, err := s.GetNode("node2bis")
   674  	if err != nil {
   675  		t.Fatalf("err: %s", err)
   676  	}
   677  
   678  	// Retrieve the node again
   679  	idx2, out2, err := s.GetNodeID(nodeID2)
   680  	if err != nil {
   681  		t.Fatalf("err: %s", err)
   682  	}
   683  
   684  	if idx != idx2 {
   685  		t.Fatalf("node should be the same")
   686  	}
   687  
   688  	if out.ID != out2.ID || out.Node != out2.Node {
   689  		t.Fatalf("all should match")
   690  	}
   691  }
   692  
   693  func TestStateStore_EnsureNode(t *testing.T) {
   694  	s := testStateStore(t)
   695  
   696  	// Fetching a non-existent node returns nil
   697  	if _, node, err := s.GetNode("node1"); node != nil || err != nil {
   698  		t.Fatalf("expected (nil, nil), got: (%#v, %#v)", node, err)
   699  	}
   700  
   701  	// Create a node registration request
   702  	in := &structs.Node{
   703  		ID:      types.NodeID("cda916bc-a357-4a19-b886-59419fcee50c"),
   704  		Node:    "node1",
   705  		Address: "1.1.1.1",
   706  	}
   707  
   708  	// Ensure the node is registered in the db
   709  	if err := s.EnsureNode(1, in); err != nil {
   710  		t.Fatalf("err: %s", err)
   711  	}
   712  
   713  	// Retrieve the node again
   714  	idx, out, err := s.GetNode("node1")
   715  	if err != nil {
   716  		t.Fatalf("err: %s", err)
   717  	}
   718  
   719  	// Correct node was returned
   720  	if out.Node != "node1" || out.Address != "1.1.1.1" {
   721  		t.Fatalf("bad node returned: %#v", out)
   722  	}
   723  
   724  	// Indexes are set properly
   725  	if out.CreateIndex != 1 || out.ModifyIndex != 1 {
   726  		t.Fatalf("bad node index: %#v", out)
   727  	}
   728  	if idx != 1 {
   729  		t.Fatalf("bad index: %d", idx)
   730  	}
   731  
   732  	// Update the node registration
   733  	in2 := &structs.Node{
   734  		ID:      in.ID,
   735  		Node:    in.Node,
   736  		Address: "1.1.1.2",
   737  	}
   738  	if err := s.EnsureNode(2, in2); err != nil {
   739  		t.Fatalf("err: %s", err)
   740  	}
   741  
   742  	// Retrieve the node
   743  	idx, out, err = s.GetNode("node1")
   744  	if err != nil {
   745  		t.Fatalf("err: %s", err)
   746  	}
   747  
   748  	// Node and indexes were updated
   749  	if out.CreateIndex != 1 || out.ModifyIndex != 2 || out.Address != "1.1.1.2" {
   750  		t.Fatalf("bad: %#v", out)
   751  	}
   752  	if idx != 2 {
   753  		t.Fatalf("bad index: %d", idx)
   754  	}
   755  
   756  	// Re-inserting data should not modify ModifiedIndex
   757  	if err := s.EnsureNode(3, in2); err != nil {
   758  		t.Fatalf("err: %s", err)
   759  	}
   760  	idx, out, err = s.GetNode("node1")
   761  	if err != nil {
   762  		t.Fatalf("err: %s", err)
   763  	}
   764  	if out.CreateIndex != 1 || out.ModifyIndex != 2 || out.Address != "1.1.1.2" {
   765  		t.Fatalf("node was modified: %#v", out)
   766  	}
   767  
   768  	// Node upsert preserves the create index
   769  	in3 := &structs.Node{
   770  		ID:      in.ID,
   771  		Node:    in.Node,
   772  		Address: "1.1.1.3",
   773  	}
   774  	if err := s.EnsureNode(3, in3); err != nil {
   775  		t.Fatalf("err: %s", err)
   776  	}
   777  	idx, out, err = s.GetNode("node1")
   778  	if err != nil {
   779  		t.Fatalf("err: %s", err)
   780  	}
   781  	if out.CreateIndex != 1 || out.ModifyIndex != 3 || out.Address != "1.1.1.3" {
   782  		t.Fatalf("node was modified: %#v", out)
   783  	}
   784  	if idx != 3 {
   785  		t.Fatalf("bad index: %d", idx)
   786  	}
   787  
   788  	// Update index to 4, no change
   789  	if err := s.EnsureNode(4, in); err != nil {
   790  		t.Fatalf("err: %v", err)
   791  	}
   792  
   793  	// Now try to add another node with the same ID
   794  	in = &structs.Node{
   795  		Node:    "node1-renamed",
   796  		ID:      types.NodeID("cda916bc-a357-4a19-b886-59419fcee50c"),
   797  		Address: "1.1.1.2",
   798  	}
   799  	if err := s.EnsureNode(6, in); err != nil {
   800  		t.Fatalf("err: %s", err)
   801  	}
   802  
   803  	// Retrieve the node
   804  	idx, out, err = s.GetNode("node1")
   805  	if out != nil {
   806  		t.Fatalf("Node should not exist anymore: %q", out)
   807  	}
   808  
   809  	idx, out, err = s.GetNode("node1-renamed")
   810  	if err != nil {
   811  		t.Fatalf("err: %s", err)
   812  	}
   813  
   814  	if out == nil {
   815  		t.Fatalf("err: %s", err)
   816  	}
   817  
   818  	// Node and indexes were updated
   819  	if out.CreateIndex != 1 || out.ModifyIndex != 6 || out.Address != "1.1.1.2" || out.Node != "node1-renamed" {
   820  		t.Fatalf("bad: %#v", out)
   821  	}
   822  	if idx != 6 {
   823  		t.Fatalf("bad index: %d", idx)
   824  	}
   825  
   826  	newNodeID := types.NodeID("d0347693-65cc-4d9f-a6e0-5025b2e6513f")
   827  
   828  	// Adding another node with same name should fail
   829  	in = &structs.Node{
   830  		Node:    "node1-renamed",
   831  		ID:      newNodeID,
   832  		Address: "1.1.1.7",
   833  	}
   834  	if err := s.EnsureNode(8, in); err == nil {
   835  		t.Fatalf("There should be an error since node1-renamed already exists")
   836  	}
   837  
   838  	// Adding another node with same name but different case should fail
   839  	in = &structs.Node{
   840  		Node:    "Node1-RENAMED",
   841  		ID:      newNodeID,
   842  		Address: "1.1.1.7",
   843  	}
   844  	if err := s.EnsureNode(8, in); err == nil {
   845  		t.Fatalf("err: %s", err)
   846  	}
   847  
   848  	// Lets add another valid node now
   849  	in = &structs.Node{
   850  		Node:    "Node1bis",
   851  		ID:      newNodeID,
   852  		Address: "1.1.1.7",
   853  	}
   854  	if err := s.EnsureNode(9, in); err != nil {
   855  		t.Fatalf("err: %s", err)
   856  	}
   857  
   858  	// Retrieve the node
   859  	idx, out, err = s.GetNode("Node1bis")
   860  	if out == nil {
   861  		t.Fatalf("Node should exist, but was null")
   862  	}
   863  
   864  	// Renaming should fail
   865  	in = &structs.Node{
   866  		Node:    "Node1bis",
   867  		ID:      newNodeID,
   868  		Address: "1.1.1.7",
   869  	}
   870  	if err := s.EnsureNode(9, in); err != nil {
   871  		t.Fatalf("err: %s", err)
   872  	}
   873  
   874  	idx, out, err = s.GetNode("Node1bis")
   875  	if err != nil {
   876  		t.Fatalf("err: %s", err)
   877  	}
   878  
   879  	// Node and indexes were updated
   880  	if out.ID != newNodeID || out.CreateIndex != 9 || out.ModifyIndex != 9 || out.Address != "1.1.1.7" || out.Node != "Node1bis" {
   881  		t.Fatalf("bad: %#v", out)
   882  	}
   883  	if idx != 9 {
   884  		t.Fatalf("bad index: %d", idx)
   885  	}
   886  
   887  	// Renaming to same value as first node should fail as well
   888  	// Adding another node with same name but different case should fail
   889  	in = &structs.Node{
   890  		Node:    "node1-renamed",
   891  		ID:      newNodeID,
   892  		Address: "1.1.1.7",
   893  	}
   894  	if err := s.EnsureNode(10, in); err == nil {
   895  		t.Fatalf("err: %s", err)
   896  	}
   897  
   898  	// It should fail also with different case
   899  	in = &structs.Node{
   900  		Node:    "Node1-Renamed",
   901  		ID:      newNodeID,
   902  		Address: "1.1.1.7",
   903  	}
   904  	if err := s.EnsureNode(10, in); err == nil {
   905  		t.Fatalf("err: %s", err)
   906  	}
   907  
   908  	// But should work if names are different
   909  	in = &structs.Node{
   910  		Node:    "Node1-Renamed2",
   911  		ID:      newNodeID,
   912  		Address: "1.1.1.7",
   913  	}
   914  	if err := s.EnsureNode(11, in); err != nil {
   915  		t.Fatalf("err: %s", err)
   916  	}
   917  	idx, out, err = s.GetNode("Node1-Renamed2")
   918  	if err != nil {
   919  		t.Fatalf("err: %s", err)
   920  	}
   921  
   922  	// Node and indexes were updated
   923  	if out.ID != newNodeID || out.CreateIndex != 9 || out.ModifyIndex != 11 || out.Address != "1.1.1.7" || out.Node != "Node1-Renamed2" {
   924  		t.Fatalf("bad: %#v", out)
   925  	}
   926  	if idx != 11 {
   927  		t.Fatalf("bad index: %d", idx)
   928  	}
   929  
   930  	// All the remaining tests are deprecated, please remove them on next Consul major release
   931  	// See https://github.com/hashicorp/consul/pull/3983 for context
   932  
   933  	// Deprecated behavior is following
   934  	deprecatedEnsureNodeWithoutIDCanRegister(t, s, "new-node-without-id", 12)
   935  
   936  	// Deprecated, but should work as well
   937  	deprecatedEnsureNodeWithoutIDCanRegister(t, s, "new-node-without-id", 13)
   938  
   939  	// All of this is deprecated as well, should be removed
   940  	in = &structs.Node{
   941  		Node:    "Node1-Renamed2",
   942  		Address: "1.1.1.66",
   943  	}
   944  	if err := s.EnsureNode(14, in); err != nil {
   945  		t.Fatalf("[DEPRECATED] it should work, err:= %q", err)
   946  	}
   947  	idx, out, err = s.GetNode("Node1-Renamed2")
   948  	if err != nil {
   949  		t.Fatalf("[DEPRECATED] err: %s", err)
   950  	}
   951  	if out.CreateIndex != 9 {
   952  		t.Fatalf("[DEPRECATED] We expected to modify node previously added, but add index = %d for node %q", out.CreateIndex, out)
   953  	}
   954  	if out.Address != "1.1.1.66" || out.ModifyIndex != 14 {
   955  		t.Fatalf("[DEPRECATED] Node with newNodeID should have been updated, but was: %d with content := %q", out.CreateIndex, out)
   956  	}
   957  }
   958  
   959  func TestStateStore_GetNodes(t *testing.T) {
   960  	s := testStateStore(t)
   961  
   962  	// Listing with no results returns nil.
   963  	ws := memdb.NewWatchSet()
   964  	idx, res, err := s.Nodes(ws)
   965  	if idx != 0 || res != nil || err != nil {
   966  		t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, res, err)
   967  	}
   968  
   969  	// Create some nodes in the state store.
   970  	testRegisterNode(t, s, 0, "node0")
   971  	testRegisterNode(t, s, 1, "node1")
   972  	testRegisterNode(t, s, 2, "node2")
   973  	if !watchFired(ws) {
   974  		t.Fatalf("bad")
   975  	}
   976  
   977  	// Retrieve the nodes.
   978  	ws = memdb.NewWatchSet()
   979  	idx, nodes, err := s.Nodes(ws)
   980  	if err != nil {
   981  		t.Fatalf("err: %s", err)
   982  	}
   983  
   984  	// Highest index was returned.
   985  	if idx != 2 {
   986  		t.Fatalf("bad index: %d", idx)
   987  	}
   988  
   989  	// All nodes were returned.
   990  	if n := len(nodes); n != 3 {
   991  		t.Fatalf("bad node count: %d", n)
   992  	}
   993  
   994  	// Make sure the nodes match.
   995  	for i, node := range nodes {
   996  		if node.CreateIndex != uint64(i) || node.ModifyIndex != uint64(i) {
   997  			t.Fatalf("bad node index: %d, %d", node.CreateIndex, node.ModifyIndex)
   998  		}
   999  		name := fmt.Sprintf("node%d", i)
  1000  		if node.Node != name {
  1001  			t.Fatalf("bad: %#v", node)
  1002  		}
  1003  	}
  1004  
  1005  	// Make sure a node delete fires the watch.
  1006  	if watchFired(ws) {
  1007  		t.Fatalf("bad")
  1008  	}
  1009  	if err := s.DeleteNode(3, "node1"); err != nil {
  1010  		t.Fatalf("err: %s", err)
  1011  	}
  1012  	if !watchFired(ws) {
  1013  		t.Fatalf("bad")
  1014  	}
  1015  }
  1016  
  1017  func BenchmarkGetNodes(b *testing.B) {
  1018  	s, err := NewStateStore(nil)
  1019  	if err != nil {
  1020  		b.Fatalf("err: %s", err)
  1021  	}
  1022  
  1023  	if err := s.EnsureNode(100, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
  1024  		b.Fatalf("err: %v", err)
  1025  	}
  1026  	if err := s.EnsureNode(101, &structs.Node{Node: "bar", Address: "127.0.0.2"}); err != nil {
  1027  		b.Fatalf("err: %v", err)
  1028  	}
  1029  
  1030  	ws := memdb.NewWatchSet()
  1031  	for i := 0; i < b.N; i++ {
  1032  		s.Nodes(ws)
  1033  	}
  1034  }
  1035  
  1036  func TestStateStore_GetNodesByMeta(t *testing.T) {
  1037  	s := testStateStore(t)
  1038  
  1039  	// Listing with no results returns nil
  1040  	ws := memdb.NewWatchSet()
  1041  	idx, res, err := s.NodesByMeta(ws, map[string]string{"somekey": "somevalue"})
  1042  	if idx != 0 || res != nil || err != nil {
  1043  		t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, res, err)
  1044  	}
  1045  
  1046  	// Create some nodes in the state store.
  1047  	testRegisterNodeWithMeta(t, s, 0, "node0", map[string]string{"role": "client"})
  1048  	testRegisterNodeWithMeta(t, s, 1, "node1", map[string]string{"role": "client", "common": "1"})
  1049  	testRegisterNodeWithMeta(t, s, 2, "node2", map[string]string{"role": "server", "common": "1"})
  1050  	if !watchFired(ws) {
  1051  		t.Fatalf("bad")
  1052  	}
  1053  
  1054  	cases := []struct {
  1055  		filters map[string]string
  1056  		nodes   []string
  1057  	}{
  1058  		// Simple meta filter
  1059  		{
  1060  			filters: map[string]string{"role": "server"},
  1061  			nodes:   []string{"node2"},
  1062  		},
  1063  		// Common meta filter
  1064  		{
  1065  			filters: map[string]string{"common": "1"},
  1066  			nodes:   []string{"node1", "node2"},
  1067  		},
  1068  		// Invalid meta filter
  1069  		{
  1070  			filters: map[string]string{"invalid": "nope"},
  1071  			nodes:   []string{},
  1072  		},
  1073  		// Multiple meta filters
  1074  		{
  1075  			filters: map[string]string{"role": "client", "common": "1"},
  1076  			nodes:   []string{"node1"},
  1077  		},
  1078  	}
  1079  
  1080  	for _, tc := range cases {
  1081  		_, result, err := s.NodesByMeta(nil, tc.filters)
  1082  		if err != nil {
  1083  			t.Fatalf("bad: %v", err)
  1084  		}
  1085  
  1086  		if len(result) != len(tc.nodes) {
  1087  			t.Fatalf("bad: %v %v", result, tc.nodes)
  1088  		}
  1089  
  1090  		for i, node := range result {
  1091  			if node.Node != tc.nodes[i] {
  1092  				t.Fatalf("bad: %v %v", node.Node, tc.nodes[i])
  1093  			}
  1094  		}
  1095  	}
  1096  
  1097  	// Set up a watch.
  1098  	ws = memdb.NewWatchSet()
  1099  	_, _, err = s.NodesByMeta(ws, map[string]string{"role": "client"})
  1100  	if err != nil {
  1101  		t.Fatalf("err: %v", err)
  1102  	}
  1103  
  1104  	// Make an unrelated modification and make sure the watch doesn't fire.
  1105  	testRegisterNodeWithMeta(t, s, 3, "node3", map[string]string{"foo": "bar"})
  1106  	if watchFired(ws) {
  1107  		t.Fatalf("bad")
  1108  	}
  1109  
  1110  	// Change a watched key and make sure it fires.
  1111  	testRegisterNodeWithMeta(t, s, 4, "node0", map[string]string{"role": "different"})
  1112  	if !watchFired(ws) {
  1113  		t.Fatalf("bad")
  1114  	}
  1115  }
  1116  
  1117  func TestStateStore_NodeServices(t *testing.T) {
  1118  	s := testStateStore(t)
  1119  
  1120  	// Register some nodes with similar IDs.
  1121  	{
  1122  		req := &structs.RegisterRequest{
  1123  			ID:      types.NodeID("40e4a748-2192-161a-0510-aaaaaaaaaaaa"),
  1124  			Node:    "node1",
  1125  			Address: "1.2.3.4",
  1126  		}
  1127  		if err := s.EnsureRegistration(1, req); err != nil {
  1128  			t.Fatalf("err: %s", err)
  1129  		}
  1130  	}
  1131  	{
  1132  		req := &structs.RegisterRequest{
  1133  			ID:      types.NodeID("40e4a748-2192-161a-0510-bbbbbbbbbbbb"),
  1134  			Node:    "node2",
  1135  			Address: "5.6.7.8",
  1136  		}
  1137  		if err := s.EnsureRegistration(2, req); err != nil {
  1138  			t.Fatalf("err: %s", err)
  1139  		}
  1140  	}
  1141  
  1142  	// Look up by name.
  1143  	{
  1144  		_, ns, err := s.NodeServices(nil, "node1")
  1145  		if err != nil {
  1146  			t.Fatalf("err: %v", err)
  1147  		}
  1148  		if ns == nil || ns.Node.Node != "node1" {
  1149  			t.Fatalf("bad: %#v", *ns)
  1150  		}
  1151  	}
  1152  	{
  1153  		_, ns, err := s.NodeServices(nil, "node2")
  1154  		if err != nil {
  1155  			t.Fatalf("err: %v", err)
  1156  		}
  1157  		if ns == nil || ns.Node.Node != "node2" {
  1158  			t.Fatalf("bad: %#v", *ns)
  1159  		}
  1160  	}
  1161  
  1162  	// Look up by UUID.
  1163  	{
  1164  		_, ns, err := s.NodeServices(nil, "40e4a748-2192-161a-0510-aaaaaaaaaaaa")
  1165  		if err != nil {
  1166  			t.Fatalf("err: %v", err)
  1167  		}
  1168  		if ns == nil || ns.Node.Node != "node1" {
  1169  			t.Fatalf("bad: %#v", ns)
  1170  		}
  1171  	}
  1172  	{
  1173  		_, ns, err := s.NodeServices(nil, "40e4a748-2192-161a-0510-bbbbbbbbbbbb")
  1174  		if err != nil {
  1175  			t.Fatalf("err: %v", err)
  1176  		}
  1177  		if ns == nil || ns.Node.Node != "node2" {
  1178  			t.Fatalf("bad: %#v", ns)
  1179  		}
  1180  	}
  1181  
  1182  	// Ambiguous prefix.
  1183  	{
  1184  		_, ns, err := s.NodeServices(nil, "40e4a748-2192-161a-0510")
  1185  		if err != nil {
  1186  			t.Fatalf("err: %v", err)
  1187  		}
  1188  		if ns != nil {
  1189  			t.Fatalf("bad: %#v", ns)
  1190  		}
  1191  	}
  1192  
  1193  	// Bad node, and not a UUID (should not get a UUID error).
  1194  	{
  1195  		_, ns, err := s.NodeServices(nil, "nope")
  1196  		if err != nil {
  1197  			t.Fatalf("err: %v", err)
  1198  		}
  1199  		if ns != nil {
  1200  			t.Fatalf("bad: %#v", ns)
  1201  		}
  1202  	}
  1203  
  1204  	// Specific prefix.
  1205  	{
  1206  		_, ns, err := s.NodeServices(nil, "40e4a748-2192-161a-0510-bb")
  1207  		if err != nil {
  1208  			t.Fatalf("err: %v", err)
  1209  		}
  1210  		if ns == nil || ns.Node.Node != "node2" {
  1211  			t.Fatalf("bad: %#v", ns)
  1212  		}
  1213  	}
  1214  }
  1215  
  1216  func TestStateStore_DeleteNode(t *testing.T) {
  1217  	s := testStateStore(t)
  1218  
  1219  	// Create a node and register a service and health check with it.
  1220  	testRegisterNode(t, s, 0, "node1")
  1221  	testRegisterService(t, s, 1, "node1", "service1")
  1222  	testRegisterCheck(t, s, 2, "node1", "", "check1", api.HealthPassing)
  1223  
  1224  	// Delete the node
  1225  	if err := s.DeleteNode(3, "node1"); err != nil {
  1226  		t.Fatalf("err: %s", err)
  1227  	}
  1228  
  1229  	// The node was removed
  1230  	if idx, n, err := s.GetNode("node1"); err != nil || n != nil || idx != 3 {
  1231  		t.Fatalf("bad: %#v %d (err: %#v)", n, idx, err)
  1232  	}
  1233  
  1234  	// Associated service was removed. Need to query this directly out of
  1235  	// the DB to make sure it is actually gone.
  1236  	tx := s.db.Txn(false)
  1237  	defer tx.Abort()
  1238  	services, err := tx.Get("services", "id", "node1", "service1")
  1239  	if err != nil {
  1240  		t.Fatalf("err: %s", err)
  1241  	}
  1242  	if service := services.Next(); service != nil {
  1243  		t.Fatalf("bad: %#v", service)
  1244  	}
  1245  
  1246  	// Associated health check was removed.
  1247  	checks, err := tx.Get("checks", "id", "node1", "check1")
  1248  	if err != nil {
  1249  		t.Fatalf("err: %s", err)
  1250  	}
  1251  	if check := checks.Next(); check != nil {
  1252  		t.Fatalf("bad: %#v", check)
  1253  	}
  1254  
  1255  	// Indexes were updated.
  1256  	for _, tbl := range []string{"nodes", "services", "checks"} {
  1257  		if idx := s.maxIndex(tbl); idx != 3 {
  1258  			t.Fatalf("bad index: %d (%s)", idx, tbl)
  1259  		}
  1260  	}
  1261  
  1262  	// Deleting a nonexistent node should be idempotent and not return
  1263  	// an error
  1264  	if err := s.DeleteNode(4, "node1"); err != nil {
  1265  		t.Fatalf("err: %s", err)
  1266  	}
  1267  	if idx := s.maxIndex("nodes"); idx != 3 {
  1268  		t.Fatalf("bad index: %d", idx)
  1269  	}
  1270  }
  1271  
  1272  func TestStateStore_Node_Snapshot(t *testing.T) {
  1273  	s := testStateStore(t)
  1274  
  1275  	// Create some nodes in the state store.
  1276  	testRegisterNode(t, s, 0, "node0")
  1277  	testRegisterNode(t, s, 1, "node1")
  1278  	testRegisterNode(t, s, 2, "node2")
  1279  
  1280  	// Snapshot the nodes.
  1281  	snap := s.Snapshot()
  1282  	defer snap.Close()
  1283  
  1284  	// Alter the real state store.
  1285  	testRegisterNode(t, s, 3, "node3")
  1286  
  1287  	// Verify the snapshot.
  1288  	if idx := snap.LastIndex(); idx != 2 {
  1289  		t.Fatalf("bad index: %d", idx)
  1290  	}
  1291  	nodes, err := snap.Nodes()
  1292  	if err != nil {
  1293  		t.Fatalf("err: %s", err)
  1294  	}
  1295  	for i := 0; i < 3; i++ {
  1296  		node := nodes.Next().(*structs.Node)
  1297  		if node == nil {
  1298  			t.Fatalf("unexpected end of nodes")
  1299  		}
  1300  
  1301  		if node.CreateIndex != uint64(i) || node.ModifyIndex != uint64(i) {
  1302  			t.Fatalf("bad node index: %d, %d", node.CreateIndex, node.ModifyIndex)
  1303  		}
  1304  		if node.Node != fmt.Sprintf("node%d", i) {
  1305  			t.Fatalf("bad: %#v", node)
  1306  		}
  1307  	}
  1308  	if nodes.Next() != nil {
  1309  		t.Fatalf("unexpected extra nodes")
  1310  	}
  1311  }
  1312  
  1313  func TestStateStore_EnsureService(t *testing.T) {
  1314  	s := testStateStore(t)
  1315  
  1316  	// Fetching services for a node with none returns nil.
  1317  	ws := memdb.NewWatchSet()
  1318  	idx, res, err := s.NodeServices(ws, "node1")
  1319  	if err != nil || res != nil || idx != 0 {
  1320  		t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, res, err)
  1321  	}
  1322  
  1323  	// Create the service registration.
  1324  	ns1 := &structs.NodeService{
  1325  		ID:      "service1",
  1326  		Service: "redis",
  1327  		Tags:    []string{"prod"},
  1328  		Address: "1.1.1.1",
  1329  		Port:    1111,
  1330  		Weights: &structs.Weights{Passing: 1, Warning: 0},
  1331  	}
  1332  
  1333  	// Creating a service without a node returns an error.
  1334  	if err := s.EnsureService(1, "node1", ns1); err != ErrMissingNode {
  1335  		t.Fatalf("expected %#v, got: %#v", ErrMissingNode, err)
  1336  	}
  1337  	if watchFired(ws) {
  1338  		t.Fatalf("bad")
  1339  	}
  1340  
  1341  	// Register the nodes.
  1342  	testRegisterNode(t, s, 0, "node1")
  1343  	testRegisterNode(t, s, 1, "node2")
  1344  	if !watchFired(ws) {
  1345  		t.Fatalf("bad")
  1346  	}
  1347  
  1348  	// Service successfully registers into the state store.
  1349  	ws = memdb.NewWatchSet()
  1350  	_, _, err = s.NodeServices(ws, "node1")
  1351  	if err != nil {
  1352  		t.Fatalf("err: %v", err)
  1353  	}
  1354  	if err = s.EnsureService(10, "node1", ns1); err != nil {
  1355  		t.Fatalf("err: %s", err)
  1356  	}
  1357  	if !watchFired(ws) {
  1358  		t.Fatalf("bad")
  1359  	}
  1360  
  1361  	// Register a similar service against both nodes.
  1362  	ns2 := *ns1
  1363  	ns2.ID = "service2"
  1364  	for _, n := range []string{"node1", "node2"} {
  1365  		if err := s.EnsureService(20, n, &ns2); err != nil {
  1366  			t.Fatalf("err: %s", err)
  1367  		}
  1368  	}
  1369  
  1370  	// Register a different service on the bad node.
  1371  	ws = memdb.NewWatchSet()
  1372  	_, _, err = s.NodeServices(ws, "node1")
  1373  	if err != nil {
  1374  		t.Fatalf("err: %v", err)
  1375  	}
  1376  	ns3 := *ns1
  1377  	ns3.ID = "service3"
  1378  	if err := s.EnsureService(30, "node2", &ns3); err != nil {
  1379  		t.Fatalf("err: %s", err)
  1380  	}
  1381  	if watchFired(ws) {
  1382  		t.Fatalf("bad")
  1383  	}
  1384  
  1385  	// Retrieve the services.
  1386  	ws = memdb.NewWatchSet()
  1387  	idx, out, err := s.NodeServices(ws, "node1")
  1388  	if err != nil {
  1389  		t.Fatalf("err: %s", err)
  1390  	}
  1391  	if idx != 30 {
  1392  		t.Fatalf("bad index: %d", idx)
  1393  	}
  1394  
  1395  	// Only the services for the requested node are returned.
  1396  	if out == nil || len(out.Services) != 2 {
  1397  		t.Fatalf("bad services: %#v", out)
  1398  	}
  1399  
  1400  	// Results match the inserted services and have the proper indexes set.
  1401  	expect1 := *ns1
  1402  	expect1.CreateIndex, expect1.ModifyIndex = 10, 10
  1403  	if svc := out.Services["service1"]; !reflect.DeepEqual(&expect1, svc) {
  1404  		t.Fatalf("bad: %#v", svc)
  1405  	}
  1406  
  1407  	expect2 := ns2
  1408  	expect2.CreateIndex, expect2.ModifyIndex = 20, 20
  1409  	if svc := out.Services["service2"]; !reflect.DeepEqual(&expect2, svc) {
  1410  		t.Fatalf("bad: %#v %#v", ns2, svc)
  1411  	}
  1412  
  1413  	// Index tables were updated.
  1414  	if idx := s.maxIndex("services"); idx != 30 {
  1415  		t.Fatalf("bad index: %d", idx)
  1416  	}
  1417  
  1418  	// Update a service registration.
  1419  	ns1.Address = "1.1.1.2"
  1420  	if err := s.EnsureService(40, "node1", ns1); err != nil {
  1421  		t.Fatalf("err: %s", err)
  1422  	}
  1423  	if !watchFired(ws) {
  1424  		t.Fatalf("bad")
  1425  	}
  1426  
  1427  	// Retrieve the service again and ensure it matches..
  1428  	idx, out, err = s.NodeServices(nil, "node1")
  1429  	if err != nil {
  1430  		t.Fatalf("err: %s", err)
  1431  	}
  1432  	if idx != 40 {
  1433  		t.Fatalf("bad index: %d", idx)
  1434  	}
  1435  	if out == nil || len(out.Services) != 2 {
  1436  		t.Fatalf("bad: %#v", out)
  1437  	}
  1438  	expect1.Address = "1.1.1.2"
  1439  	expect1.ModifyIndex = 40
  1440  	if svc := out.Services["service1"]; !reflect.DeepEqual(&expect1, svc) {
  1441  		t.Fatalf("bad: %#v", svc)
  1442  	}
  1443  
  1444  	// Index tables were updated.
  1445  	if idx := s.maxIndex("services"); idx != 40 {
  1446  		t.Fatalf("bad index: %d", idx)
  1447  	}
  1448  }
  1449  
  1450  func TestStateStore_EnsureService_connectProxy(t *testing.T) {
  1451  	assert := assert.New(t)
  1452  	s := testStateStore(t)
  1453  
  1454  	// Create the service registration.
  1455  	ns1 := &structs.NodeService{
  1456  		Kind:    structs.ServiceKindConnectProxy,
  1457  		ID:      "connect-proxy",
  1458  		Service: "connect-proxy",
  1459  		Address: "1.1.1.1",
  1460  		Port:    1111,
  1461  		Weights: &structs.Weights{
  1462  			Passing: 1,
  1463  			Warning: 1,
  1464  		},
  1465  		Proxy: structs.ConnectProxyConfig{DestinationServiceName: "foo"},
  1466  	}
  1467  
  1468  	// Service successfully registers into the state store.
  1469  	testRegisterNode(t, s, 0, "node1")
  1470  	assert.Nil(s.EnsureService(10, "node1", ns1))
  1471  
  1472  	// Retrieve and verify
  1473  	_, out, err := s.NodeServices(nil, "node1")
  1474  	assert.Nil(err)
  1475  	assert.NotNil(out)
  1476  	assert.Len(out.Services, 1)
  1477  
  1478  	expect1 := *ns1
  1479  	expect1.CreateIndex, expect1.ModifyIndex = 10, 10
  1480  	assert.Equal(&expect1, out.Services["connect-proxy"])
  1481  }
  1482  
  1483  func TestStateStore_Services(t *testing.T) {
  1484  	s := testStateStore(t)
  1485  
  1486  	// Listing with no results returns an empty list.
  1487  	ws := memdb.NewWatchSet()
  1488  	idx, services, err := s.Services(ws)
  1489  	if err != nil {
  1490  		t.Fatalf("err: %s", err)
  1491  	}
  1492  	if idx != 0 {
  1493  		t.Fatalf("bad: %d", idx)
  1494  	}
  1495  	if len(services) != 0 {
  1496  		t.Fatalf("bad: %v", services)
  1497  	}
  1498  
  1499  	// Register several nodes and services.
  1500  	testRegisterNode(t, s, 1, "node1")
  1501  	ns1 := &structs.NodeService{
  1502  		ID:      "service1",
  1503  		Service: "redis",
  1504  		Tags:    []string{"prod", "master"},
  1505  		Address: "1.1.1.1",
  1506  		Port:    1111,
  1507  	}
  1508  	if err := s.EnsureService(2, "node1", ns1); err != nil {
  1509  		t.Fatalf("err: %s", err)
  1510  	}
  1511  	testRegisterService(t, s, 3, "node1", "dogs")
  1512  	testRegisterNode(t, s, 4, "node2")
  1513  	ns2 := &structs.NodeService{
  1514  		ID:      "service3",
  1515  		Service: "redis",
  1516  		Tags:    []string{"prod", "slave"},
  1517  		Address: "1.1.1.1",
  1518  		Port:    1111,
  1519  	}
  1520  	if err := s.EnsureService(5, "node2", ns2); err != nil {
  1521  		t.Fatalf("err: %s", err)
  1522  	}
  1523  	if !watchFired(ws) {
  1524  		t.Fatalf("bad")
  1525  	}
  1526  
  1527  	// Pull all the services.
  1528  	ws = memdb.NewWatchSet()
  1529  	idx, services, err = s.Services(ws)
  1530  	if err != nil {
  1531  		t.Fatalf("err: %s", err)
  1532  	}
  1533  	if idx != 5 {
  1534  		t.Fatalf("bad index: %d", idx)
  1535  	}
  1536  
  1537  	// Verify the result. We sort the lists since the order is
  1538  	// non-deterministic (it's built using a map internally).
  1539  	expected := structs.Services{
  1540  		"redis": []string{"prod", "master", "slave"},
  1541  		"dogs":  []string{},
  1542  	}
  1543  	sort.Strings(expected["redis"])
  1544  	for _, tags := range services {
  1545  		sort.Strings(tags)
  1546  	}
  1547  	if !reflect.DeepEqual(expected, services) {
  1548  		t.Fatalf("bad: %#v", services)
  1549  	}
  1550  
  1551  	// Deleting a node with a service should fire the watch.
  1552  	if err := s.DeleteNode(6, "node1"); err != nil {
  1553  		t.Fatalf("err: %s", err)
  1554  	}
  1555  	if !watchFired(ws) {
  1556  		t.Fatalf("bad")
  1557  	}
  1558  }
  1559  
  1560  func TestStateStore_ServicesByNodeMeta(t *testing.T) {
  1561  	s := testStateStore(t)
  1562  
  1563  	// Listing with no results returns nil.
  1564  	ws := memdb.NewWatchSet()
  1565  	idx, res, err := s.ServicesByNodeMeta(ws, map[string]string{"somekey": "somevalue"})
  1566  	if idx != 0 || len(res) != 0 || err != nil {
  1567  		t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, res, err)
  1568  	}
  1569  
  1570  	// Create some nodes and services in the state store.
  1571  	node0 := &structs.Node{Node: "node0", Address: "127.0.0.1", Meta: map[string]string{"role": "client", "common": "1"}}
  1572  	if err := s.EnsureNode(0, node0); err != nil {
  1573  		t.Fatalf("err: %v", err)
  1574  	}
  1575  	node1 := &structs.Node{Node: "node1", Address: "127.0.0.1", Meta: map[string]string{"role": "server", "common": "1"}}
  1576  	if err := s.EnsureNode(1, node1); err != nil {
  1577  		t.Fatalf("err: %v", err)
  1578  	}
  1579  	ns1 := &structs.NodeService{
  1580  		ID:      "service1",
  1581  		Service: "redis",
  1582  		Tags:    []string{"prod", "master"},
  1583  		Address: "1.1.1.1",
  1584  		Port:    1111,
  1585  	}
  1586  	if err := s.EnsureService(2, "node0", ns1); err != nil {
  1587  		t.Fatalf("err: %s", err)
  1588  	}
  1589  	ns2 := &structs.NodeService{
  1590  		ID:      "service1",
  1591  		Service: "redis",
  1592  		Tags:    []string{"prod", "slave"},
  1593  		Address: "1.1.1.1",
  1594  		Port:    1111,
  1595  	}
  1596  	if err := s.EnsureService(3, "node1", ns2); err != nil {
  1597  		t.Fatalf("err: %s", err)
  1598  	}
  1599  	if !watchFired(ws) {
  1600  		t.Fatalf("bad")
  1601  	}
  1602  
  1603  	// Filter the services by the first node's meta value.
  1604  	ws = memdb.NewWatchSet()
  1605  	_, res, err = s.ServicesByNodeMeta(ws, map[string]string{"role": "client"})
  1606  	if err != nil {
  1607  		t.Fatalf("err: %s", err)
  1608  	}
  1609  	expected := structs.Services{
  1610  		"redis": []string{"master", "prod"},
  1611  	}
  1612  	sort.Strings(res["redis"])
  1613  	if !reflect.DeepEqual(res, expected) {
  1614  		t.Fatalf("bad: %v %v", res, expected)
  1615  	}
  1616  
  1617  	// Get all services using the common meta value
  1618  	_, res, err = s.ServicesByNodeMeta(ws, map[string]string{"common": "1"})
  1619  	if err != nil {
  1620  		t.Fatalf("err: %s", err)
  1621  	}
  1622  	expected = structs.Services{
  1623  		"redis": []string{"master", "prod", "slave"},
  1624  	}
  1625  	sort.Strings(res["redis"])
  1626  	if !reflect.DeepEqual(res, expected) {
  1627  		t.Fatalf("bad: %v %v", res, expected)
  1628  	}
  1629  
  1630  	// Get an empty list for an invalid meta value
  1631  	_, res, err = s.ServicesByNodeMeta(ws, map[string]string{"invalid": "nope"})
  1632  	if err != nil {
  1633  		t.Fatalf("err: %s", err)
  1634  	}
  1635  	expected = structs.Services{}
  1636  	if !reflect.DeepEqual(res, expected) {
  1637  		t.Fatalf("bad: %v %v", res, expected)
  1638  	}
  1639  
  1640  	// Get the first node's service instance using multiple meta filters
  1641  	_, res, err = s.ServicesByNodeMeta(ws, map[string]string{"role": "client", "common": "1"})
  1642  	if err != nil {
  1643  		t.Fatalf("err: %s", err)
  1644  	}
  1645  	expected = structs.Services{
  1646  		"redis": []string{"master", "prod"},
  1647  	}
  1648  	sort.Strings(res["redis"])
  1649  	if !reflect.DeepEqual(res, expected) {
  1650  		t.Fatalf("bad: %v %v", res, expected)
  1651  	}
  1652  
  1653  	// Sanity check the watch before we proceed.
  1654  	if watchFired(ws) {
  1655  		t.Fatalf("bad")
  1656  	}
  1657  
  1658  	// Registering some unrelated node + service should not fire the watch.
  1659  	testRegisterNode(t, s, 4, "nope")
  1660  	testRegisterService(t, s, 5, "nope", "nope")
  1661  	if watchFired(ws) {
  1662  		t.Fatalf("bad")
  1663  	}
  1664  
  1665  	// Overwhelm the service tracking.
  1666  	idx = 6
  1667  	for i := 0; i < 2*watchLimit; i++ {
  1668  		node := fmt.Sprintf("many%d", i)
  1669  		testRegisterNodeWithMeta(t, s, idx, node, map[string]string{"common": "1"})
  1670  		idx++
  1671  		testRegisterService(t, s, idx, node, "nope")
  1672  		idx++
  1673  	}
  1674  
  1675  	// Now get a fresh watch, which will be forced to watch the whole
  1676  	// service table.
  1677  	ws = memdb.NewWatchSet()
  1678  	_, _, err = s.ServicesByNodeMeta(ws, map[string]string{"common": "1"})
  1679  	if err != nil {
  1680  		t.Fatalf("err: %s", err)
  1681  	}
  1682  
  1683  	// Registering some unrelated node + service should not fire the watch.
  1684  	testRegisterService(t, s, idx, "nope", "more-nope")
  1685  	if !watchFired(ws) {
  1686  		t.Fatalf("bad")
  1687  	}
  1688  }
  1689  
  1690  func TestStateStore_ServiceNodes(t *testing.T) {
  1691  	s := testStateStore(t)
  1692  
  1693  	// Listing with no results returns an empty list.
  1694  	ws := memdb.NewWatchSet()
  1695  	idx, nodes, err := s.ServiceNodes(ws, "db")
  1696  	if err != nil {
  1697  		t.Fatalf("err: %s", err)
  1698  	}
  1699  	if idx != 0 {
  1700  		t.Fatalf("bad: %d", idx)
  1701  	}
  1702  	if len(nodes) != 0 {
  1703  		t.Fatalf("bad: %v", nodes)
  1704  	}
  1705  
  1706  	// Create some nodes and services.
  1707  	if err := s.EnsureNode(10, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
  1708  		t.Fatalf("err: %v", err)
  1709  	}
  1710  	if err := s.EnsureNode(11, &structs.Node{Node: "bar", Address: "127.0.0.2"}); err != nil {
  1711  		t.Fatalf("err: %v", err)
  1712  	}
  1713  	if err := s.EnsureService(12, "foo", &structs.NodeService{ID: "api", Service: "api", Tags: nil, Address: "", Port: 5000}); err != nil {
  1714  		t.Fatalf("err: %v", err)
  1715  	}
  1716  	if err := s.EnsureService(13, "bar", &structs.NodeService{ID: "api", Service: "api", Tags: nil, Address: "", Port: 5000}); err != nil {
  1717  		t.Fatalf("err: %v", err)
  1718  	}
  1719  	if err := s.EnsureService(14, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"master"}, Address: "", Port: 8000}); err != nil {
  1720  		t.Fatalf("err: %v", err)
  1721  	}
  1722  	if err := s.EnsureService(15, "bar", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"slave"}, Address: "", Port: 8000}); err != nil {
  1723  		t.Fatalf("err: %v", err)
  1724  	}
  1725  	if err := s.EnsureService(16, "bar", &structs.NodeService{ID: "db2", Service: "db", Tags: []string{"slave"}, Address: "", Port: 8001}); err != nil {
  1726  		t.Fatalf("err: %v", err)
  1727  	}
  1728  	if !watchFired(ws) {
  1729  		t.Fatalf("bad")
  1730  	}
  1731  
  1732  	// Read everything back.
  1733  	ws = memdb.NewWatchSet()
  1734  	idx, nodes, err = s.ServiceNodes(ws, "db")
  1735  	if err != nil {
  1736  		t.Fatalf("err: %s", err)
  1737  	}
  1738  	if idx != 16 {
  1739  		t.Fatalf("bad: %d", idx)
  1740  	}
  1741  	if len(nodes) != 3 {
  1742  		t.Fatalf("bad: %v", nodes)
  1743  	}
  1744  	if nodes[0].Node != "bar" {
  1745  		t.Fatalf("bad: %v", nodes)
  1746  	}
  1747  	if nodes[0].Address != "127.0.0.2" {
  1748  		t.Fatalf("bad: %v", nodes)
  1749  	}
  1750  	if nodes[0].ServiceID != "db" {
  1751  		t.Fatalf("bad: %v", nodes)
  1752  	}
  1753  	if !lib.StrContains(nodes[0].ServiceTags, "slave") {
  1754  		t.Fatalf("bad: %v", nodes)
  1755  	}
  1756  	if nodes[0].ServicePort != 8000 {
  1757  		t.Fatalf("bad: %v", nodes)
  1758  	}
  1759  	if nodes[1].Node != "bar" {
  1760  		t.Fatalf("bad: %v", nodes)
  1761  	}
  1762  	if nodes[1].Address != "127.0.0.2" {
  1763  		t.Fatalf("bad: %v", nodes)
  1764  	}
  1765  	if nodes[1].ServiceID != "db2" {
  1766  		t.Fatalf("bad: %v", nodes)
  1767  	}
  1768  	if !lib.StrContains(nodes[1].ServiceTags, "slave") {
  1769  		t.Fatalf("bad: %v", nodes)
  1770  	}
  1771  	if nodes[1].ServicePort != 8001 {
  1772  		t.Fatalf("bad: %v", nodes)
  1773  	}
  1774  	if nodes[2].Node != "foo" {
  1775  		t.Fatalf("bad: %v", nodes)
  1776  	}
  1777  	if nodes[2].Address != "127.0.0.1" {
  1778  		t.Fatalf("bad: %v", nodes)
  1779  	}
  1780  	if nodes[2].ServiceID != "db" {
  1781  		t.Fatalf("bad: %v", nodes)
  1782  	}
  1783  	if !lib.StrContains(nodes[2].ServiceTags, "master") {
  1784  		t.Fatalf("bad: %v", nodes)
  1785  	}
  1786  	if nodes[2].ServicePort != 8000 {
  1787  		t.Fatalf("bad: %v", nodes)
  1788  	}
  1789  
  1790  	// Registering some unrelated node should not fire the watch.
  1791  	testRegisterNode(t, s, 17, "nope")
  1792  	if watchFired(ws) {
  1793  		t.Fatalf("bad")
  1794  	}
  1795  
  1796  	// But removing a node with the "db" service should fire the watch.
  1797  	if err := s.DeleteNode(18, "bar"); err != nil {
  1798  		t.Fatalf("err: %s", err)
  1799  	}
  1800  	if !watchFired(ws) {
  1801  		t.Fatalf("bad")
  1802  	}
  1803  
  1804  	// Overwhelm the node tracking.
  1805  	idx = 19
  1806  	for i := 0; i < 2*watchLimit; i++ {
  1807  		node := fmt.Sprintf("many%d", i)
  1808  		if err := s.EnsureNode(idx, &structs.Node{Node: node, Address: "127.0.0.1"}); err != nil {
  1809  			t.Fatalf("err: %v", err)
  1810  		}
  1811  		if err := s.EnsureService(idx, node, &structs.NodeService{ID: "db", Service: "db", Port: 8000}); err != nil {
  1812  			t.Fatalf("err: %v", err)
  1813  		}
  1814  		idx++
  1815  	}
  1816  
  1817  	// Now get a fresh watch, which will be forced to watch the whole nodes
  1818  	// table.
  1819  	ws = memdb.NewWatchSet()
  1820  	_, _, err = s.ServiceNodes(ws, "db")
  1821  	if err != nil {
  1822  		t.Fatalf("err: %s", err)
  1823  	}
  1824  
  1825  	// Registering some unrelated node should fire the watch now.
  1826  	testRegisterNode(t, s, idx, "more-nope")
  1827  	if !watchFired(ws) {
  1828  		t.Fatalf("bad")
  1829  	}
  1830  }
  1831  
  1832  func TestStateStore_ServiceTagNodes(t *testing.T) {
  1833  	s := testStateStore(t)
  1834  
  1835  	// Listing with no results returns an empty list.
  1836  	ws := memdb.NewWatchSet()
  1837  	idx, nodes, err := s.ServiceTagNodes(ws, "db", []string{"master"})
  1838  	if err != nil {
  1839  		t.Fatalf("err: %s", err)
  1840  	}
  1841  	if idx != 0 {
  1842  		t.Fatalf("bad: %d", idx)
  1843  	}
  1844  	if len(nodes) != 0 {
  1845  		t.Fatalf("bad: %v", nodes)
  1846  	}
  1847  
  1848  	// Create some nodes and services.
  1849  	if err := s.EnsureNode(15, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
  1850  		t.Fatalf("err: %v", err)
  1851  	}
  1852  	if err := s.EnsureNode(16, &structs.Node{Node: "bar", Address: "127.0.0.2"}); err != nil {
  1853  		t.Fatalf("err: %v", err)
  1854  	}
  1855  	if err := s.EnsureService(17, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"master"}, Address: "", Port: 8000}); err != nil {
  1856  		t.Fatalf("err: %v", err)
  1857  	}
  1858  	if err := s.EnsureService(18, "foo", &structs.NodeService{ID: "db2", Service: "db", Tags: []string{"slave"}, Address: "", Port: 8001}); err != nil {
  1859  		t.Fatalf("err: %v", err)
  1860  	}
  1861  	if err := s.EnsureService(19, "bar", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"slave"}, Address: "", Port: 8000}); err != nil {
  1862  		t.Fatalf("err: %v", err)
  1863  	}
  1864  	if !watchFired(ws) {
  1865  		t.Fatalf("bad")
  1866  	}
  1867  
  1868  	// Read everything back.
  1869  	ws = memdb.NewWatchSet()
  1870  	idx, nodes, err = s.ServiceTagNodes(ws, "db", []string{"master"})
  1871  	if err != nil {
  1872  		t.Fatalf("err: %s", err)
  1873  	}
  1874  	if idx != 19 {
  1875  		t.Fatalf("bad: %v", idx)
  1876  	}
  1877  	if len(nodes) != 1 {
  1878  		t.Fatalf("bad: %v", nodes)
  1879  	}
  1880  	if nodes[0].Node != "foo" {
  1881  		t.Fatalf("bad: %v", nodes)
  1882  	}
  1883  	if nodes[0].Address != "127.0.0.1" {
  1884  		t.Fatalf("bad: %v", nodes)
  1885  	}
  1886  	if !lib.StrContains(nodes[0].ServiceTags, "master") {
  1887  		t.Fatalf("bad: %v", nodes)
  1888  	}
  1889  	if nodes[0].ServicePort != 8000 {
  1890  		t.Fatalf("bad: %v", nodes)
  1891  	}
  1892  
  1893  	// Registering some unrelated node should not fire the watch.
  1894  	testRegisterNode(t, s, 20, "nope")
  1895  	if watchFired(ws) {
  1896  		t.Fatalf("bad")
  1897  	}
  1898  
  1899  	// But removing a node with the "db:master" service should fire the watch.
  1900  	if err := s.DeleteNode(21, "foo"); err != nil {
  1901  		t.Fatalf("err: %s", err)
  1902  	}
  1903  	if !watchFired(ws) {
  1904  		t.Fatalf("bad")
  1905  	}
  1906  }
  1907  
  1908  func TestStateStore_ServiceTagNodes_MultipleTags(t *testing.T) {
  1909  	s := testStateStore(t)
  1910  
  1911  	if err := s.EnsureNode(15, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
  1912  		t.Fatalf("err: %v", err)
  1913  	}
  1914  
  1915  	if err := s.EnsureNode(16, &structs.Node{Node: "bar", Address: "127.0.0.2"}); err != nil {
  1916  		t.Fatalf("err: %v", err)
  1917  	}
  1918  
  1919  	if err := s.EnsureService(17, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"master", "v2"}, Address: "", Port: 8000}); err != nil {
  1920  		t.Fatalf("err: %v", err)
  1921  	}
  1922  
  1923  	if err := s.EnsureService(18, "foo", &structs.NodeService{ID: "db2", Service: "db", Tags: []string{"slave", "v2", "dev"}, Address: "", Port: 8001}); err != nil {
  1924  		t.Fatalf("err: %v", err)
  1925  	}
  1926  
  1927  	if err := s.EnsureService(19, "bar", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"slave", "v2"}, Address: "", Port: 8000}); err != nil {
  1928  		t.Fatalf("err: %v", err)
  1929  	}
  1930  
  1931  	idx, nodes, err := s.ServiceTagNodes(nil, "db", []string{"master"})
  1932  	require.NoError(t, err)
  1933  	require.Equal(t, int(idx), 19)
  1934  	require.Len(t, nodes, 1)
  1935  	require.Equal(t, nodes[0].Node, "foo")
  1936  	require.Equal(t, nodes[0].Address, "127.0.0.1")
  1937  	require.Contains(t, nodes[0].ServiceTags, "master")
  1938  	require.Equal(t, nodes[0].ServicePort, 8000)
  1939  
  1940  	idx, nodes, err = s.ServiceTagNodes(nil, "db", []string{"v2"})
  1941  	require.NoError(t, err)
  1942  	require.Equal(t, int(idx), 19)
  1943  	require.Len(t, nodes, 3)
  1944  
  1945  	// Test filtering on multiple tags
  1946  	idx, nodes, err = s.ServiceTagNodes(nil, "db", []string{"v2", "slave"})
  1947  	require.NoError(t, err)
  1948  	require.Equal(t, int(idx), 19)
  1949  	require.Len(t, nodes, 2)
  1950  	require.Contains(t, nodes[0].ServiceTags, "v2")
  1951  	require.Contains(t, nodes[0].ServiceTags, "slave")
  1952  	require.Contains(t, nodes[1].ServiceTags, "v2")
  1953  	require.Contains(t, nodes[1].ServiceTags, "slave")
  1954  
  1955  	idx, nodes, err = s.ServiceTagNodes(nil, "db", []string{"dev"})
  1956  	require.NoError(t, err)
  1957  	require.Equal(t, int(idx), 19)
  1958  	require.Len(t, nodes, 1)
  1959  	require.Equal(t, nodes[0].Node, "foo")
  1960  	require.Equal(t, nodes[0].Address, "127.0.0.1")
  1961  	require.Contains(t, nodes[0].ServiceTags, "dev")
  1962  	require.Equal(t, nodes[0].ServicePort, 8001)
  1963  }
  1964  
  1965  func TestStateStore_DeleteService(t *testing.T) {
  1966  	s := testStateStore(t)
  1967  
  1968  	// Register a node with one service and a check.
  1969  	testRegisterNode(t, s, 1, "node1")
  1970  	testRegisterService(t, s, 2, "node1", "service1")
  1971  	testRegisterCheck(t, s, 3, "node1", "service1", "check1", api.HealthPassing)
  1972  
  1973  	// Delete the service.
  1974  	ws := memdb.NewWatchSet()
  1975  	_, _, err := s.NodeServices(ws, "node1")
  1976  	if err := s.DeleteService(4, "node1", "service1"); err != nil {
  1977  		t.Fatalf("err: %s", err)
  1978  	}
  1979  	if !watchFired(ws) {
  1980  		t.Fatalf("bad")
  1981  	}
  1982  
  1983  	// Service doesn't exist.
  1984  	ws = memdb.NewWatchSet()
  1985  	_, ns, err := s.NodeServices(ws, "node1")
  1986  	if err != nil || ns == nil || len(ns.Services) != 0 {
  1987  		t.Fatalf("bad: %#v (err: %#v)", ns, err)
  1988  	}
  1989  
  1990  	// Check doesn't exist. Check using the raw DB so we can test
  1991  	// that it actually is removed in the state store.
  1992  	tx := s.db.Txn(false)
  1993  	defer tx.Abort()
  1994  	check, err := tx.First("checks", "id", "node1", "check1")
  1995  	if err != nil || check != nil {
  1996  		t.Fatalf("bad: %#v (err: %s)", check, err)
  1997  	}
  1998  
  1999  	// Index tables were updated.
  2000  	if idx := s.maxIndex("services"); idx != 4 {
  2001  		t.Fatalf("bad index: %d", idx)
  2002  	}
  2003  	if idx := s.maxIndex("checks"); idx != 4 {
  2004  		t.Fatalf("bad index: %d", idx)
  2005  	}
  2006  
  2007  	// Deleting a nonexistent service should be idempotent and not return an
  2008  	// error, nor fire a watch.
  2009  	if err := s.DeleteService(5, "node1", "service1"); err != nil {
  2010  		t.Fatalf("err: %s", err)
  2011  	}
  2012  	if idx := s.maxIndex("services"); idx != 4 {
  2013  		t.Fatalf("bad index: %d", idx)
  2014  	}
  2015  	if watchFired(ws) {
  2016  		t.Fatalf("bad")
  2017  	}
  2018  }
  2019  
  2020  func TestStateStore_ConnectServiceNodes(t *testing.T) {
  2021  	assert := assert.New(t)
  2022  	s := testStateStore(t)
  2023  
  2024  	// Listing with no results returns an empty list.
  2025  	ws := memdb.NewWatchSet()
  2026  	idx, nodes, err := s.ConnectServiceNodes(ws, "db")
  2027  	assert.Nil(err)
  2028  	assert.Equal(idx, uint64(0))
  2029  	assert.Len(nodes, 0)
  2030  
  2031  	// Create some nodes and services.
  2032  	assert.Nil(s.EnsureNode(10, &structs.Node{Node: "foo", Address: "127.0.0.1"}))
  2033  	assert.Nil(s.EnsureNode(11, &structs.Node{Node: "bar", Address: "127.0.0.2"}))
  2034  	assert.Nil(s.EnsureService(12, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: nil, Address: "", Port: 5000}))
  2035  	assert.Nil(s.EnsureService(13, "bar", &structs.NodeService{ID: "api", Service: "api", Tags: nil, Address: "", Port: 5000}))
  2036  	assert.Nil(s.EnsureService(14, "foo", &structs.NodeService{Kind: structs.ServiceKindConnectProxy, ID: "proxy", Service: "proxy", Proxy: structs.ConnectProxyConfig{DestinationServiceName: "db"}, Port: 8000}))
  2037  	assert.Nil(s.EnsureService(15, "bar", &structs.NodeService{Kind: structs.ServiceKindConnectProxy, ID: "proxy", Service: "proxy", Proxy: structs.ConnectProxyConfig{DestinationServiceName: "db"}, Port: 8000}))
  2038  	assert.Nil(s.EnsureService(16, "bar", &structs.NodeService{ID: "native-db", Service: "db", Connect: structs.ServiceConnect{Native: true}}))
  2039  	assert.Nil(s.EnsureService(17, "bar", &structs.NodeService{ID: "db2", Service: "db", Tags: []string{"slave"}, Address: "", Port: 8001}))
  2040  	assert.True(watchFired(ws))
  2041  
  2042  	// Read everything back.
  2043  	ws = memdb.NewWatchSet()
  2044  	idx, nodes, err = s.ConnectServiceNodes(ws, "db")
  2045  	assert.Nil(err)
  2046  	assert.Equal(idx, uint64(idx))
  2047  	assert.Len(nodes, 3)
  2048  
  2049  	for _, n := range nodes {
  2050  		assert.True(
  2051  			n.ServiceKind == structs.ServiceKindConnectProxy ||
  2052  				n.ServiceConnect.Native,
  2053  			"either proxy or connect native")
  2054  	}
  2055  
  2056  	// Registering some unrelated node should not fire the watch.
  2057  	testRegisterNode(t, s, 17, "nope")
  2058  	assert.False(watchFired(ws))
  2059  
  2060  	// But removing a node with the "db" service should fire the watch.
  2061  	assert.Nil(s.DeleteNode(18, "bar"))
  2062  	assert.True(watchFired(ws))
  2063  }
  2064  
  2065  func TestStateStore_Service_Snapshot(t *testing.T) {
  2066  	s := testStateStore(t)
  2067  
  2068  	// Register a node with two services.
  2069  	testRegisterNode(t, s, 0, "node1")
  2070  	ns := []*structs.NodeService{
  2071  		&structs.NodeService{
  2072  			ID:      "service1",
  2073  			Service: "redis",
  2074  			Tags:    []string{"prod"},
  2075  			Address: "1.1.1.1",
  2076  			Port:    1111,
  2077  			Weights: &structs.Weights{Passing: 1, Warning: 0},
  2078  		},
  2079  		&structs.NodeService{
  2080  			ID:      "service2",
  2081  			Service: "nomad",
  2082  			Tags:    []string{"dev"},
  2083  			Address: "1.1.1.2",
  2084  			Port:    1112,
  2085  			Weights: &structs.Weights{Passing: 1, Warning: 1},
  2086  		},
  2087  	}
  2088  	for i, svc := range ns {
  2089  		if err := s.EnsureService(uint64(i+1), "node1", svc); err != nil {
  2090  			t.Fatalf("err: %s", err)
  2091  		}
  2092  	}
  2093  
  2094  	// Create a second node/service to make sure node filtering works. This
  2095  	// will affect the index but not the dump.
  2096  	testRegisterNode(t, s, 3, "node2")
  2097  	testRegisterService(t, s, 4, "node2", "service2")
  2098  
  2099  	// Snapshot the service.
  2100  	snap := s.Snapshot()
  2101  	defer snap.Close()
  2102  
  2103  	// Alter the real state store.
  2104  	testRegisterService(t, s, 5, "node2", "service3")
  2105  
  2106  	// Verify the snapshot.
  2107  	if idx := snap.LastIndex(); idx != 4 {
  2108  		t.Fatalf("bad index: %d", idx)
  2109  	}
  2110  	services, err := snap.Services("node1")
  2111  	if err != nil {
  2112  		t.Fatalf("err: %s", err)
  2113  	}
  2114  	for i := 0; i < len(ns); i++ {
  2115  		svc := services.Next().(*structs.ServiceNode)
  2116  		if svc == nil {
  2117  			t.Fatalf("unexpected end of services")
  2118  		}
  2119  
  2120  		ns[i].CreateIndex, ns[i].ModifyIndex = uint64(i+1), uint64(i+1)
  2121  		if !reflect.DeepEqual(ns[i], svc.ToNodeService()) {
  2122  			t.Fatalf("bad: %#v != %#v", svc, ns[i])
  2123  		}
  2124  	}
  2125  	if services.Next() != nil {
  2126  		t.Fatalf("unexpected extra services")
  2127  	}
  2128  }
  2129  
  2130  func TestStateStore_EnsureCheck(t *testing.T) {
  2131  	s := testStateStore(t)
  2132  
  2133  	// Create a check associated with the node
  2134  	check := &structs.HealthCheck{
  2135  		Node:        "node1",
  2136  		CheckID:     "check1",
  2137  		Name:        "redis check",
  2138  		Status:      api.HealthPassing,
  2139  		Notes:       "test check",
  2140  		Output:      "aaa",
  2141  		ServiceID:   "service1",
  2142  		ServiceName: "redis",
  2143  	}
  2144  
  2145  	// Creating a check without a node returns error
  2146  	if err := s.EnsureCheck(1, check); err != ErrMissingNode {
  2147  		t.Fatalf("expected %#v, got: %#v", ErrMissingNode, err)
  2148  	}
  2149  
  2150  	// Register the node
  2151  	testRegisterNode(t, s, 1, "node1")
  2152  
  2153  	// Creating a check with a bad services returns error
  2154  	if err := s.EnsureCheck(1, check); err != ErrMissingService {
  2155  		t.Fatalf("expected: %#v, got: %#v", ErrMissingService, err)
  2156  	}
  2157  
  2158  	// Register the service
  2159  	testRegisterService(t, s, 2, "node1", "service1")
  2160  
  2161  	// Inserting the check with the prerequisites succeeds
  2162  	if err := s.EnsureCheck(3, check); err != nil {
  2163  		t.Fatalf("err: %s", err)
  2164  	}
  2165  
  2166  	// Retrieve the check and make sure it matches
  2167  	idx, checks, err := s.NodeChecks(nil, "node1")
  2168  	if err != nil {
  2169  		t.Fatalf("err: %s", err)
  2170  	}
  2171  	if idx != 3 {
  2172  		t.Fatalf("bad index: %d", idx)
  2173  	}
  2174  	if len(checks) != 1 {
  2175  		t.Fatalf("wrong number of checks: %d", len(checks))
  2176  	}
  2177  	if !reflect.DeepEqual(checks[0], check) {
  2178  		t.Fatalf("bad: %#v", checks[0])
  2179  	}
  2180  
  2181  	testCheckOutput := func(expectedNodeIndex, expectedIndexForCheck uint64, outputTxt string) {
  2182  		// Check that we successfully updated
  2183  		idx, checks, err = s.NodeChecks(nil, "node1")
  2184  		if err != nil {
  2185  			t.Fatalf("err: %s", err)
  2186  		}
  2187  		if idx != expectedNodeIndex {
  2188  			t.Fatalf("bad index: %d", idx)
  2189  		}
  2190  
  2191  		if len(checks) != 1 {
  2192  			t.Fatalf("wrong number of checks: %d", len(checks))
  2193  		}
  2194  		if checks[0].Output != outputTxt {
  2195  			t.Fatalf("wrong check output: %#v", checks[0])
  2196  		}
  2197  		if checks[0].CreateIndex != 3 || checks[0].ModifyIndex != expectedIndexForCheck {
  2198  			t.Fatalf("bad index: %#v, expectedIndexForCheck:=%v ", checks[0], expectedIndexForCheck)
  2199  		}
  2200  	}
  2201  	// Do not really modify the health check content the health check
  2202  	check = &structs.HealthCheck{
  2203  		Node:        "node1",
  2204  		CheckID:     "check1",
  2205  		Name:        "redis check",
  2206  		Status:      api.HealthPassing,
  2207  		Notes:       "test check",
  2208  		Output:      "aaa",
  2209  		ServiceID:   "service1",
  2210  		ServiceName: "redis",
  2211  	}
  2212  	if err := s.EnsureCheck(4, check); err != nil {
  2213  		t.Fatalf("err: %s", err)
  2214  	}
  2215  	testCheckOutput(4, 3, check.Output)
  2216  
  2217  	// Do modify the heathcheck
  2218  	check = &structs.HealthCheck{
  2219  		Node:        "node1",
  2220  		CheckID:     "check1",
  2221  		Name:        "redis check",
  2222  		Status:      api.HealthPassing,
  2223  		Notes:       "test check",
  2224  		Output:      "bbbmodified",
  2225  		ServiceID:   "service1",
  2226  		ServiceName: "redis",
  2227  	}
  2228  	if err := s.EnsureCheck(5, check); err != nil {
  2229  		t.Fatalf("err: %s", err)
  2230  	}
  2231  	testCheckOutput(5, 5, "bbbmodified")
  2232  
  2233  	// Index tables were updated
  2234  	if idx := s.maxIndex("checks"); idx != 5 {
  2235  		t.Fatalf("bad index: %d", idx)
  2236  	}
  2237  }
  2238  
  2239  func TestStateStore_EnsureCheck_defaultStatus(t *testing.T) {
  2240  	s := testStateStore(t)
  2241  
  2242  	// Register a node
  2243  	testRegisterNode(t, s, 1, "node1")
  2244  
  2245  	// Create and register a check with no health status
  2246  	check := &structs.HealthCheck{
  2247  		Node:    "node1",
  2248  		CheckID: "check1",
  2249  		Status:  "",
  2250  	}
  2251  	if err := s.EnsureCheck(2, check); err != nil {
  2252  		t.Fatalf("err: %s", err)
  2253  	}
  2254  
  2255  	// Get the check again
  2256  	_, result, err := s.NodeChecks(nil, "node1")
  2257  	if err != nil {
  2258  		t.Fatalf("err: %s", err)
  2259  	}
  2260  
  2261  	// Check that the status was set to the proper default
  2262  	if len(result) != 1 || result[0].Status != api.HealthCritical {
  2263  		t.Fatalf("bad: %#v", result)
  2264  	}
  2265  }
  2266  
  2267  func TestStateStore_NodeChecks(t *testing.T) {
  2268  	s := testStateStore(t)
  2269  
  2270  	// Do an initial query for a node that doesn't exist.
  2271  	ws := memdb.NewWatchSet()
  2272  	idx, checks, err := s.NodeChecks(ws, "node1")
  2273  	if err != nil {
  2274  		t.Fatalf("err: %s", err)
  2275  	}
  2276  	if idx != 0 {
  2277  		t.Fatalf("bad: %d", idx)
  2278  	}
  2279  	if len(checks) != 0 {
  2280  		t.Fatalf("bad: %#v", checks)
  2281  	}
  2282  
  2283  	// Create some nodes and checks.
  2284  	testRegisterNode(t, s, 0, "node1")
  2285  	testRegisterService(t, s, 1, "node1", "service1")
  2286  	testRegisterCheck(t, s, 2, "node1", "service1", "check1", api.HealthPassing)
  2287  	testRegisterCheck(t, s, 3, "node1", "service1", "check2", api.HealthPassing)
  2288  	testRegisterNode(t, s, 4, "node2")
  2289  	testRegisterService(t, s, 5, "node2", "service2")
  2290  	testRegisterCheck(t, s, 6, "node2", "service2", "check3", api.HealthPassing)
  2291  	if !watchFired(ws) {
  2292  		t.Fatalf("bad")
  2293  	}
  2294  
  2295  	// Try querying for all checks associated with node1
  2296  	ws = memdb.NewWatchSet()
  2297  	idx, checks, err = s.NodeChecks(ws, "node1")
  2298  	if err != nil {
  2299  		t.Fatalf("err: %s", err)
  2300  	}
  2301  	if idx != 6 {
  2302  		t.Fatalf("bad index: %d", idx)
  2303  	}
  2304  	if len(checks) != 2 || checks[0].CheckID != "check1" || checks[1].CheckID != "check2" {
  2305  		t.Fatalf("bad checks: %#v", checks)
  2306  	}
  2307  
  2308  	// Creating some unrelated node should not fire the watch.
  2309  	testRegisterNode(t, s, 7, "node3")
  2310  	testRegisterCheck(t, s, 8, "node3", "", "check1", api.HealthPassing)
  2311  	if watchFired(ws) {
  2312  		t.Fatalf("bad")
  2313  	}
  2314  
  2315  	// Try querying for all checks associated with node2
  2316  	ws = memdb.NewWatchSet()
  2317  	idx, checks, err = s.NodeChecks(ws, "node2")
  2318  	if err != nil {
  2319  		t.Fatalf("err: %s", err)
  2320  	}
  2321  	if idx != 8 {
  2322  		t.Fatalf("bad index: %d", idx)
  2323  	}
  2324  	if len(checks) != 1 || checks[0].CheckID != "check3" {
  2325  		t.Fatalf("bad checks: %#v", checks)
  2326  	}
  2327  
  2328  	// Changing node2 should fire the watch.
  2329  	testRegisterCheck(t, s, 9, "node2", "service2", "check3", api.HealthCritical)
  2330  	if !watchFired(ws) {
  2331  		t.Fatalf("bad")
  2332  	}
  2333  }
  2334  
  2335  func TestStateStore_ServiceChecks(t *testing.T) {
  2336  	s := testStateStore(t)
  2337  
  2338  	// Do an initial query for a service that doesn't exist.
  2339  	ws := memdb.NewWatchSet()
  2340  	idx, checks, err := s.ServiceChecks(ws, "service1")
  2341  	if err != nil {
  2342  		t.Fatalf("err: %s", err)
  2343  	}
  2344  	if idx != 0 {
  2345  		t.Fatalf("bad: %d", idx)
  2346  	}
  2347  	if len(checks) != 0 {
  2348  		t.Fatalf("bad: %#v", checks)
  2349  	}
  2350  
  2351  	// Create some nodes and checks.
  2352  	testRegisterNode(t, s, 0, "node1")
  2353  	testRegisterService(t, s, 1, "node1", "service1")
  2354  	testRegisterCheck(t, s, 2, "node1", "service1", "check1", api.HealthPassing)
  2355  	testRegisterCheck(t, s, 3, "node1", "service1", "check2", api.HealthPassing)
  2356  	testRegisterNode(t, s, 4, "node2")
  2357  	testRegisterService(t, s, 5, "node2", "service2")
  2358  	testRegisterCheck(t, s, 6, "node2", "service2", "check3", api.HealthPassing)
  2359  	if !watchFired(ws) {
  2360  		t.Fatalf("bad")
  2361  	}
  2362  
  2363  	// Try querying for all checks associated with service1.
  2364  	ws = memdb.NewWatchSet()
  2365  	idx, checks, err = s.ServiceChecks(ws, "service1")
  2366  	if err != nil {
  2367  		t.Fatalf("err: %s", err)
  2368  	}
  2369  	if idx != 6 {
  2370  		t.Fatalf("bad index: %d", idx)
  2371  	}
  2372  	if len(checks) != 2 || checks[0].CheckID != "check1" || checks[1].CheckID != "check2" {
  2373  		t.Fatalf("bad checks: %#v", checks)
  2374  	}
  2375  
  2376  	// Adding some unrelated service + check should not fire the watch.
  2377  	testRegisterService(t, s, 7, "node1", "service3")
  2378  	testRegisterCheck(t, s, 8, "node1", "service3", "check3", api.HealthPassing)
  2379  	if watchFired(ws) {
  2380  		t.Fatalf("bad")
  2381  	}
  2382  
  2383  	// Updating a related check should fire the watch.
  2384  	testRegisterCheck(t, s, 9, "node1", "service1", "check2", api.HealthCritical)
  2385  	if !watchFired(ws) {
  2386  		t.Fatalf("bad")
  2387  	}
  2388  }
  2389  
  2390  func TestStateStore_ServiceChecksByNodeMeta(t *testing.T) {
  2391  	s := testStateStore(t)
  2392  
  2393  	// Querying with no results returns nil.
  2394  	ws := memdb.NewWatchSet()
  2395  	idx, checks, err := s.ServiceChecksByNodeMeta(ws, "service1", nil)
  2396  	if err != nil {
  2397  		t.Fatalf("err: %s", err)
  2398  	}
  2399  	if idx != 0 {
  2400  		t.Fatalf("bad: %d", idx)
  2401  	}
  2402  	if len(checks) != 0 {
  2403  		t.Fatalf("bad: %#v", checks)
  2404  	}
  2405  
  2406  	// Create some nodes and checks.
  2407  	testRegisterNodeWithMeta(t, s, 0, "node1", map[string]string{"somekey": "somevalue", "common": "1"})
  2408  	testRegisterService(t, s, 1, "node1", "service1")
  2409  	testRegisterCheck(t, s, 2, "node1", "service1", "check1", api.HealthPassing)
  2410  	testRegisterCheck(t, s, 3, "node1", "service1", "check2", api.HealthPassing)
  2411  	testRegisterNodeWithMeta(t, s, 4, "node2", map[string]string{"common": "1"})
  2412  	testRegisterService(t, s, 5, "node2", "service1")
  2413  	testRegisterCheck(t, s, 6, "node2", "service1", "check3", api.HealthPassing)
  2414  	if !watchFired(ws) {
  2415  		t.Fatalf("bad")
  2416  	}
  2417  
  2418  	cases := []struct {
  2419  		filters map[string]string
  2420  		checks  []string
  2421  	}{
  2422  		// Basic meta filter
  2423  		{
  2424  			filters: map[string]string{"somekey": "somevalue"},
  2425  			checks:  []string{"check1", "check2"},
  2426  		},
  2427  		// Common meta field
  2428  		{
  2429  			filters: map[string]string{"common": "1"},
  2430  			checks:  []string{"check1", "check2", "check3"},
  2431  		},
  2432  		// Invalid meta filter
  2433  		{
  2434  			filters: map[string]string{"invalid": "nope"},
  2435  			checks:  []string{},
  2436  		},
  2437  		// Multiple filters
  2438  		{
  2439  			filters: map[string]string{"somekey": "somevalue", "common": "1"},
  2440  			checks:  []string{"check1", "check2"},
  2441  		},
  2442  	}
  2443  
  2444  	// Try querying for all checks associated with service1.
  2445  	idx = 7
  2446  	for _, tc := range cases {
  2447  		ws = memdb.NewWatchSet()
  2448  		_, checks, err := s.ServiceChecksByNodeMeta(ws, "service1", tc.filters)
  2449  		if err != nil {
  2450  			t.Fatalf("err: %s", err)
  2451  		}
  2452  		if len(checks) != len(tc.checks) {
  2453  			t.Fatalf("bad checks: %#v", checks)
  2454  		}
  2455  		for i, check := range checks {
  2456  			if check.CheckID != types.CheckID(tc.checks[i]) {
  2457  				t.Fatalf("bad checks: %#v", checks)
  2458  			}
  2459  		}
  2460  
  2461  		// Registering some unrelated node should not fire the watch.
  2462  		testRegisterNode(t, s, idx, fmt.Sprintf("nope%d", idx))
  2463  		idx++
  2464  		if watchFired(ws) {
  2465  			t.Fatalf("bad")
  2466  		}
  2467  	}
  2468  
  2469  	// Overwhelm the node tracking.
  2470  	for i := 0; i < 2*watchLimit; i++ {
  2471  		node := fmt.Sprintf("many%d", idx)
  2472  		testRegisterNodeWithMeta(t, s, idx, node, map[string]string{"common": "1"})
  2473  		idx++
  2474  		testRegisterService(t, s, idx, node, "service1")
  2475  		idx++
  2476  		testRegisterCheck(t, s, idx, node, "service1", "check1", api.HealthPassing)
  2477  		idx++
  2478  	}
  2479  
  2480  	// Now get a fresh watch, which will be forced to watch the whole
  2481  	// node table.
  2482  	ws = memdb.NewWatchSet()
  2483  	_, _, err = s.ServiceChecksByNodeMeta(ws, "service1",
  2484  		map[string]string{"common": "1"})
  2485  	if err != nil {
  2486  		t.Fatalf("err: %s", err)
  2487  	}
  2488  
  2489  	// Registering some unrelated node should now fire the watch.
  2490  	testRegisterNode(t, s, idx, "nope")
  2491  	if !watchFired(ws) {
  2492  		t.Fatalf("bad")
  2493  	}
  2494  }
  2495  
  2496  func TestStateStore_ChecksInState(t *testing.T) {
  2497  	s := testStateStore(t)
  2498  
  2499  	// Querying with no results returns nil
  2500  	ws := memdb.NewWatchSet()
  2501  	idx, res, err := s.ChecksInState(ws, api.HealthPassing)
  2502  	if idx != 0 || res != nil || err != nil {
  2503  		t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, res, err)
  2504  	}
  2505  
  2506  	// Register a node with checks in varied states
  2507  	testRegisterNode(t, s, 0, "node1")
  2508  	testRegisterCheck(t, s, 1, "node1", "", "check1", api.HealthPassing)
  2509  	testRegisterCheck(t, s, 2, "node1", "", "check2", api.HealthCritical)
  2510  	testRegisterCheck(t, s, 3, "node1", "", "check3", api.HealthPassing)
  2511  	if !watchFired(ws) {
  2512  		t.Fatalf("bad")
  2513  	}
  2514  
  2515  	// Query the state store for passing checks.
  2516  	ws = memdb.NewWatchSet()
  2517  	_, checks, err := s.ChecksInState(ws, api.HealthPassing)
  2518  	if err != nil {
  2519  		t.Fatalf("err: %s", err)
  2520  	}
  2521  
  2522  	// Make sure we only get the checks which match the state
  2523  	if n := len(checks); n != 2 {
  2524  		t.Fatalf("expected 2 checks, got: %d", n)
  2525  	}
  2526  	if checks[0].CheckID != "check1" || checks[1].CheckID != "check3" {
  2527  		t.Fatalf("bad: %#v", checks)
  2528  	}
  2529  	if watchFired(ws) {
  2530  		t.Fatalf("bad")
  2531  	}
  2532  
  2533  	// Changing the state of a check should fire the watch.
  2534  	testRegisterCheck(t, s, 4, "node1", "", "check1", api.HealthCritical)
  2535  	if !watchFired(ws) {
  2536  		t.Fatalf("bad")
  2537  	}
  2538  
  2539  	// HealthAny just returns everything.
  2540  	ws = memdb.NewWatchSet()
  2541  	_, checks, err = s.ChecksInState(ws, api.HealthAny)
  2542  	if err != nil {
  2543  		t.Fatalf("err: %s", err)
  2544  	}
  2545  	if n := len(checks); n != 3 {
  2546  		t.Fatalf("expected 3 checks, got: %d", n)
  2547  	}
  2548  	if watchFired(ws) {
  2549  		t.Fatalf("bad")
  2550  	}
  2551  
  2552  	// Adding a new check should fire the watch.
  2553  	testRegisterCheck(t, s, 5, "node1", "", "check4", api.HealthCritical)
  2554  	if !watchFired(ws) {
  2555  		t.Fatalf("bad")
  2556  	}
  2557  }
  2558  
  2559  func TestStateStore_ChecksInStateByNodeMeta(t *testing.T) {
  2560  	s := testStateStore(t)
  2561  
  2562  	// Querying with no results returns nil.
  2563  	ws := memdb.NewWatchSet()
  2564  	idx, res, err := s.ChecksInStateByNodeMeta(ws, api.HealthPassing, nil)
  2565  	if idx != 0 || res != nil || err != nil {
  2566  		t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, res, err)
  2567  	}
  2568  
  2569  	// Register a node with checks in varied states.
  2570  	testRegisterNodeWithMeta(t, s, 0, "node1", map[string]string{"somekey": "somevalue", "common": "1"})
  2571  	testRegisterCheck(t, s, 1, "node1", "", "check1", api.HealthPassing)
  2572  	testRegisterCheck(t, s, 2, "node1", "", "check2", api.HealthCritical)
  2573  	testRegisterNodeWithMeta(t, s, 3, "node2", map[string]string{"common": "1"})
  2574  	testRegisterCheck(t, s, 4, "node2", "", "check3", api.HealthPassing)
  2575  	if !watchFired(ws) {
  2576  		t.Fatalf("bad")
  2577  	}
  2578  
  2579  	cases := []struct {
  2580  		filters map[string]string
  2581  		state   string
  2582  		checks  []string
  2583  	}{
  2584  		// Basic meta filter, any status
  2585  		{
  2586  			filters: map[string]string{"somekey": "somevalue"},
  2587  			state:   api.HealthAny,
  2588  			checks:  []string{"check2", "check1"},
  2589  		},
  2590  		// Basic meta filter, only passing
  2591  		{
  2592  			filters: map[string]string{"somekey": "somevalue"},
  2593  			state:   api.HealthPassing,
  2594  			checks:  []string{"check1"},
  2595  		},
  2596  		// Common meta filter, any status
  2597  		{
  2598  			filters: map[string]string{"common": "1"},
  2599  			state:   api.HealthAny,
  2600  			checks:  []string{"check2", "check1", "check3"},
  2601  		},
  2602  		// Common meta filter, only passing
  2603  		{
  2604  			filters: map[string]string{"common": "1"},
  2605  			state:   api.HealthPassing,
  2606  			checks:  []string{"check1", "check3"},
  2607  		},
  2608  		// Invalid meta filter
  2609  		{
  2610  			filters: map[string]string{"invalid": "nope"},
  2611  			checks:  []string{},
  2612  		},
  2613  		// Multiple filters, any status
  2614  		{
  2615  			filters: map[string]string{"somekey": "somevalue", "common": "1"},
  2616  			state:   api.HealthAny,
  2617  			checks:  []string{"check2", "check1"},
  2618  		},
  2619  		// Multiple filters, only passing
  2620  		{
  2621  			filters: map[string]string{"somekey": "somevalue", "common": "1"},
  2622  			state:   api.HealthPassing,
  2623  			checks:  []string{"check1"},
  2624  		},
  2625  	}
  2626  
  2627  	// Try querying for all checks associated with service1.
  2628  	idx = 5
  2629  	for _, tc := range cases {
  2630  		ws = memdb.NewWatchSet()
  2631  		_, checks, err := s.ChecksInStateByNodeMeta(ws, tc.state, tc.filters)
  2632  		if err != nil {
  2633  			t.Fatalf("err: %s", err)
  2634  		}
  2635  		if len(checks) != len(tc.checks) {
  2636  			t.Fatalf("bad checks: %#v", checks)
  2637  		}
  2638  		for i, check := range checks {
  2639  			if check.CheckID != types.CheckID(tc.checks[i]) {
  2640  				t.Fatalf("bad checks: %#v, %v", checks, tc.checks)
  2641  			}
  2642  		}
  2643  
  2644  		// Registering some unrelated node should not fire the watch.
  2645  		testRegisterNode(t, s, idx, fmt.Sprintf("nope%d", idx))
  2646  		idx++
  2647  		if watchFired(ws) {
  2648  			t.Fatalf("bad")
  2649  		}
  2650  	}
  2651  
  2652  	// Overwhelm the node tracking.
  2653  	for i := 0; i < 2*watchLimit; i++ {
  2654  		node := fmt.Sprintf("many%d", idx)
  2655  		testRegisterNodeWithMeta(t, s, idx, node, map[string]string{"common": "1"})
  2656  		idx++
  2657  		testRegisterService(t, s, idx, node, "service1")
  2658  		idx++
  2659  		testRegisterCheck(t, s, idx, node, "service1", "check1", api.HealthPassing)
  2660  		idx++
  2661  	}
  2662  
  2663  	// Now get a fresh watch, which will be forced to watch the whole
  2664  	// node table.
  2665  	ws = memdb.NewWatchSet()
  2666  	_, _, err = s.ChecksInStateByNodeMeta(ws, api.HealthPassing,
  2667  		map[string]string{"common": "1"})
  2668  	if err != nil {
  2669  		t.Fatalf("err: %s", err)
  2670  	}
  2671  
  2672  	// Registering some unrelated node should now fire the watch.
  2673  	testRegisterNode(t, s, idx, "nope")
  2674  	if !watchFired(ws) {
  2675  		t.Fatalf("bad")
  2676  	}
  2677  }
  2678  
  2679  func TestStateStore_DeleteCheck(t *testing.T) {
  2680  	s := testStateStore(t)
  2681  
  2682  	// Register a node and a node-level health check.
  2683  	testRegisterNode(t, s, 1, "node1")
  2684  	testRegisterCheck(t, s, 2, "node1", "", "check1", api.HealthPassing)
  2685  	testRegisterService(t, s, 2, "node1", "service1")
  2686  
  2687  	// Make sure the check is there.
  2688  	ws := memdb.NewWatchSet()
  2689  	_, checks, err := s.NodeChecks(ws, "node1")
  2690  	if err != nil {
  2691  		t.Fatalf("err: %s", err)
  2692  	}
  2693  	if len(checks) != 1 {
  2694  		t.Fatalf("bad: %#v", checks)
  2695  	}
  2696  
  2697  	ensureServiceVersion(t, s, ws, "service1", 2, 1)
  2698  
  2699  	// Delete the check.
  2700  	if err := s.DeleteCheck(3, "node1", "check1"); err != nil {
  2701  		t.Fatalf("err: %s", err)
  2702  	}
  2703  	if idx, check, err := s.NodeCheck("node1", "check1"); idx != 3 || err != nil || check != nil {
  2704  		t.Fatalf("Node check should have been deleted idx=%d, node=%v, err=%s", idx, check, err)
  2705  	}
  2706  	if idx := s.maxIndex("checks"); idx != 3 {
  2707  		t.Fatalf("bad index for checks: %d", idx)
  2708  	}
  2709  	if !watchFired(ws) {
  2710  		t.Fatalf("bad")
  2711  	}
  2712  	// All services linked to this node should have their index updated
  2713  	ensureServiceVersion(t, s, ws, "service1", 3, 1)
  2714  
  2715  	// Check is gone
  2716  	ws = memdb.NewWatchSet()
  2717  	_, checks, err = s.NodeChecks(ws, "node1")
  2718  	if err != nil {
  2719  		t.Fatalf("err: %s", err)
  2720  	}
  2721  	if len(checks) != 0 {
  2722  		t.Fatalf("bad: %#v", checks)
  2723  	}
  2724  
  2725  	// Index tables were updated.
  2726  	if idx := s.maxIndex("checks"); idx != 3 {
  2727  		t.Fatalf("bad index: %d", idx)
  2728  	}
  2729  
  2730  	// Deleting a nonexistent check should be idempotent and not return an
  2731  	// error.
  2732  	if err := s.DeleteCheck(4, "node1", "check1"); err != nil {
  2733  		t.Fatalf("err: %s", err)
  2734  	}
  2735  	if idx := s.maxIndex("checks"); idx != 3 {
  2736  		t.Fatalf("bad index: %d", idx)
  2737  	}
  2738  	if watchFired(ws) {
  2739  		t.Fatalf("bad")
  2740  	}
  2741  }
  2742  
  2743  func ensureServiceVersion(t *testing.T, s *Store, ws memdb.WatchSet, serviceID string, expectedIdx uint64, expectedSize int) {
  2744  	idx, services, err := s.ServiceNodes(ws, serviceID)
  2745  	t.Helper()
  2746  	if err != nil {
  2747  		t.Fatalf("err: %s", err)
  2748  	}
  2749  	if idx != expectedIdx {
  2750  		t.Fatalf("bad: %d, expected %d", idx, expectedIdx)
  2751  	}
  2752  	if len(services) != expectedSize {
  2753  		t.Fatalf("expected size: %d, but was %d", expectedSize, len(services))
  2754  	}
  2755  }
  2756  
  2757  // Ensure index exist, if expectedIndex = -1, ensure the index does not exists
  2758  func ensureIndexForService(t *testing.T, s *Store, ws memdb.WatchSet, serviceName string, expectedIndex uint64) {
  2759  	t.Helper()
  2760  	tx := s.db.Txn(false)
  2761  	defer tx.Abort()
  2762  	transaction, err := tx.First("index", "id", fmt.Sprintf("service.%s", serviceName))
  2763  	if err == nil {
  2764  		if idx, ok := transaction.(*IndexEntry); ok {
  2765  			if expectedIndex != idx.Value {
  2766  				t.Fatalf("Expected index %d, but had %d for %s", expectedIndex, idx.Value, serviceName)
  2767  			}
  2768  			return
  2769  		}
  2770  	}
  2771  	if expectedIndex != 0 {
  2772  		t.Fatalf("Index for %s was expected but not found", serviceName)
  2773  	}
  2774  }
  2775  
  2776  // TestIndexIndependence test that changes on a given service does not impact the
  2777  // index of other services. It allows to have huge benefits for watches since
  2778  // watchers are notified ONLY when there are changes in the given service
  2779  func TestIndexIndependence(t *testing.T) {
  2780  	s := testStateStore(t)
  2781  
  2782  	// Querying with no matches gives an empty response
  2783  	ws := memdb.NewWatchSet()
  2784  	idx, res, err := s.CheckServiceNodes(ws, "service1")
  2785  	if idx != 0 || res != nil || err != nil {
  2786  		t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, res, err)
  2787  	}
  2788  
  2789  	// Register some nodes.
  2790  	testRegisterNode(t, s, 0, "node1")
  2791  	testRegisterNode(t, s, 1, "node2")
  2792  
  2793  	// Register node-level checks. These should be the final result.
  2794  	testRegisterCheck(t, s, 2, "node1", "", "check1", api.HealthPassing)
  2795  	testRegisterCheck(t, s, 3, "node2", "", "check2", api.HealthPassing)
  2796  
  2797  	// Register a service against the nodes.
  2798  	testRegisterService(t, s, 4, "node1", "service1")
  2799  	testRegisterService(t, s, 5, "node2", "service2")
  2800  	ensureServiceVersion(t, s, ws, "service2", 5, 1)
  2801  
  2802  	// Register checks against the services.
  2803  	testRegisterCheck(t, s, 6, "node1", "service1", "check3", api.HealthPassing)
  2804  	testRegisterCheck(t, s, 7, "node2", "service2", "check4", api.HealthPassing)
  2805  	// Index must be updated when checks are updated
  2806  	ensureServiceVersion(t, s, ws, "service1", 6, 1)
  2807  	ensureServiceVersion(t, s, ws, "service2", 7, 1)
  2808  
  2809  	if !watchFired(ws) {
  2810  		t.Fatalf("bad")
  2811  	}
  2812  	// We ensure the idx for service2 has not been changed
  2813  	testRegisterCheck(t, s, 8, "node2", "service2", "check4", api.HealthWarning)
  2814  	ensureServiceVersion(t, s, ws, "service2", 8, 1)
  2815  	testRegisterCheck(t, s, 9, "node2", "service2", "check4", api.HealthPassing)
  2816  	ensureServiceVersion(t, s, ws, "service2", 9, 1)
  2817  
  2818  	// Add a new check on node1, while not on service, it should impact
  2819  	// indexes of all services running on node1, aka service1
  2820  	testRegisterCheck(t, s, 10, "node1", "", "check_node", api.HealthPassing)
  2821  
  2822  	// Service2 should not be modified
  2823  	ensureServiceVersion(t, s, ws, "service2", 9, 1)
  2824  	// Service1 should be modified
  2825  	ensureServiceVersion(t, s, ws, "service1", 10, 1)
  2826  
  2827  	if !watchFired(ws) {
  2828  		t.Fatalf("bad")
  2829  	}
  2830  
  2831  	testRegisterService(t, s, 11, "node1", "service_shared")
  2832  	ensureServiceVersion(t, s, ws, "service_shared", 11, 1)
  2833  	testRegisterService(t, s, 12, "node2", "service_shared")
  2834  	ensureServiceVersion(t, s, ws, "service_shared", 12, 2)
  2835  
  2836  	testRegisterCheck(t, s, 13, "node2", "service_shared", "check_service_shared", api.HealthCritical)
  2837  	ensureServiceVersion(t, s, ws, "service_shared", 13, 2)
  2838  	testRegisterCheck(t, s, 14, "node2", "service_shared", "check_service_shared", api.HealthPassing)
  2839  	ensureServiceVersion(t, s, ws, "service_shared", 14, 2)
  2840  
  2841  	s.DeleteCheck(15, "node2", types.CheckID("check_service_shared"))
  2842  	ensureServiceVersion(t, s, ws, "service_shared", 15, 2)
  2843  	ensureIndexForService(t, s, ws, "service_shared", 15)
  2844  	s.DeleteService(16, "node2", "service_shared")
  2845  	ensureServiceVersion(t, s, ws, "service_shared", 16, 1)
  2846  	ensureIndexForService(t, s, ws, "service_shared", 16)
  2847  	s.DeleteService(17, "node1", "service_shared")
  2848  	ensureServiceVersion(t, s, ws, "service_shared", 17, 0)
  2849  
  2850  	testRegisterService(t, s, 18, "node1", "service_new")
  2851  
  2852  	// Since service does not exists anymore, its index should be that of
  2853  	// the last deleted service
  2854  	ensureServiceVersion(t, s, ws, "service_shared", 17, 0)
  2855  
  2856  	// No index should exist anymore, it must have been garbage collected
  2857  	ensureIndexForService(t, s, ws, "service_shared", 0)
  2858  	if !watchFired(ws) {
  2859  		t.Fatalf("bad")
  2860  	}
  2861  }
  2862  
  2863  func TestMissingServiceIndex(t *testing.T) {
  2864  	s := testStateStore(t)
  2865  
  2866  	// Querying with no matches gives an empty response
  2867  	ws := memdb.NewWatchSet()
  2868  	idx, res, err := s.CheckServiceNodes(ws, "service1")
  2869  	require.Nil(t, err)
  2870  	require.Nil(t, res)
  2871  
  2872  	// index should be 0 for a non existing service at startup
  2873  	require.Equal(t, uint64(0), idx)
  2874  
  2875  	testRegisterNode(t, s, 0, "node1")
  2876  
  2877  	// node operations should not affect missing service index
  2878  	ensureServiceVersion(t, s, ws, "service1", 0, 0)
  2879  
  2880  	testRegisterService(t, s, 10, "node1", "service1")
  2881  	ensureServiceVersion(t, s, ws, "service1", 10, 1)
  2882  
  2883  	s.DeleteService(11, "node1", "service1")
  2884  	// service1 is now missing, its index is now that of the last index a service was
  2885  	// deleted at
  2886  	ensureServiceVersion(t, s, ws, "service1", 11, 0)
  2887  
  2888  	testRegisterService(t, s, 12, "node1", "service2")
  2889  	ensureServiceVersion(t, s, ws, "service2", 12, 1)
  2890  
  2891  	// missing service index does not change even though another service have been
  2892  	// registered
  2893  	ensureServiceVersion(t, s, ws, "service1", 11, 0)
  2894  	ensureServiceVersion(t, s, ws, "i_do_not_exist", 11, 0)
  2895  
  2896  	// registering a service on another node does not affect missing service
  2897  	// index
  2898  	testRegisterNode(t, s, 13, "node2")
  2899  	testRegisterService(t, s, 14, "node2", "service3")
  2900  	ensureServiceVersion(t, s, ws, "service3", 14, 1)
  2901  	ensureServiceVersion(t, s, ws, "service1", 11, 0)
  2902  
  2903  	// unregistering a service bumps missing service index
  2904  	s.DeleteService(15, "node2", "service3")
  2905  	ensureServiceVersion(t, s, ws, "service3", 15, 0)
  2906  	ensureServiceVersion(t, s, ws, "service2", 12, 1)
  2907  	ensureServiceVersion(t, s, ws, "service1", 15, 0)
  2908  	ensureServiceVersion(t, s, ws, "i_do_not_exist", 15, 0)
  2909  
  2910  	// registering again a missing service correctly updates its index
  2911  	testRegisterService(t, s, 16, "node1", "service1")
  2912  	ensureServiceVersion(t, s, ws, "service1", 16, 1)
  2913  }
  2914  
  2915  func TestStateStore_CheckServiceNodes(t *testing.T) {
  2916  	s := testStateStore(t)
  2917  
  2918  	// Querying with no matches gives an empty response
  2919  	ws := memdb.NewWatchSet()
  2920  	idx, res, err := s.CheckServiceNodes(ws, "service1")
  2921  	if idx != 0 || res != nil || err != nil {
  2922  		t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, res, err)
  2923  	}
  2924  
  2925  	// Register some nodes.
  2926  	testRegisterNode(t, s, 0, "node1")
  2927  	testRegisterNode(t, s, 1, "node2")
  2928  
  2929  	// Register node-level checks. These should be the final result.
  2930  	testRegisterCheck(t, s, 2, "node1", "", "check1", api.HealthPassing)
  2931  	testRegisterCheck(t, s, 3, "node2", "", "check2", api.HealthPassing)
  2932  
  2933  	// Register a service against the nodes.
  2934  	testRegisterService(t, s, 4, "node1", "service1")
  2935  	testRegisterService(t, s, 5, "node2", "service2")
  2936  
  2937  	// Register checks against the services.
  2938  	testRegisterCheck(t, s, 6, "node1", "service1", "check3", api.HealthPassing)
  2939  	testRegisterCheck(t, s, 7, "node2", "service2", "check4", api.HealthPassing)
  2940  
  2941  	// At this point all the changes should have fired the watch.
  2942  	if !watchFired(ws) {
  2943  		t.Fatalf("bad")
  2944  	}
  2945  
  2946  	// We ensure the idx for service2 has not been changed
  2947  	ensureServiceVersion(t, s, ws, "service2", 7, 1)
  2948  
  2949  	// Query the state store for nodes and checks which have been registered
  2950  	// with a specific service.
  2951  	ws = memdb.NewWatchSet()
  2952  	ensureServiceVersion(t, s, ws, "service1", 6, 1)
  2953  	idx, results, err := s.CheckServiceNodes(ws, "service1")
  2954  	if err != nil {
  2955  		t.Fatalf("err: %s", err)
  2956  	}
  2957  	// registered with ensureServiceVersion(t, s, ws, "service1", 6, 1)
  2958  	if idx != 6 {
  2959  		t.Fatalf("bad index: %d", idx)
  2960  	}
  2961  
  2962  	// Make sure we get the expected result (service check + node check).
  2963  	if n := len(results); n != 1 {
  2964  		t.Fatalf("expected 1 result, got: %d", n)
  2965  	}
  2966  	csn := results[0]
  2967  	if csn.Node == nil || csn.Service == nil || len(csn.Checks) != 2 ||
  2968  		csn.Checks[0].ServiceID != "" || csn.Checks[0].CheckID != "check1" ||
  2969  		csn.Checks[1].ServiceID != "service1" || csn.Checks[1].CheckID != "check3" {
  2970  		t.Fatalf("bad output: %#v", csn)
  2971  	}
  2972  
  2973  	// Node updates alter the returned index and fire the watch.
  2974  	testRegisterNodeWithChange(t, s, 8, "node1")
  2975  	if !watchFired(ws) {
  2976  		t.Fatalf("bad")
  2977  	}
  2978  	ws = memdb.NewWatchSet()
  2979  	idx, results, err = s.CheckServiceNodes(ws, "service1")
  2980  	if err != nil {
  2981  		t.Fatalf("err: %s", err)
  2982  	}
  2983  	// service1 has been updated by node on idx 8
  2984  	if idx != 8 {
  2985  		t.Fatalf("bad index: %d", idx)
  2986  	}
  2987  
  2988  	// Service updates alter the returned index and fire the watch.
  2989  
  2990  	testRegisterServiceWithChange(t, s, 9, "node1", "service1", true)
  2991  	if !watchFired(ws) {
  2992  		t.Fatalf("bad")
  2993  	}
  2994  	ws = memdb.NewWatchSet()
  2995  	idx, results, err = s.CheckServiceNodes(ws, "service1")
  2996  	if err != nil {
  2997  		t.Fatalf("err: %s", err)
  2998  	}
  2999  	if idx != 9 {
  3000  		t.Fatalf("bad index: %d", idx)
  3001  	}
  3002  
  3003  	// Check updates alter the returned index and fire the watch.
  3004  	testRegisterCheck(t, s, 10, "node1", "service1", "check1", api.HealthCritical)
  3005  	if !watchFired(ws) {
  3006  		t.Fatalf("bad")
  3007  	}
  3008  	ws = memdb.NewWatchSet()
  3009  	idx, results, err = s.CheckServiceNodes(ws, "service1")
  3010  	if err != nil {
  3011  		t.Fatalf("err: %s", err)
  3012  	}
  3013  	if idx != 10 {
  3014  		t.Fatalf("bad index: %d", idx)
  3015  	}
  3016  
  3017  	// Registering some unrelated node + service should not fire the watch.
  3018  	testRegisterNode(t, s, 11, "nope")
  3019  	testRegisterService(t, s, 12, "nope", "nope")
  3020  	if watchFired(ws) {
  3021  		t.Fatalf("bad")
  3022  	}
  3023  
  3024  	// Note that we can't overwhelm chan tracking any more since we optimized it
  3025  	// to only need to watch one chan in the happy path. The only path that does
  3026  	// bees to watch more stuff is where there are no service instances which also
  3027  	// means fewer than watchLimit chans too so effectively no way to trigger
  3028  	// Fallback watch any more.
  3029  }
  3030  
  3031  func TestStateStore_CheckConnectServiceNodes(t *testing.T) {
  3032  	assert := assert.New(t)
  3033  	s := testStateStore(t)
  3034  
  3035  	// Listing with no results returns an empty list.
  3036  	ws := memdb.NewWatchSet()
  3037  	idx, nodes, err := s.CheckConnectServiceNodes(ws, "db")
  3038  	assert.Nil(err)
  3039  	assert.Equal(idx, uint64(0))
  3040  	assert.Len(nodes, 0)
  3041  
  3042  	// Create some nodes and services.
  3043  	assert.Nil(s.EnsureNode(10, &structs.Node{Node: "foo", Address: "127.0.0.1"}))
  3044  	assert.Nil(s.EnsureNode(11, &structs.Node{Node: "bar", Address: "127.0.0.2"}))
  3045  	assert.Nil(s.EnsureService(12, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: nil, Address: "", Port: 5000}))
  3046  	assert.Nil(s.EnsureService(13, "bar", &structs.NodeService{ID: "api", Service: "api", Tags: nil, Address: "", Port: 5000}))
  3047  	assert.Nil(s.EnsureService(14, "foo", &structs.NodeService{Kind: structs.ServiceKindConnectProxy, ID: "proxy", Service: "proxy", Proxy: structs.ConnectProxyConfig{DestinationServiceName: "db"}, Port: 8000}))
  3048  	assert.Nil(s.EnsureService(15, "bar", &structs.NodeService{Kind: structs.ServiceKindConnectProxy, ID: "proxy", Service: "proxy", Proxy: structs.ConnectProxyConfig{DestinationServiceName: "db"}, Port: 8000}))
  3049  	assert.Nil(s.EnsureService(16, "bar", &structs.NodeService{ID: "db2", Service: "db", Tags: []string{"slave"}, Address: "", Port: 8001}))
  3050  	assert.True(watchFired(ws))
  3051  
  3052  	// Register node checks
  3053  	testRegisterCheck(t, s, 17, "foo", "", "check1", api.HealthPassing)
  3054  	testRegisterCheck(t, s, 18, "bar", "", "check2", api.HealthPassing)
  3055  
  3056  	// Register checks against the services.
  3057  	testRegisterCheck(t, s, 19, "foo", "db", "check3", api.HealthPassing)
  3058  	testRegisterCheck(t, s, 20, "bar", "proxy", "check4", api.HealthPassing)
  3059  
  3060  	// Read everything back.
  3061  	ws = memdb.NewWatchSet()
  3062  	idx, nodes, err = s.CheckConnectServiceNodes(ws, "db")
  3063  	assert.Nil(err)
  3064  	assert.Equal(idx, uint64(idx))
  3065  	assert.Len(nodes, 2)
  3066  
  3067  	for _, n := range nodes {
  3068  		assert.Equal(structs.ServiceKindConnectProxy, n.Service.Kind)
  3069  		assert.Equal("db", n.Service.Proxy.DestinationServiceName)
  3070  	}
  3071  }
  3072  
  3073  func BenchmarkCheckServiceNodes(b *testing.B) {
  3074  	s, err := NewStateStore(nil)
  3075  	if err != nil {
  3076  		b.Fatalf("err: %s", err)
  3077  	}
  3078  
  3079  	if err := s.EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
  3080  		b.Fatalf("err: %v", err)
  3081  	}
  3082  	if err := s.EnsureService(2, "foo", &structs.NodeService{ID: "db1", Service: "db", Tags: []string{"master"}, Address: "", Port: 8000}); err != nil {
  3083  		b.Fatalf("err: %v", err)
  3084  	}
  3085  	check := &structs.HealthCheck{
  3086  		Node:      "foo",
  3087  		CheckID:   "db",
  3088  		Name:      "can connect",
  3089  		Status:    api.HealthPassing,
  3090  		ServiceID: "db1",
  3091  	}
  3092  	if err := s.EnsureCheck(3, check); err != nil {
  3093  		b.Fatalf("err: %v", err)
  3094  	}
  3095  	check = &structs.HealthCheck{
  3096  		Node:    "foo",
  3097  		CheckID: "check1",
  3098  		Name:    "check1",
  3099  		Status:  api.HealthPassing,
  3100  	}
  3101  	if err := s.EnsureCheck(4, check); err != nil {
  3102  		b.Fatalf("err: %v", err)
  3103  	}
  3104  
  3105  	ws := memdb.NewWatchSet()
  3106  	for i := 0; i < b.N; i++ {
  3107  		s.CheckServiceNodes(ws, "db")
  3108  	}
  3109  }
  3110  
  3111  func TestStateStore_CheckServiceTagNodes(t *testing.T) {
  3112  	s := testStateStore(t)
  3113  
  3114  	if err := s.EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
  3115  		t.Fatalf("err: %v", err)
  3116  	}
  3117  	if err := s.EnsureService(2, "foo", &structs.NodeService{ID: "db1", Service: "db", Tags: []string{"master"}, Address: "", Port: 8000}); err != nil {
  3118  		t.Fatalf("err: %v", err)
  3119  	}
  3120  	check := &structs.HealthCheck{
  3121  		Node:      "foo",
  3122  		CheckID:   "db",
  3123  		Name:      "can connect",
  3124  		Status:    api.HealthPassing,
  3125  		ServiceID: "db1",
  3126  	}
  3127  	if err := s.EnsureCheck(3, check); err != nil {
  3128  		t.Fatalf("err: %v", err)
  3129  	}
  3130  	check = &structs.HealthCheck{
  3131  		Node:    "foo",
  3132  		CheckID: "check1",
  3133  		Name:    "another check",
  3134  		Status:  api.HealthPassing,
  3135  	}
  3136  	if err := s.EnsureCheck(4, check); err != nil {
  3137  		t.Fatalf("err: %v", err)
  3138  	}
  3139  
  3140  	ws := memdb.NewWatchSet()
  3141  	idx, nodes, err := s.CheckServiceTagNodes(ws, "db", []string{"master"})
  3142  	if err != nil {
  3143  		t.Fatalf("err: %s", err)
  3144  	}
  3145  	if idx != 4 {
  3146  		t.Fatalf("bad: %v", idx)
  3147  	}
  3148  	if len(nodes) != 1 {
  3149  		t.Fatalf("Bad: %v", nodes)
  3150  	}
  3151  	if nodes[0].Node.Node != "foo" {
  3152  		t.Fatalf("Bad: %v", nodes[0])
  3153  	}
  3154  	if nodes[0].Service.ID != "db1" {
  3155  		t.Fatalf("Bad: %v", nodes[0])
  3156  	}
  3157  	if len(nodes[0].Checks) != 2 {
  3158  		t.Fatalf("Bad: %v", nodes[0])
  3159  	}
  3160  	if nodes[0].Checks[0].CheckID != "check1" {
  3161  		t.Fatalf("Bad: %v", nodes[0])
  3162  	}
  3163  	if nodes[0].Checks[1].CheckID != "db" {
  3164  		t.Fatalf("Bad: %v", nodes[0])
  3165  	}
  3166  
  3167  	// Changing a tag should fire the watch.
  3168  	if err := s.EnsureService(4, "foo", &structs.NodeService{ID: "db1", Service: "db", Tags: []string{"nope"}, Address: "", Port: 8000}); err != nil {
  3169  		t.Fatalf("err: %v", err)
  3170  	}
  3171  	if !watchFired(ws) {
  3172  		t.Fatalf("bad")
  3173  	}
  3174  }
  3175  
  3176  func TestStateStore_Check_Snapshot(t *testing.T) {
  3177  	s := testStateStore(t)
  3178  
  3179  	// Create a node, a service, and a service check as well as a node check.
  3180  	testRegisterNode(t, s, 0, "node1")
  3181  	testRegisterService(t, s, 1, "node1", "service1")
  3182  	checks := structs.HealthChecks{
  3183  		&structs.HealthCheck{
  3184  			Node:    "node1",
  3185  			CheckID: "check1",
  3186  			Name:    "node check",
  3187  			Status:  api.HealthPassing,
  3188  		},
  3189  		&structs.HealthCheck{
  3190  			Node:      "node1",
  3191  			CheckID:   "check2",
  3192  			Name:      "service check",
  3193  			Status:    api.HealthCritical,
  3194  			ServiceID: "service1",
  3195  		},
  3196  	}
  3197  	for i, hc := range checks {
  3198  		if err := s.EnsureCheck(uint64(i+1), hc); err != nil {
  3199  			t.Fatalf("err: %s", err)
  3200  		}
  3201  	}
  3202  
  3203  	// Create a second node/service to make sure node filtering works. This
  3204  	// will affect the index but not the dump.
  3205  	testRegisterNode(t, s, 3, "node2")
  3206  	testRegisterService(t, s, 4, "node2", "service2")
  3207  	testRegisterCheck(t, s, 5, "node2", "service2", "check3", api.HealthPassing)
  3208  
  3209  	// Snapshot the checks.
  3210  	snap := s.Snapshot()
  3211  	defer snap.Close()
  3212  
  3213  	// Alter the real state store.
  3214  	testRegisterCheck(t, s, 6, "node2", "service2", "check4", api.HealthPassing)
  3215  
  3216  	// Verify the snapshot.
  3217  	if idx := snap.LastIndex(); idx != 5 {
  3218  		t.Fatalf("bad index: %d", idx)
  3219  	}
  3220  	iter, err := snap.Checks("node1")
  3221  	if err != nil {
  3222  		t.Fatalf("err: %s", err)
  3223  	}
  3224  	for i := 0; i < len(checks); i++ {
  3225  		check := iter.Next().(*structs.HealthCheck)
  3226  		if check == nil {
  3227  			t.Fatalf("unexpected end of checks")
  3228  		}
  3229  
  3230  		checks[i].CreateIndex, checks[i].ModifyIndex = uint64(i+1), uint64(i+1)
  3231  		if !reflect.DeepEqual(check, checks[i]) {
  3232  			t.Fatalf("bad: %#v != %#v", check, checks[i])
  3233  		}
  3234  	}
  3235  	if iter.Next() != nil {
  3236  		t.Fatalf("unexpected extra checks")
  3237  	}
  3238  }
  3239  
  3240  func TestStateStore_NodeInfo_NodeDump(t *testing.T) {
  3241  	s := testStateStore(t)
  3242  
  3243  	// Generating a node dump that matches nothing returns empty
  3244  	wsInfo := memdb.NewWatchSet()
  3245  	idx, dump, err := s.NodeInfo(wsInfo, "node1")
  3246  	if idx != 0 || dump != nil || err != nil {
  3247  		t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, dump, err)
  3248  	}
  3249  	wsDump := memdb.NewWatchSet()
  3250  	idx, dump, err = s.NodeDump(wsDump)
  3251  	if idx != 0 || dump != nil || err != nil {
  3252  		t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, dump, err)
  3253  	}
  3254  
  3255  	// Register some nodes
  3256  	testRegisterNode(t, s, 0, "node1")
  3257  	testRegisterNode(t, s, 1, "node2")
  3258  
  3259  	// Register services against them
  3260  	testRegisterService(t, s, 2, "node1", "service1")
  3261  	testRegisterService(t, s, 3, "node1", "service2")
  3262  	testRegisterService(t, s, 4, "node2", "service1")
  3263  	testRegisterService(t, s, 5, "node2", "service2")
  3264  
  3265  	// Register service-level checks
  3266  	testRegisterCheck(t, s, 6, "node1", "service1", "check1", api.HealthPassing)
  3267  	testRegisterCheck(t, s, 7, "node2", "service1", "check1", api.HealthPassing)
  3268  
  3269  	// Register node-level checks
  3270  	testRegisterCheck(t, s, 8, "node1", "", "check2", api.HealthPassing)
  3271  	testRegisterCheck(t, s, 9, "node2", "", "check2", api.HealthPassing)
  3272  
  3273  	// Both watches should have fired due to the changes above.
  3274  	if !watchFired(wsInfo) {
  3275  		t.Fatalf("bad")
  3276  	}
  3277  	if !watchFired(wsDump) {
  3278  		t.Fatalf("bad")
  3279  	}
  3280  
  3281  	// Check that our result matches what we expect.
  3282  	expect := structs.NodeDump{
  3283  		&structs.NodeInfo{
  3284  			Node: "node1",
  3285  			Checks: structs.HealthChecks{
  3286  				&structs.HealthCheck{
  3287  					Node:        "node1",
  3288  					CheckID:     "check1",
  3289  					ServiceID:   "service1",
  3290  					ServiceName: "service1",
  3291  					Status:      api.HealthPassing,
  3292  					RaftIndex: structs.RaftIndex{
  3293  						CreateIndex: 6,
  3294  						ModifyIndex: 6,
  3295  					},
  3296  				},
  3297  				&structs.HealthCheck{
  3298  					Node:        "node1",
  3299  					CheckID:     "check2",
  3300  					ServiceID:   "",
  3301  					ServiceName: "",
  3302  					Status:      api.HealthPassing,
  3303  					RaftIndex: structs.RaftIndex{
  3304  						CreateIndex: 8,
  3305  						ModifyIndex: 8,
  3306  					},
  3307  				},
  3308  			},
  3309  			Services: []*structs.NodeService{
  3310  				&structs.NodeService{
  3311  					ID:      "service1",
  3312  					Service: "service1",
  3313  					Address: "1.1.1.1",
  3314  					Meta:    make(map[string]string),
  3315  					Port:    1111,
  3316  					Weights: &structs.Weights{Passing: 1, Warning: 1},
  3317  					RaftIndex: structs.RaftIndex{
  3318  						CreateIndex: 2,
  3319  						ModifyIndex: 2,
  3320  					},
  3321  				},
  3322  				&structs.NodeService{
  3323  					ID:      "service2",
  3324  					Service: "service2",
  3325  					Address: "1.1.1.1",
  3326  					Meta:    make(map[string]string),
  3327  					Port:    1111,
  3328  					Weights: &structs.Weights{Passing: 1, Warning: 1},
  3329  					RaftIndex: structs.RaftIndex{
  3330  						CreateIndex: 3,
  3331  						ModifyIndex: 3,
  3332  					},
  3333  				},
  3334  			},
  3335  		},
  3336  		&structs.NodeInfo{
  3337  			Node: "node2",
  3338  			Checks: structs.HealthChecks{
  3339  				&structs.HealthCheck{
  3340  					Node:        "node2",
  3341  					CheckID:     "check1",
  3342  					ServiceID:   "service1",
  3343  					ServiceName: "service1",
  3344  					Status:      api.HealthPassing,
  3345  					RaftIndex: structs.RaftIndex{
  3346  						CreateIndex: 7,
  3347  						ModifyIndex: 7,
  3348  					},
  3349  				},
  3350  				&structs.HealthCheck{
  3351  					Node:        "node2",
  3352  					CheckID:     "check2",
  3353  					ServiceID:   "",
  3354  					ServiceName: "",
  3355  					Status:      api.HealthPassing,
  3356  					RaftIndex: structs.RaftIndex{
  3357  						CreateIndex: 9,
  3358  						ModifyIndex: 9,
  3359  					},
  3360  				},
  3361  			},
  3362  			Services: []*structs.NodeService{
  3363  				&structs.NodeService{
  3364  					ID:      "service1",
  3365  					Service: "service1",
  3366  					Address: "1.1.1.1",
  3367  					Port:    1111,
  3368  					Meta:    make(map[string]string),
  3369  					Weights: &structs.Weights{Passing: 1, Warning: 1},
  3370  					RaftIndex: structs.RaftIndex{
  3371  						CreateIndex: 4,
  3372  						ModifyIndex: 4,
  3373  					},
  3374  				},
  3375  				&structs.NodeService{
  3376  					ID:      "service2",
  3377  					Service: "service2",
  3378  					Address: "1.1.1.1",
  3379  					Port:    1111,
  3380  					Meta:    make(map[string]string),
  3381  					Weights: &structs.Weights{Passing: 1, Warning: 1},
  3382  					RaftIndex: structs.RaftIndex{
  3383  						CreateIndex: 5,
  3384  						ModifyIndex: 5,
  3385  					},
  3386  				},
  3387  			},
  3388  		},
  3389  	}
  3390  
  3391  	// Get a dump of just a single node
  3392  	ws := memdb.NewWatchSet()
  3393  	idx, dump, err = s.NodeInfo(ws, "node1")
  3394  	if err != nil {
  3395  		t.Fatalf("err: %s", err)
  3396  	}
  3397  	if idx != 9 {
  3398  		t.Fatalf("bad index: %d", idx)
  3399  	}
  3400  	if len(dump) != 1 || !reflect.DeepEqual(dump[0], expect[0]) {
  3401  		t.Fatalf("bad: len=%#v dump=%#v expect=%#v", len(dump), dump[0], expect[0])
  3402  	}
  3403  
  3404  	// Generate a dump of all the nodes
  3405  	idx, dump, err = s.NodeDump(nil)
  3406  	if err != nil {
  3407  		t.Fatalf("err: %s", err)
  3408  	}
  3409  	if idx != 9 {
  3410  		t.Fatalf("bad index: %d", 9)
  3411  	}
  3412  	if !reflect.DeepEqual(dump, expect) {
  3413  		t.Fatalf("bad: %#v", dump[0].Services[0])
  3414  	}
  3415  
  3416  	// Registering some unrelated node + service + check should not fire the
  3417  	// watch.
  3418  	testRegisterNode(t, s, 10, "nope")
  3419  	testRegisterService(t, s, 11, "nope", "nope")
  3420  	if watchFired(ws) {
  3421  		t.Fatalf("bad")
  3422  	}
  3423  }
  3424  
  3425  func TestStateStore_ServiceIdxUpdateOnNodeUpdate(t *testing.T) {
  3426  	s := testStateStore(t)
  3427  
  3428  	// Create a service on a node
  3429  	err := s.EnsureNode(10, &structs.Node{Node: "node", Address: "127.0.0.1"})
  3430  	require.Nil(t, err)
  3431  	err = s.EnsureService(12, "node", &structs.NodeService{ID: "srv", Service: "srv", Tags: nil, Address: "", Port: 5000})
  3432  	require.Nil(t, err)
  3433  
  3434  	// Store the current service index
  3435  	ws := memdb.NewWatchSet()
  3436  	lastIdx, _, err := s.ServiceNodes(ws, "srv")
  3437  	require.Nil(t, err)
  3438  
  3439  	// Update the node with some meta
  3440  	err = s.EnsureNode(14, &structs.Node{Node: "node", Address: "127.0.0.1", Meta: map[string]string{"foo": "bar"}})
  3441  	require.Nil(t, err)
  3442  
  3443  	// Read the new service index
  3444  	ws = memdb.NewWatchSet()
  3445  	newIdx, _, err := s.ServiceNodes(ws, "srv")
  3446  	require.Nil(t, err)
  3447  
  3448  	require.True(t, newIdx > lastIdx)
  3449  }