github.com/hhrutter/nomad@v0.6.0-rc2.0.20170723054333-80c4b03f0705/nomad/state/state_store_test.go (about)

     1  package state
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"reflect"
     7  	"sort"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	memdb "github.com/hashicorp/go-memdb"
    13  	"github.com/hashicorp/nomad/helper"
    14  	"github.com/hashicorp/nomad/nomad/mock"
    15  	"github.com/hashicorp/nomad/nomad/structs"
    16  )
    17  
    18  func testStateStore(t *testing.T) *StateStore {
    19  	state, err := NewStateStore(os.Stderr)
    20  	if err != nil {
    21  		t.Fatalf("err: %v", err)
    22  	}
    23  	if state == nil {
    24  		t.Fatalf("missing state")
    25  	}
    26  	return state
    27  }
    28  
    29  // This test checks that:
    30  // 1) The job is denormalized
    31  // 2) Allocations are created
    32  func TestStateStore_UpsertPlanResults_AllocationsCreated_Denormalized(t *testing.T) {
    33  	state := testStateStore(t)
    34  	alloc := mock.Alloc()
    35  	job := alloc.Job
    36  	alloc.Job = nil
    37  
    38  	if err := state.UpsertJob(999, job); err != nil {
    39  		t.Fatalf("err: %v", err)
    40  	}
    41  
    42  	// Create a plan result
    43  	res := structs.ApplyPlanResultsRequest{
    44  		AllocUpdateRequest: structs.AllocUpdateRequest{
    45  			Alloc: []*structs.Allocation{alloc},
    46  			Job:   job,
    47  		},
    48  	}
    49  
    50  	err := state.UpsertPlanResults(1000, &res)
    51  	if err != nil {
    52  		t.Fatalf("err: %v", err)
    53  	}
    54  
    55  	ws := memdb.NewWatchSet()
    56  	out, err := state.AllocByID(ws, alloc.ID)
    57  	if err != nil {
    58  		t.Fatalf("err: %v", err)
    59  	}
    60  
    61  	if !reflect.DeepEqual(alloc, out) {
    62  		t.Fatalf("bad: %#v %#v", alloc, out)
    63  	}
    64  
    65  	index, err := state.Index("allocs")
    66  	if err != nil {
    67  		t.Fatalf("err: %v", err)
    68  	}
    69  	if index != 1000 {
    70  		t.Fatalf("bad: %d", index)
    71  	}
    72  
    73  	if watchFired(ws) {
    74  		t.Fatalf("bad")
    75  	}
    76  }
    77  
    78  // This test checks that the deployment is created and allocations count towards
    79  // the deployment
    80  func TestStateStore_UpsertPlanResults_Deployment(t *testing.T) {
    81  	state := testStateStore(t)
    82  	alloc := mock.Alloc()
    83  	alloc2 := mock.Alloc()
    84  	job := alloc.Job
    85  	alloc.Job = nil
    86  	alloc2.Job = nil
    87  
    88  	d := mock.Deployment()
    89  	alloc.DeploymentID = d.ID
    90  	alloc2.DeploymentID = d.ID
    91  
    92  	if err := state.UpsertJob(999, job); err != nil {
    93  		t.Fatalf("err: %v", err)
    94  	}
    95  
    96  	// Create a plan result
    97  	res := structs.ApplyPlanResultsRequest{
    98  		AllocUpdateRequest: structs.AllocUpdateRequest{
    99  			Alloc: []*structs.Allocation{alloc, alloc2},
   100  			Job:   job,
   101  		},
   102  		Deployment: d,
   103  	}
   104  
   105  	err := state.UpsertPlanResults(1000, &res)
   106  	if err != nil {
   107  		t.Fatalf("err: %v", err)
   108  	}
   109  
   110  	ws := memdb.NewWatchSet()
   111  	out, err := state.AllocByID(ws, alloc.ID)
   112  	if err != nil {
   113  		t.Fatalf("err: %v", err)
   114  	}
   115  
   116  	if !reflect.DeepEqual(alloc, out) {
   117  		t.Fatalf("bad: %#v %#v", alloc, out)
   118  	}
   119  
   120  	dout, err := state.DeploymentByID(ws, d.ID)
   121  	if err != nil {
   122  		t.Fatalf("err: %v", err)
   123  	}
   124  
   125  	if dout == nil {
   126  		t.Fatalf("bad: nil deployment")
   127  	}
   128  
   129  	tg, ok := dout.TaskGroups[alloc.TaskGroup]
   130  	if !ok {
   131  		t.Fatalf("bad: nil deployment state")
   132  	}
   133  	if tg == nil || tg.PlacedAllocs != 2 {
   134  		t.Fatalf("bad: %v", dout)
   135  	}
   136  
   137  	if watchFired(ws) {
   138  		t.Fatalf("bad")
   139  	}
   140  
   141  	// Update the allocs to be part of a new deployment
   142  	d2 := d.Copy()
   143  	d2.ID = structs.GenerateUUID()
   144  
   145  	allocNew := alloc.Copy()
   146  	allocNew.DeploymentID = d2.ID
   147  	allocNew2 := alloc2.Copy()
   148  	allocNew2.DeploymentID = d2.ID
   149  
   150  	// Create another plan
   151  	res = structs.ApplyPlanResultsRequest{
   152  		AllocUpdateRequest: structs.AllocUpdateRequest{
   153  			Alloc: []*structs.Allocation{allocNew, allocNew2},
   154  			Job:   job,
   155  		},
   156  		Deployment: d2,
   157  	}
   158  
   159  	err = state.UpsertPlanResults(1001, &res)
   160  	if err != nil {
   161  		t.Fatalf("err: %v", err)
   162  	}
   163  
   164  	dout, err = state.DeploymentByID(ws, d2.ID)
   165  	if err != nil {
   166  		t.Fatalf("err: %v", err)
   167  	}
   168  
   169  	if dout == nil {
   170  		t.Fatalf("bad: nil deployment")
   171  	}
   172  
   173  	tg, ok = dout.TaskGroups[alloc.TaskGroup]
   174  	if !ok {
   175  		t.Fatalf("bad: nil deployment state")
   176  	}
   177  	if tg == nil || tg.PlacedAllocs != 2 {
   178  		t.Fatalf("bad: %v", dout)
   179  	}
   180  }
   181  
   182  // This test checks that deployment updates are applied correctly
   183  func TestStateStore_UpsertPlanResults_DeploymentUpdates(t *testing.T) {
   184  	state := testStateStore(t)
   185  
   186  	// Create a job that applies to all
   187  	job := mock.Job()
   188  	if err := state.UpsertJob(998, job); err != nil {
   189  		t.Fatalf("err: %v", err)
   190  	}
   191  
   192  	// Create a deployment that we will update its status
   193  	doutstanding := mock.Deployment()
   194  	doutstanding.JobID = job.ID
   195  
   196  	if err := state.UpsertDeployment(1000, doutstanding); err != nil {
   197  		t.Fatalf("err: %v", err)
   198  	}
   199  
   200  	alloc := mock.Alloc()
   201  	alloc.Job = nil
   202  
   203  	dnew := mock.Deployment()
   204  	dnew.JobID = job.ID
   205  	alloc.DeploymentID = dnew.ID
   206  
   207  	// Update the old deployment
   208  	update := &structs.DeploymentStatusUpdate{
   209  		DeploymentID:      doutstanding.ID,
   210  		Status:            "foo",
   211  		StatusDescription: "bar",
   212  	}
   213  
   214  	// Create a plan result
   215  	res := structs.ApplyPlanResultsRequest{
   216  		AllocUpdateRequest: structs.AllocUpdateRequest{
   217  			Alloc: []*structs.Allocation{alloc},
   218  			Job:   job,
   219  		},
   220  		Deployment:        dnew,
   221  		DeploymentUpdates: []*structs.DeploymentStatusUpdate{update},
   222  	}
   223  
   224  	err := state.UpsertPlanResults(1000, &res)
   225  	if err != nil {
   226  		t.Fatalf("err: %v", err)
   227  	}
   228  
   229  	ws := memdb.NewWatchSet()
   230  
   231  	// Check the deployments are correctly updated.
   232  	dout, err := state.DeploymentByID(ws, dnew.ID)
   233  	if err != nil {
   234  		t.Fatalf("err: %v", err)
   235  	}
   236  
   237  	if dout == nil {
   238  		t.Fatalf("bad: nil deployment")
   239  	}
   240  
   241  	tg, ok := dout.TaskGroups[alloc.TaskGroup]
   242  	if !ok {
   243  		t.Fatalf("bad: nil deployment state")
   244  	}
   245  	if tg == nil || tg.PlacedAllocs != 1 {
   246  		t.Fatalf("bad: %v", dout)
   247  	}
   248  
   249  	doutstandingout, err := state.DeploymentByID(ws, doutstanding.ID)
   250  	if err != nil || doutstandingout == nil {
   251  		t.Fatalf("bad: %v %v", err, doutstandingout)
   252  	}
   253  	if doutstandingout.Status != update.Status || doutstandingout.StatusDescription != update.StatusDescription || doutstandingout.ModifyIndex != 1000 {
   254  		t.Fatalf("bad: %v", doutstandingout)
   255  	}
   256  
   257  	if watchFired(ws) {
   258  		t.Fatalf("bad")
   259  	}
   260  }
   261  
   262  func TestStateStore_UpsertDeployment(t *testing.T) {
   263  	state := testStateStore(t)
   264  	deployment := mock.Deployment()
   265  
   266  	// Create a watchset so we can test that upsert fires the watch
   267  	ws := memdb.NewWatchSet()
   268  	_, err := state.DeploymentsByJobID(ws, deployment.ID)
   269  	if err != nil {
   270  		t.Fatalf("bad: %v", err)
   271  	}
   272  
   273  	err = state.UpsertDeployment(1000, deployment)
   274  	if err != nil {
   275  		t.Fatalf("err: %v", err)
   276  	}
   277  	if !watchFired(ws) {
   278  		t.Fatalf("bad")
   279  	}
   280  
   281  	ws = memdb.NewWatchSet()
   282  	out, err := state.DeploymentByID(ws, deployment.ID)
   283  	if err != nil {
   284  		t.Fatalf("err: %v", err)
   285  	}
   286  
   287  	if !reflect.DeepEqual(deployment, out) {
   288  		t.Fatalf("bad: %#v %#v", deployment, out)
   289  	}
   290  
   291  	index, err := state.Index("deployment")
   292  	if err != nil {
   293  		t.Fatalf("err: %v", err)
   294  	}
   295  	if index != 1000 {
   296  		t.Fatalf("bad: %d", index)
   297  	}
   298  
   299  	if watchFired(ws) {
   300  		t.Fatalf("bad")
   301  	}
   302  }
   303  
   304  func TestStateStore_DeleteDeployment(t *testing.T) {
   305  	state := testStateStore(t)
   306  	d1 := mock.Deployment()
   307  	d2 := mock.Deployment()
   308  
   309  	err := state.UpsertDeployment(1000, d1)
   310  	if err != nil {
   311  		t.Fatalf("err: %v", err)
   312  	}
   313  	if err := state.UpsertDeployment(1001, d2); err != nil {
   314  		t.Fatalf("err: %v", err)
   315  	}
   316  
   317  	// Create a watchset so we can test that delete fires the watch
   318  	ws := memdb.NewWatchSet()
   319  	if _, err := state.DeploymentByID(ws, d1.ID); err != nil {
   320  		t.Fatalf("bad: %v", err)
   321  	}
   322  
   323  	err = state.DeleteDeployment(1002, []string{d1.ID, d2.ID})
   324  	if err != nil {
   325  		t.Fatalf("err: %v", err)
   326  	}
   327  
   328  	if !watchFired(ws) {
   329  		t.Fatalf("bad")
   330  	}
   331  
   332  	ws = memdb.NewWatchSet()
   333  	out, err := state.DeploymentByID(ws, d1.ID)
   334  	if err != nil {
   335  		t.Fatalf("err: %v", err)
   336  	}
   337  
   338  	if out != nil {
   339  		t.Fatalf("bad: %#v %#v", d1, out)
   340  	}
   341  
   342  	index, err := state.Index("deployment")
   343  	if err != nil {
   344  		t.Fatalf("err: %v", err)
   345  	}
   346  	if index != 1002 {
   347  		t.Fatalf("bad: %d", index)
   348  	}
   349  
   350  	if watchFired(ws) {
   351  		t.Fatalf("bad")
   352  	}
   353  }
   354  
   355  func TestStateStore_Deployments(t *testing.T) {
   356  	state := testStateStore(t)
   357  	var deployments []*structs.Deployment
   358  
   359  	for i := 0; i < 10; i++ {
   360  		deployment := mock.Deployment()
   361  		deployments = append(deployments, deployment)
   362  
   363  		err := state.UpsertDeployment(1000+uint64(i), deployment)
   364  		if err != nil {
   365  			t.Fatalf("err: %v", err)
   366  		}
   367  	}
   368  
   369  	ws := memdb.NewWatchSet()
   370  	iter, err := state.Deployments(ws)
   371  	if err != nil {
   372  		t.Fatalf("err: %v", err)
   373  	}
   374  
   375  	var out []*structs.Deployment
   376  	for {
   377  		raw := iter.Next()
   378  		if raw == nil {
   379  			break
   380  		}
   381  		out = append(out, raw.(*structs.Deployment))
   382  	}
   383  
   384  	lessThan := func(i, j int) bool {
   385  		return deployments[i].ID < deployments[j].ID
   386  	}
   387  	sort.Slice(deployments, lessThan)
   388  	sort.Slice(out, lessThan)
   389  
   390  	if !reflect.DeepEqual(deployments, out) {
   391  		t.Fatalf("bad: %#v %#v", deployments, out)
   392  	}
   393  
   394  	if watchFired(ws) {
   395  		t.Fatalf("bad")
   396  	}
   397  }
   398  
   399  func TestStateStore_DeploymentsByIDPrefix(t *testing.T) {
   400  	state := testStateStore(t)
   401  	deploy := mock.Deployment()
   402  
   403  	deploy.ID = "11111111-662e-d0ab-d1c9-3e434af7bdb4"
   404  	err := state.UpsertDeployment(1000, deploy)
   405  	if err != nil {
   406  		t.Fatalf("err: %v", err)
   407  	}
   408  
   409  	// Create a watchset so we can test that getters don't cause it to fire
   410  	ws := memdb.NewWatchSet()
   411  	iter, err := state.DeploymentsByIDPrefix(ws, deploy.ID)
   412  	if err != nil {
   413  		t.Fatalf("err: %v", err)
   414  	}
   415  
   416  	gatherDeploys := func(iter memdb.ResultIterator) []*structs.Deployment {
   417  		var deploys []*structs.Deployment
   418  		for {
   419  			raw := iter.Next()
   420  			if raw == nil {
   421  				break
   422  			}
   423  			deploy := raw.(*structs.Deployment)
   424  			deploys = append(deploys, deploy)
   425  		}
   426  		return deploys
   427  	}
   428  
   429  	deploys := gatherDeploys(iter)
   430  	if len(deploys) != 1 {
   431  		t.Fatalf("err: %v", err)
   432  	}
   433  
   434  	if watchFired(ws) {
   435  		t.Fatalf("bad")
   436  	}
   437  
   438  	iter, err = state.DeploymentsByIDPrefix(ws, "11")
   439  	if err != nil {
   440  		t.Fatalf("err: %v", err)
   441  	}
   442  
   443  	deploys = gatherDeploys(iter)
   444  	if len(deploys) != 1 {
   445  		t.Fatalf("err: %v", err)
   446  	}
   447  
   448  	deploy = mock.Deployment()
   449  	deploy.ID = "11222222-662e-d0ab-d1c9-3e434af7bdb4"
   450  	err = state.UpsertDeployment(1001, deploy)
   451  	if err != nil {
   452  		t.Fatalf("err: %v", err)
   453  	}
   454  
   455  	if !watchFired(ws) {
   456  		t.Fatalf("bad")
   457  	}
   458  
   459  	ws = memdb.NewWatchSet()
   460  	iter, err = state.DeploymentsByIDPrefix(ws, "11")
   461  	if err != nil {
   462  		t.Fatalf("err: %v", err)
   463  	}
   464  
   465  	deploys = gatherDeploys(iter)
   466  	if len(deploys) != 2 {
   467  		t.Fatalf("err: %v", err)
   468  	}
   469  
   470  	iter, err = state.DeploymentsByIDPrefix(ws, "1111")
   471  	if err != nil {
   472  		t.Fatalf("err: %v", err)
   473  	}
   474  
   475  	deploys = gatherDeploys(iter)
   476  	if len(deploys) != 1 {
   477  		t.Fatalf("err: %v", err)
   478  	}
   479  
   480  	if watchFired(ws) {
   481  		t.Fatalf("bad")
   482  	}
   483  }
   484  
   485  func TestStateStore_UpsertNode_Node(t *testing.T) {
   486  	state := testStateStore(t)
   487  	node := mock.Node()
   488  
   489  	// Create a watchset so we can test that upsert fires the watch
   490  	ws := memdb.NewWatchSet()
   491  	_, err := state.NodeByID(ws, node.ID)
   492  	if err != nil {
   493  		t.Fatalf("bad: %v", err)
   494  	}
   495  
   496  	err = state.UpsertNode(1000, node)
   497  	if err != nil {
   498  		t.Fatalf("err: %v", err)
   499  	}
   500  	if !watchFired(ws) {
   501  		t.Fatalf("bad")
   502  	}
   503  
   504  	ws = memdb.NewWatchSet()
   505  	out, err := state.NodeByID(ws, node.ID)
   506  	if err != nil {
   507  		t.Fatalf("err: %v", err)
   508  	}
   509  
   510  	if !reflect.DeepEqual(node, out) {
   511  		t.Fatalf("bad: %#v %#v", node, out)
   512  	}
   513  
   514  	index, err := state.Index("nodes")
   515  	if err != nil {
   516  		t.Fatalf("err: %v", err)
   517  	}
   518  	if index != 1000 {
   519  		t.Fatalf("bad: %d", index)
   520  	}
   521  
   522  	if watchFired(ws) {
   523  		t.Fatalf("bad")
   524  	}
   525  }
   526  
   527  func TestStateStore_DeleteNode_Node(t *testing.T) {
   528  	state := testStateStore(t)
   529  	node := mock.Node()
   530  
   531  	err := state.UpsertNode(1000, node)
   532  	if err != nil {
   533  		t.Fatalf("err: %v", err)
   534  	}
   535  
   536  	// Create a watchset so we can test that delete fires the watch
   537  	ws := memdb.NewWatchSet()
   538  	if _, err := state.NodeByID(ws, node.ID); err != nil {
   539  		t.Fatalf("bad: %v", err)
   540  	}
   541  
   542  	err = state.DeleteNode(1001, node.ID)
   543  	if err != nil {
   544  		t.Fatalf("err: %v", err)
   545  	}
   546  
   547  	if !watchFired(ws) {
   548  		t.Fatalf("bad")
   549  	}
   550  
   551  	ws = memdb.NewWatchSet()
   552  	out, err := state.NodeByID(ws, node.ID)
   553  	if err != nil {
   554  		t.Fatalf("err: %v", err)
   555  	}
   556  
   557  	if out != nil {
   558  		t.Fatalf("bad: %#v %#v", node, out)
   559  	}
   560  
   561  	index, err := state.Index("nodes")
   562  	if err != nil {
   563  		t.Fatalf("err: %v", err)
   564  	}
   565  	if index != 1001 {
   566  		t.Fatalf("bad: %d", index)
   567  	}
   568  
   569  	if watchFired(ws) {
   570  		t.Fatalf("bad")
   571  	}
   572  }
   573  
   574  func TestStateStore_UpdateNodeStatus_Node(t *testing.T) {
   575  	state := testStateStore(t)
   576  	node := mock.Node()
   577  
   578  	err := state.UpsertNode(800, node)
   579  	if err != nil {
   580  		t.Fatalf("err: %v", err)
   581  	}
   582  
   583  	// Create a watchset so we can test that update node status fires the watch
   584  	ws := memdb.NewWatchSet()
   585  	if _, err := state.NodeByID(ws, node.ID); err != nil {
   586  		t.Fatalf("bad: %v", err)
   587  	}
   588  
   589  	err = state.UpdateNodeStatus(801, node.ID, structs.NodeStatusReady)
   590  	if err != nil {
   591  		t.Fatalf("err: %v", err)
   592  	}
   593  
   594  	if !watchFired(ws) {
   595  		t.Fatalf("bad")
   596  	}
   597  
   598  	ws = memdb.NewWatchSet()
   599  	out, err := state.NodeByID(ws, node.ID)
   600  	if err != nil {
   601  		t.Fatalf("err: %v", err)
   602  	}
   603  
   604  	if out.Status != structs.NodeStatusReady {
   605  		t.Fatalf("bad: %#v", out)
   606  	}
   607  	if out.ModifyIndex != 801 {
   608  		t.Fatalf("bad: %#v", out)
   609  	}
   610  
   611  	index, err := state.Index("nodes")
   612  	if err != nil {
   613  		t.Fatalf("err: %v", err)
   614  	}
   615  	if index != 801 {
   616  		t.Fatalf("bad: %d", index)
   617  	}
   618  
   619  	if watchFired(ws) {
   620  		t.Fatalf("bad")
   621  	}
   622  }
   623  
   624  func TestStateStore_UpdateNodeDrain_Node(t *testing.T) {
   625  	state := testStateStore(t)
   626  	node := mock.Node()
   627  
   628  	err := state.UpsertNode(1000, node)
   629  	if err != nil {
   630  		t.Fatalf("err: %v", err)
   631  	}
   632  
   633  	// Create a watchset so we can test that update node drain fires the watch
   634  	ws := memdb.NewWatchSet()
   635  	if _, err := state.NodeByID(ws, node.ID); err != nil {
   636  		t.Fatalf("bad: %v", err)
   637  	}
   638  
   639  	err = state.UpdateNodeDrain(1001, node.ID, true)
   640  	if err != nil {
   641  		t.Fatalf("err: %v", err)
   642  	}
   643  
   644  	if !watchFired(ws) {
   645  		t.Fatalf("bad")
   646  	}
   647  
   648  	ws = memdb.NewWatchSet()
   649  	out, err := state.NodeByID(ws, node.ID)
   650  	if err != nil {
   651  		t.Fatalf("err: %v", err)
   652  	}
   653  
   654  	if !out.Drain {
   655  		t.Fatalf("bad: %#v", out)
   656  	}
   657  	if out.ModifyIndex != 1001 {
   658  		t.Fatalf("bad: %#v", out)
   659  	}
   660  
   661  	index, err := state.Index("nodes")
   662  	if err != nil {
   663  		t.Fatalf("err: %v", err)
   664  	}
   665  	if index != 1001 {
   666  		t.Fatalf("bad: %d", index)
   667  	}
   668  
   669  	if watchFired(ws) {
   670  		t.Fatalf("bad")
   671  	}
   672  }
   673  
   674  func TestStateStore_Nodes(t *testing.T) {
   675  	state := testStateStore(t)
   676  	var nodes []*structs.Node
   677  
   678  	for i := 0; i < 10; i++ {
   679  		node := mock.Node()
   680  		nodes = append(nodes, node)
   681  
   682  		err := state.UpsertNode(1000+uint64(i), node)
   683  		if err != nil {
   684  			t.Fatalf("err: %v", err)
   685  		}
   686  	}
   687  
   688  	// Create a watchset so we can test that getters don't cause it to fire
   689  	ws := memdb.NewWatchSet()
   690  	iter, err := state.Nodes(ws)
   691  	if err != nil {
   692  		t.Fatalf("bad: %v", err)
   693  	}
   694  
   695  	var out []*structs.Node
   696  	for {
   697  		raw := iter.Next()
   698  		if raw == nil {
   699  			break
   700  		}
   701  		out = append(out, raw.(*structs.Node))
   702  	}
   703  
   704  	sort.Sort(NodeIDSort(nodes))
   705  	sort.Sort(NodeIDSort(out))
   706  
   707  	if !reflect.DeepEqual(nodes, out) {
   708  		t.Fatalf("bad: %#v %#v", nodes, out)
   709  	}
   710  
   711  	if watchFired(ws) {
   712  		t.Fatalf("bad")
   713  	}
   714  }
   715  
   716  func TestStateStore_NodesByIDPrefix(t *testing.T) {
   717  	state := testStateStore(t)
   718  	node := mock.Node()
   719  
   720  	node.ID = "11111111-662e-d0ab-d1c9-3e434af7bdb4"
   721  	err := state.UpsertNode(1000, node)
   722  	if err != nil {
   723  		t.Fatalf("err: %v", err)
   724  	}
   725  
   726  	// Create a watchset so we can test that getters don't cause it to fire
   727  	ws := memdb.NewWatchSet()
   728  	iter, err := state.NodesByIDPrefix(ws, node.ID)
   729  	if err != nil {
   730  		t.Fatalf("err: %v", err)
   731  	}
   732  
   733  	gatherNodes := func(iter memdb.ResultIterator) []*structs.Node {
   734  		var nodes []*structs.Node
   735  		for {
   736  			raw := iter.Next()
   737  			if raw == nil {
   738  				break
   739  			}
   740  			node := raw.(*structs.Node)
   741  			nodes = append(nodes, node)
   742  		}
   743  		return nodes
   744  	}
   745  
   746  	nodes := gatherNodes(iter)
   747  	if len(nodes) != 1 {
   748  		t.Fatalf("err: %v", err)
   749  	}
   750  
   751  	if watchFired(ws) {
   752  		t.Fatalf("bad")
   753  	}
   754  
   755  	iter, err = state.NodesByIDPrefix(ws, "11")
   756  	if err != nil {
   757  		t.Fatalf("err: %v", err)
   758  	}
   759  
   760  	nodes = gatherNodes(iter)
   761  	if len(nodes) != 1 {
   762  		t.Fatalf("err: %v", err)
   763  	}
   764  
   765  	node = mock.Node()
   766  	node.ID = "11222222-662e-d0ab-d1c9-3e434af7bdb4"
   767  	err = state.UpsertNode(1001, node)
   768  	if err != nil {
   769  		t.Fatalf("err: %v", err)
   770  	}
   771  
   772  	if !watchFired(ws) {
   773  		t.Fatalf("bad")
   774  	}
   775  
   776  	ws = memdb.NewWatchSet()
   777  	iter, err = state.NodesByIDPrefix(ws, "11")
   778  	if err != nil {
   779  		t.Fatalf("err: %v", err)
   780  	}
   781  
   782  	nodes = gatherNodes(iter)
   783  	if len(nodes) != 2 {
   784  		t.Fatalf("err: %v", err)
   785  	}
   786  
   787  	iter, err = state.NodesByIDPrefix(ws, "1111")
   788  	if err != nil {
   789  		t.Fatalf("err: %v", err)
   790  	}
   791  
   792  	nodes = gatherNodes(iter)
   793  	if len(nodes) != 1 {
   794  		t.Fatalf("err: %v", err)
   795  	}
   796  
   797  	if watchFired(ws) {
   798  		t.Fatalf("bad")
   799  	}
   800  }
   801  
   802  func TestStateStore_RestoreNode(t *testing.T) {
   803  	state := testStateStore(t)
   804  	node := mock.Node()
   805  
   806  	restore, err := state.Restore()
   807  	if err != nil {
   808  		t.Fatalf("err: %v", err)
   809  	}
   810  
   811  	err = restore.NodeRestore(node)
   812  	if err != nil {
   813  		t.Fatalf("err: %v", err)
   814  	}
   815  	restore.Commit()
   816  
   817  	ws := memdb.NewWatchSet()
   818  	out, err := state.NodeByID(ws, node.ID)
   819  	if err != nil {
   820  		t.Fatalf("err: %v", err)
   821  	}
   822  
   823  	if !reflect.DeepEqual(out, node) {
   824  		t.Fatalf("Bad: %#v %#v", out, node)
   825  	}
   826  }
   827  
   828  func TestStateStore_UpsertJob_Job(t *testing.T) {
   829  	state := testStateStore(t)
   830  	job := mock.Job()
   831  
   832  	// Create a watchset so we can test that upsert fires the watch
   833  	ws := memdb.NewWatchSet()
   834  	_, err := state.JobByID(ws, job.ID)
   835  	if err != nil {
   836  		t.Fatalf("bad: %v", err)
   837  	}
   838  
   839  	if err := state.UpsertJob(1000, job); err != nil {
   840  		t.Fatalf("err: %v", err)
   841  	}
   842  	if !watchFired(ws) {
   843  		t.Fatalf("bad")
   844  	}
   845  
   846  	ws = memdb.NewWatchSet()
   847  	out, err := state.JobByID(ws, job.ID)
   848  	if err != nil {
   849  		t.Fatalf("err: %v", err)
   850  	}
   851  
   852  	if !reflect.DeepEqual(job, out) {
   853  		t.Fatalf("bad: %#v %#v", job, out)
   854  	}
   855  
   856  	index, err := state.Index("jobs")
   857  	if err != nil {
   858  		t.Fatalf("err: %v", err)
   859  	}
   860  	if index != 1000 {
   861  		t.Fatalf("bad: %d", index)
   862  	}
   863  
   864  	summary, err := state.JobSummaryByID(ws, job.ID)
   865  	if err != nil {
   866  		t.Fatalf("err: %v", err)
   867  	}
   868  	if summary == nil {
   869  		t.Fatalf("nil summary")
   870  	}
   871  	if summary.JobID != job.ID {
   872  		t.Fatalf("bad summary id: %v", summary.JobID)
   873  	}
   874  	_, ok := summary.Summary["web"]
   875  	if !ok {
   876  		t.Fatalf("nil summary for task group")
   877  	}
   878  	if watchFired(ws) {
   879  		t.Fatalf("bad")
   880  	}
   881  
   882  	// Check the job versions
   883  	allVersions, err := state.JobVersionsByID(ws, job.ID)
   884  	if err != nil {
   885  		t.Fatalf("err: %v", err)
   886  	}
   887  	if len(allVersions) != 1 {
   888  		t.Fatalf("got %d; want 1", len(allVersions))
   889  	}
   890  
   891  	if a := allVersions[0]; a.ID != job.ID || a.Version != 0 {
   892  		t.Fatalf("bad: %v", a)
   893  	}
   894  
   895  	// Test the looking up the job by version returns the same results
   896  	vout, err := state.JobByIDAndVersion(ws, job.ID, 0)
   897  	if err != nil {
   898  		t.Fatalf("err: %v", err)
   899  	}
   900  
   901  	if !reflect.DeepEqual(out, vout) {
   902  		t.Fatalf("bad: %#v %#v", out, vout)
   903  	}
   904  }
   905  
   906  func TestStateStore_UpdateUpsertJob_Job(t *testing.T) {
   907  	state := testStateStore(t)
   908  	job := mock.Job()
   909  
   910  	// Create a watchset so we can test that upsert fires the watch
   911  	ws := memdb.NewWatchSet()
   912  	_, err := state.JobByID(ws, job.ID)
   913  	if err != nil {
   914  		t.Fatalf("bad: %v", err)
   915  	}
   916  
   917  	if err := state.UpsertJob(1000, job); err != nil {
   918  		t.Fatalf("err: %v", err)
   919  	}
   920  
   921  	job2 := mock.Job()
   922  	job2.ID = job.ID
   923  	job2.AllAtOnce = true
   924  	err = state.UpsertJob(1001, job2)
   925  	if err != nil {
   926  		t.Fatalf("err: %v", err)
   927  	}
   928  
   929  	if !watchFired(ws) {
   930  		t.Fatalf("bad")
   931  	}
   932  
   933  	ws = memdb.NewWatchSet()
   934  	out, err := state.JobByID(ws, job.ID)
   935  	if err != nil {
   936  		t.Fatalf("err: %v", err)
   937  	}
   938  
   939  	if !reflect.DeepEqual(job2, out) {
   940  		t.Fatalf("bad: %#v %#v", job2, out)
   941  	}
   942  
   943  	if out.CreateIndex != 1000 {
   944  		t.Fatalf("bad: %#v", out)
   945  	}
   946  	if out.ModifyIndex != 1001 {
   947  		t.Fatalf("bad: %#v", out)
   948  	}
   949  	if out.Version != 1 {
   950  		t.Fatalf("bad: %#v", out)
   951  	}
   952  
   953  	index, err := state.Index("jobs")
   954  	if err != nil {
   955  		t.Fatalf("err: %v", err)
   956  	}
   957  	if index != 1001 {
   958  		t.Fatalf("bad: %d", index)
   959  	}
   960  
   961  	// Test the looking up the job by version returns the same results
   962  	vout, err := state.JobByIDAndVersion(ws, job.ID, 1)
   963  	if err != nil {
   964  		t.Fatalf("err: %v", err)
   965  	}
   966  
   967  	if !reflect.DeepEqual(out, vout) {
   968  		t.Fatalf("bad: %#v %#v", out, vout)
   969  	}
   970  
   971  	// Test that the job summary remains the same if the job is updated but
   972  	// count remains same
   973  	summary, err := state.JobSummaryByID(ws, job.ID)
   974  	if err != nil {
   975  		t.Fatalf("err: %v", err)
   976  	}
   977  	if summary == nil {
   978  		t.Fatalf("nil summary")
   979  	}
   980  	if summary.JobID != job.ID {
   981  		t.Fatalf("bad summary id: %v", summary.JobID)
   982  	}
   983  	_, ok := summary.Summary["web"]
   984  	if !ok {
   985  		t.Fatalf("nil summary for task group")
   986  	}
   987  
   988  	// Check the job versions
   989  	allVersions, err := state.JobVersionsByID(ws, job.ID)
   990  	if err != nil {
   991  		t.Fatalf("err: %v", err)
   992  	}
   993  	if len(allVersions) != 2 {
   994  		t.Fatalf("got %d; want 1", len(allVersions))
   995  	}
   996  
   997  	if a := allVersions[0]; a.ID != job.ID || a.Version != 1 || !a.AllAtOnce {
   998  		t.Fatalf("bad: %+v", a)
   999  	}
  1000  	if a := allVersions[1]; a.ID != job.ID || a.Version != 0 || a.AllAtOnce {
  1001  		t.Fatalf("bad: %+v", a)
  1002  	}
  1003  
  1004  	if watchFired(ws) {
  1005  		t.Fatalf("bad")
  1006  	}
  1007  }
  1008  
  1009  func TestStateStore_UpdateUpsertJob_PeriodicJob(t *testing.T) {
  1010  	state := testStateStore(t)
  1011  	job := mock.PeriodicJob()
  1012  
  1013  	// Create a watchset so we can test that upsert fires the watch
  1014  	ws := memdb.NewWatchSet()
  1015  	_, err := state.JobByID(ws, job.ID)
  1016  	if err != nil {
  1017  		t.Fatalf("bad: %v", err)
  1018  	}
  1019  
  1020  	if err := state.UpsertJob(1000, job); err != nil {
  1021  		t.Fatalf("err: %v", err)
  1022  	}
  1023  
  1024  	// Create a child and an evaluation
  1025  	job2 := job.Copy()
  1026  	job2.Periodic = nil
  1027  	job2.ID = fmt.Sprintf("%v/%s-1490635020", job.ID, structs.PeriodicLaunchSuffix)
  1028  	err = state.UpsertJob(1001, job2)
  1029  	if err != nil {
  1030  		t.Fatalf("err: %v", err)
  1031  	}
  1032  
  1033  	eval := mock.Eval()
  1034  	eval.JobID = job2.ID
  1035  	err = state.UpsertEvals(1002, []*structs.Evaluation{eval})
  1036  	if err != nil {
  1037  		t.Fatalf("err: %v", err)
  1038  	}
  1039  
  1040  	job3 := job.Copy()
  1041  	job3.TaskGroups[0].Tasks[0].Name = "new name"
  1042  	err = state.UpsertJob(1003, job3)
  1043  	if err != nil {
  1044  		t.Fatalf("err: %v", err)
  1045  	}
  1046  
  1047  	if !watchFired(ws) {
  1048  		t.Fatalf("bad")
  1049  	}
  1050  
  1051  	ws = memdb.NewWatchSet()
  1052  	out, err := state.JobByID(ws, job.ID)
  1053  	if err != nil {
  1054  		t.Fatalf("err: %v", err)
  1055  	}
  1056  
  1057  	if s, e := out.Status, structs.JobStatusRunning; s != e {
  1058  		t.Fatalf("got status %v; want %v", s, e)
  1059  	}
  1060  
  1061  }
  1062  
  1063  // This test ensures that UpsertJob creates the EphemeralDisk is a job doesn't have
  1064  // one and clear out the task's disk resource asks
  1065  // COMPAT 0.4.1 -> 0.5
  1066  func TestStateStore_UpsertJob_NoEphemeralDisk(t *testing.T) {
  1067  	state := testStateStore(t)
  1068  	job := mock.Job()
  1069  
  1070  	// Set the EphemeralDisk to nil and set the tasks's DiskMB to 150
  1071  	job.TaskGroups[0].EphemeralDisk = nil
  1072  	job.TaskGroups[0].Tasks[0].Resources.DiskMB = 150
  1073  
  1074  	err := state.UpsertJob(1000, job)
  1075  	if err != nil {
  1076  		t.Fatalf("err: %v", err)
  1077  	}
  1078  
  1079  	ws := memdb.NewWatchSet()
  1080  	out, err := state.JobByID(ws, job.ID)
  1081  	if err != nil {
  1082  		t.Fatalf("err: %v", err)
  1083  	}
  1084  
  1085  	// Expect the state store to create the EphemeralDisk and clear out Tasks's
  1086  	// DiskMB
  1087  	expected := job.Copy()
  1088  	expected.TaskGroups[0].EphemeralDisk = &structs.EphemeralDisk{
  1089  		SizeMB: 150,
  1090  	}
  1091  	expected.TaskGroups[0].Tasks[0].Resources.DiskMB = 0
  1092  
  1093  	if !reflect.DeepEqual(expected, out) {
  1094  		t.Fatalf("bad: %#v %#v", expected, out)
  1095  	}
  1096  }
  1097  
  1098  // Upsert a job that is the child of a parent job and ensures its summary gets
  1099  // updated.
  1100  func TestStateStore_UpsertJob_ChildJob(t *testing.T) {
  1101  	state := testStateStore(t)
  1102  
  1103  	// Create a watchset so we can test that upsert fires the watch
  1104  	parent := mock.Job()
  1105  	ws := memdb.NewWatchSet()
  1106  	_, err := state.JobByID(ws, parent.ID)
  1107  	if err != nil {
  1108  		t.Fatalf("bad: %v", err)
  1109  	}
  1110  
  1111  	if err := state.UpsertJob(1000, parent); err != nil {
  1112  		t.Fatalf("err: %v", err)
  1113  	}
  1114  
  1115  	child := mock.Job()
  1116  	child.ParentID = parent.ID
  1117  	if err := state.UpsertJob(1001, child); err != nil {
  1118  		t.Fatalf("err: %v", err)
  1119  	}
  1120  
  1121  	summary, err := state.JobSummaryByID(ws, parent.ID)
  1122  	if err != nil {
  1123  		t.Fatalf("err: %v", err)
  1124  	}
  1125  	if summary == nil {
  1126  		t.Fatalf("nil summary")
  1127  	}
  1128  	if summary.JobID != parent.ID {
  1129  		t.Fatalf("bad summary id: %v", parent.ID)
  1130  	}
  1131  	if summary.Children == nil {
  1132  		t.Fatalf("nil children summary")
  1133  	}
  1134  	if summary.Children.Pending != 1 || summary.Children.Running != 0 || summary.Children.Dead != 0 {
  1135  		t.Fatalf("bad children summary: %v", summary.Children)
  1136  	}
  1137  	if !watchFired(ws) {
  1138  		t.Fatalf("bad")
  1139  	}
  1140  }
  1141  
  1142  func TestStateStore_UpdateUpsertJob_JobVersion(t *testing.T) {
  1143  	state := testStateStore(t)
  1144  
  1145  	// Create a job and mark it as stable
  1146  	job := mock.Job()
  1147  	job.Stable = true
  1148  	job.Priority = 0
  1149  
  1150  	// Create a watchset so we can test that upsert fires the watch
  1151  	ws := memdb.NewWatchSet()
  1152  	_, err := state.JobVersionsByID(ws, job.ID)
  1153  	if err != nil {
  1154  		t.Fatalf("bad: %v", err)
  1155  	}
  1156  
  1157  	if err := state.UpsertJob(1000, job); err != nil {
  1158  		t.Fatalf("err: %v", err)
  1159  	}
  1160  
  1161  	if !watchFired(ws) {
  1162  		t.Fatalf("bad")
  1163  	}
  1164  
  1165  	var finalJob *structs.Job
  1166  	for i := 1; i < 20; i++ {
  1167  		finalJob = mock.Job()
  1168  		finalJob.ID = job.ID
  1169  		finalJob.Priority = i
  1170  		err = state.UpsertJob(uint64(1000+i), finalJob)
  1171  		if err != nil {
  1172  			t.Fatalf("err: %v", err)
  1173  		}
  1174  	}
  1175  
  1176  	ws = memdb.NewWatchSet()
  1177  	out, err := state.JobByID(ws, job.ID)
  1178  	if err != nil {
  1179  		t.Fatalf("err: %v", err)
  1180  	}
  1181  
  1182  	if !reflect.DeepEqual(finalJob, out) {
  1183  		t.Fatalf("bad: %#v %#v", finalJob, out)
  1184  	}
  1185  
  1186  	if out.CreateIndex != 1000 {
  1187  		t.Fatalf("bad: %#v", out)
  1188  	}
  1189  	if out.ModifyIndex != 1019 {
  1190  		t.Fatalf("bad: %#v", out)
  1191  	}
  1192  	if out.Version != 19 {
  1193  		t.Fatalf("bad: %#v", out)
  1194  	}
  1195  
  1196  	index, err := state.Index("job_version")
  1197  	if err != nil {
  1198  		t.Fatalf("err: %v", err)
  1199  	}
  1200  	if index != 1019 {
  1201  		t.Fatalf("bad: %d", index)
  1202  	}
  1203  
  1204  	// Check the job versions
  1205  	allVersions, err := state.JobVersionsByID(ws, job.ID)
  1206  	if err != nil {
  1207  		t.Fatalf("err: %v", err)
  1208  	}
  1209  	if len(allVersions) != structs.JobTrackedVersions {
  1210  		t.Fatalf("got %d; want 1", len(allVersions))
  1211  	}
  1212  
  1213  	if a := allVersions[0]; a.ID != job.ID || a.Version != 19 || a.Priority != 19 {
  1214  		t.Fatalf("bad: %+v", a)
  1215  	}
  1216  	if a := allVersions[1]; a.ID != job.ID || a.Version != 18 || a.Priority != 18 {
  1217  		t.Fatalf("bad: %+v", a)
  1218  	}
  1219  
  1220  	// Ensure we didn't delete the stable job
  1221  	if a := allVersions[structs.JobTrackedVersions-1]; a.ID != job.ID ||
  1222  		a.Version != 0 || a.Priority != 0 || !a.Stable {
  1223  		t.Fatalf("bad: %+v", a)
  1224  	}
  1225  
  1226  	if watchFired(ws) {
  1227  		t.Fatalf("bad")
  1228  	}
  1229  }
  1230  
  1231  func TestStateStore_DeleteJob_Job(t *testing.T) {
  1232  	state := testStateStore(t)
  1233  	job := mock.Job()
  1234  
  1235  	err := state.UpsertJob(1000, job)
  1236  	if err != nil {
  1237  		t.Fatalf("err: %v", err)
  1238  	}
  1239  
  1240  	// Create a watchset so we can test that delete fires the watch
  1241  	ws := memdb.NewWatchSet()
  1242  	if _, err := state.JobByID(ws, job.ID); err != nil {
  1243  		t.Fatalf("bad: %v", err)
  1244  	}
  1245  
  1246  	err = state.DeleteJob(1001, job.ID)
  1247  	if err != nil {
  1248  		t.Fatalf("err: %v", err)
  1249  	}
  1250  
  1251  	if !watchFired(ws) {
  1252  		t.Fatalf("bad")
  1253  	}
  1254  
  1255  	ws = memdb.NewWatchSet()
  1256  	out, err := state.JobByID(ws, job.ID)
  1257  	if err != nil {
  1258  		t.Fatalf("err: %v", err)
  1259  	}
  1260  
  1261  	if out != nil {
  1262  		t.Fatalf("bad: %#v %#v", job, out)
  1263  	}
  1264  
  1265  	index, err := state.Index("jobs")
  1266  	if err != nil {
  1267  		t.Fatalf("err: %v", err)
  1268  	}
  1269  	if index != 1001 {
  1270  		t.Fatalf("bad: %d", index)
  1271  	}
  1272  
  1273  	summary, err := state.JobSummaryByID(ws, job.ID)
  1274  	if err != nil {
  1275  		t.Fatalf("err: %v", err)
  1276  	}
  1277  	if summary != nil {
  1278  		t.Fatalf("expected summary to be nil, but got: %v", summary)
  1279  	}
  1280  
  1281  	index, err = state.Index("job_summary")
  1282  	if err != nil {
  1283  		t.Fatalf("err: %v", err)
  1284  	}
  1285  	if index != 1001 {
  1286  		t.Fatalf("bad: %d", index)
  1287  	}
  1288  
  1289  	versions, err := state.JobVersionsByID(ws, job.ID)
  1290  	if err != nil {
  1291  		t.Fatalf("err: %v", err)
  1292  	}
  1293  	if len(versions) != 0 {
  1294  		t.Fatalf("expected no job versions")
  1295  	}
  1296  
  1297  	index, err = state.Index("job_summary")
  1298  	if err != nil {
  1299  		t.Fatalf("err: %v", err)
  1300  	}
  1301  	if index != 1001 {
  1302  		t.Fatalf("bad: %d", index)
  1303  	}
  1304  
  1305  	if watchFired(ws) {
  1306  		t.Fatalf("bad")
  1307  	}
  1308  }
  1309  
  1310  func TestStateStore_DeleteJob_ChildJob(t *testing.T) {
  1311  	state := testStateStore(t)
  1312  
  1313  	parent := mock.Job()
  1314  	if err := state.UpsertJob(998, parent); err != nil {
  1315  		t.Fatalf("err: %v", err)
  1316  	}
  1317  
  1318  	child := mock.Job()
  1319  	child.ParentID = parent.ID
  1320  
  1321  	if err := state.UpsertJob(999, child); err != nil {
  1322  		t.Fatalf("err: %v", err)
  1323  	}
  1324  
  1325  	// Create a watchset so we can test that delete fires the watch
  1326  	ws := memdb.NewWatchSet()
  1327  	if _, err := state.JobSummaryByID(ws, parent.ID); err != nil {
  1328  		t.Fatalf("bad: %v", err)
  1329  	}
  1330  
  1331  	err := state.DeleteJob(1001, child.ID)
  1332  	if err != nil {
  1333  		t.Fatalf("err: %v", err)
  1334  	}
  1335  	if !watchFired(ws) {
  1336  		t.Fatalf("bad")
  1337  	}
  1338  
  1339  	ws = memdb.NewWatchSet()
  1340  	summary, err := state.JobSummaryByID(ws, parent.ID)
  1341  	if err != nil {
  1342  		t.Fatalf("err: %v", err)
  1343  	}
  1344  	if summary == nil {
  1345  		t.Fatalf("nil summary")
  1346  	}
  1347  	if summary.JobID != parent.ID {
  1348  		t.Fatalf("bad summary id: %v", parent.ID)
  1349  	}
  1350  	if summary.Children == nil {
  1351  		t.Fatalf("nil children summary")
  1352  	}
  1353  	if summary.Children.Pending != 0 || summary.Children.Running != 0 || summary.Children.Dead != 1 {
  1354  		t.Fatalf("bad children summary: %v", summary.Children)
  1355  	}
  1356  	if watchFired(ws) {
  1357  		t.Fatalf("bad")
  1358  	}
  1359  }
  1360  
  1361  func TestStateStore_Jobs(t *testing.T) {
  1362  	state := testStateStore(t)
  1363  	var jobs []*structs.Job
  1364  
  1365  	for i := 0; i < 10; i++ {
  1366  		job := mock.Job()
  1367  		jobs = append(jobs, job)
  1368  
  1369  		err := state.UpsertJob(1000+uint64(i), job)
  1370  		if err != nil {
  1371  			t.Fatalf("err: %v", err)
  1372  		}
  1373  	}
  1374  
  1375  	ws := memdb.NewWatchSet()
  1376  	iter, err := state.Jobs(ws)
  1377  	if err != nil {
  1378  		t.Fatalf("err: %v", err)
  1379  	}
  1380  
  1381  	var out []*structs.Job
  1382  	for {
  1383  		raw := iter.Next()
  1384  		if raw == nil {
  1385  			break
  1386  		}
  1387  		out = append(out, raw.(*structs.Job))
  1388  	}
  1389  
  1390  	sort.Sort(JobIDSort(jobs))
  1391  	sort.Sort(JobIDSort(out))
  1392  
  1393  	if !reflect.DeepEqual(jobs, out) {
  1394  		t.Fatalf("bad: %#v %#v", jobs, out)
  1395  	}
  1396  	if watchFired(ws) {
  1397  		t.Fatalf("bad")
  1398  	}
  1399  }
  1400  
  1401  func TestStateStore_JobVersions(t *testing.T) {
  1402  	state := testStateStore(t)
  1403  	var jobs []*structs.Job
  1404  
  1405  	for i := 0; i < 10; i++ {
  1406  		job := mock.Job()
  1407  		jobs = append(jobs, job)
  1408  
  1409  		err := state.UpsertJob(1000+uint64(i), job)
  1410  		if err != nil {
  1411  			t.Fatalf("err: %v", err)
  1412  		}
  1413  	}
  1414  
  1415  	ws := memdb.NewWatchSet()
  1416  	iter, err := state.JobVersions(ws)
  1417  	if err != nil {
  1418  		t.Fatalf("err: %v", err)
  1419  	}
  1420  
  1421  	var out []*structs.Job
  1422  	for {
  1423  		raw := iter.Next()
  1424  		if raw == nil {
  1425  			break
  1426  		}
  1427  		out = append(out, raw.(*structs.Job))
  1428  	}
  1429  
  1430  	sort.Sort(JobIDSort(jobs))
  1431  	sort.Sort(JobIDSort(out))
  1432  
  1433  	if !reflect.DeepEqual(jobs, out) {
  1434  		t.Fatalf("bad: %#v %#v", jobs, out)
  1435  	}
  1436  	if watchFired(ws) {
  1437  		t.Fatalf("bad")
  1438  	}
  1439  }
  1440  
  1441  func TestStateStore_JobsByIDPrefix(t *testing.T) {
  1442  	state := testStateStore(t)
  1443  	job := mock.Job()
  1444  
  1445  	job.ID = "redis"
  1446  	err := state.UpsertJob(1000, job)
  1447  	if err != nil {
  1448  		t.Fatalf("err: %v", err)
  1449  	}
  1450  
  1451  	ws := memdb.NewWatchSet()
  1452  	iter, err := state.JobsByIDPrefix(ws, job.ID)
  1453  	if err != nil {
  1454  		t.Fatalf("err: %v", err)
  1455  	}
  1456  
  1457  	gatherJobs := func(iter memdb.ResultIterator) []*structs.Job {
  1458  		var jobs []*structs.Job
  1459  		for {
  1460  			raw := iter.Next()
  1461  			if raw == nil {
  1462  				break
  1463  			}
  1464  			jobs = append(jobs, raw.(*structs.Job))
  1465  		}
  1466  		return jobs
  1467  	}
  1468  
  1469  	jobs := gatherJobs(iter)
  1470  	if len(jobs) != 1 {
  1471  		t.Fatalf("err: %v", err)
  1472  	}
  1473  
  1474  	iter, err = state.JobsByIDPrefix(ws, "re")
  1475  	if err != nil {
  1476  		t.Fatalf("err: %v", err)
  1477  	}
  1478  
  1479  	jobs = gatherJobs(iter)
  1480  	if len(jobs) != 1 {
  1481  		t.Fatalf("err: %v", err)
  1482  	}
  1483  	if watchFired(ws) {
  1484  		t.Fatalf("bad")
  1485  	}
  1486  
  1487  	job = mock.Job()
  1488  	job.ID = "riak"
  1489  	err = state.UpsertJob(1001, job)
  1490  	if err != nil {
  1491  		t.Fatalf("err: %v", err)
  1492  	}
  1493  
  1494  	if !watchFired(ws) {
  1495  		t.Fatalf("bad")
  1496  	}
  1497  
  1498  	ws = memdb.NewWatchSet()
  1499  	iter, err = state.JobsByIDPrefix(ws, "r")
  1500  	if err != nil {
  1501  		t.Fatalf("err: %v", err)
  1502  	}
  1503  
  1504  	jobs = gatherJobs(iter)
  1505  	if len(jobs) != 2 {
  1506  		t.Fatalf("err: %v", err)
  1507  	}
  1508  
  1509  	iter, err = state.JobsByIDPrefix(ws, "ri")
  1510  	if err != nil {
  1511  		t.Fatalf("err: %v", err)
  1512  	}
  1513  
  1514  	jobs = gatherJobs(iter)
  1515  	if len(jobs) != 1 {
  1516  		t.Fatalf("err: %v", err)
  1517  	}
  1518  	if watchFired(ws) {
  1519  		t.Fatalf("bad")
  1520  	}
  1521  }
  1522  
  1523  func TestStateStore_JobsByPeriodic(t *testing.T) {
  1524  	state := testStateStore(t)
  1525  	var periodic, nonPeriodic []*structs.Job
  1526  
  1527  	for i := 0; i < 10; i++ {
  1528  		job := mock.Job()
  1529  		nonPeriodic = append(nonPeriodic, job)
  1530  
  1531  		err := state.UpsertJob(1000+uint64(i), job)
  1532  		if err != nil {
  1533  			t.Fatalf("err: %v", err)
  1534  		}
  1535  	}
  1536  
  1537  	for i := 0; i < 10; i++ {
  1538  		job := mock.PeriodicJob()
  1539  		periodic = append(periodic, job)
  1540  
  1541  		err := state.UpsertJob(2000+uint64(i), job)
  1542  		if err != nil {
  1543  			t.Fatalf("err: %v", err)
  1544  		}
  1545  	}
  1546  
  1547  	ws := memdb.NewWatchSet()
  1548  	iter, err := state.JobsByPeriodic(ws, true)
  1549  	if err != nil {
  1550  		t.Fatalf("err: %v", err)
  1551  	}
  1552  
  1553  	var outPeriodic []*structs.Job
  1554  	for {
  1555  		raw := iter.Next()
  1556  		if raw == nil {
  1557  			break
  1558  		}
  1559  		outPeriodic = append(outPeriodic, raw.(*structs.Job))
  1560  	}
  1561  
  1562  	iter, err = state.JobsByPeriodic(ws, false)
  1563  	if err != nil {
  1564  		t.Fatalf("err: %v", err)
  1565  	}
  1566  
  1567  	var outNonPeriodic []*structs.Job
  1568  	for {
  1569  		raw := iter.Next()
  1570  		if raw == nil {
  1571  			break
  1572  		}
  1573  		outNonPeriodic = append(outNonPeriodic, raw.(*structs.Job))
  1574  	}
  1575  
  1576  	sort.Sort(JobIDSort(periodic))
  1577  	sort.Sort(JobIDSort(nonPeriodic))
  1578  	sort.Sort(JobIDSort(outPeriodic))
  1579  	sort.Sort(JobIDSort(outNonPeriodic))
  1580  
  1581  	if !reflect.DeepEqual(periodic, outPeriodic) {
  1582  		t.Fatalf("bad: %#v %#v", periodic, outPeriodic)
  1583  	}
  1584  
  1585  	if !reflect.DeepEqual(nonPeriodic, outNonPeriodic) {
  1586  		t.Fatalf("bad: %#v %#v", nonPeriodic, outNonPeriodic)
  1587  	}
  1588  	if watchFired(ws) {
  1589  		t.Fatalf("bad")
  1590  	}
  1591  }
  1592  
  1593  func TestStateStore_JobsByScheduler(t *testing.T) {
  1594  	state := testStateStore(t)
  1595  	var serviceJobs []*structs.Job
  1596  	var sysJobs []*structs.Job
  1597  
  1598  	for i := 0; i < 10; i++ {
  1599  		job := mock.Job()
  1600  		serviceJobs = append(serviceJobs, job)
  1601  
  1602  		err := state.UpsertJob(1000+uint64(i), job)
  1603  		if err != nil {
  1604  			t.Fatalf("err: %v", err)
  1605  		}
  1606  	}
  1607  
  1608  	for i := 0; i < 10; i++ {
  1609  		job := mock.SystemJob()
  1610  		job.Status = structs.JobStatusRunning
  1611  		sysJobs = append(sysJobs, job)
  1612  
  1613  		err := state.UpsertJob(2000+uint64(i), job)
  1614  		if err != nil {
  1615  			t.Fatalf("err: %v", err)
  1616  		}
  1617  	}
  1618  
  1619  	ws := memdb.NewWatchSet()
  1620  	iter, err := state.JobsByScheduler(ws, "service")
  1621  	if err != nil {
  1622  		t.Fatalf("err: %v", err)
  1623  	}
  1624  
  1625  	var outService []*structs.Job
  1626  	for {
  1627  		raw := iter.Next()
  1628  		if raw == nil {
  1629  			break
  1630  		}
  1631  		outService = append(outService, raw.(*structs.Job))
  1632  	}
  1633  
  1634  	iter, err = state.JobsByScheduler(ws, "system")
  1635  	if err != nil {
  1636  		t.Fatalf("err: %v", err)
  1637  	}
  1638  
  1639  	var outSystem []*structs.Job
  1640  	for {
  1641  		raw := iter.Next()
  1642  		if raw == nil {
  1643  			break
  1644  		}
  1645  		outSystem = append(outSystem, raw.(*structs.Job))
  1646  	}
  1647  
  1648  	sort.Sort(JobIDSort(serviceJobs))
  1649  	sort.Sort(JobIDSort(sysJobs))
  1650  	sort.Sort(JobIDSort(outService))
  1651  	sort.Sort(JobIDSort(outSystem))
  1652  
  1653  	if !reflect.DeepEqual(serviceJobs, outService) {
  1654  		t.Fatalf("bad: %#v %#v", serviceJobs, outService)
  1655  	}
  1656  
  1657  	if !reflect.DeepEqual(sysJobs, outSystem) {
  1658  		t.Fatalf("bad: %#v %#v", sysJobs, outSystem)
  1659  	}
  1660  	if watchFired(ws) {
  1661  		t.Fatalf("bad")
  1662  	}
  1663  }
  1664  
  1665  func TestStateStore_JobsByGC(t *testing.T) {
  1666  	state := testStateStore(t)
  1667  	gc, nonGc := make(map[string]struct{}), make(map[string]struct{})
  1668  
  1669  	for i := 0; i < 20; i++ {
  1670  		var job *structs.Job
  1671  		if i%2 == 0 {
  1672  			job = mock.Job()
  1673  		} else {
  1674  			job = mock.PeriodicJob()
  1675  		}
  1676  		nonGc[job.ID] = struct{}{}
  1677  
  1678  		if err := state.UpsertJob(1000+uint64(i), job); err != nil {
  1679  			t.Fatalf("err: %v", err)
  1680  		}
  1681  	}
  1682  
  1683  	for i := 0; i < 20; i += 2 {
  1684  		job := mock.Job()
  1685  		job.Type = structs.JobTypeBatch
  1686  		gc[job.ID] = struct{}{}
  1687  
  1688  		if err := state.UpsertJob(2000+uint64(i), job); err != nil {
  1689  			t.Fatalf("err: %v", err)
  1690  		}
  1691  
  1692  		// Create an eval for it
  1693  		eval := mock.Eval()
  1694  		eval.JobID = job.ID
  1695  		eval.Status = structs.EvalStatusComplete
  1696  		if err := state.UpsertEvals(2000+uint64(i+1), []*structs.Evaluation{eval}); err != nil {
  1697  			t.Fatalf("err: %v", err)
  1698  		}
  1699  
  1700  	}
  1701  
  1702  	ws := memdb.NewWatchSet()
  1703  	iter, err := state.JobsByGC(ws, true)
  1704  	if err != nil {
  1705  		t.Fatalf("err: %v", err)
  1706  	}
  1707  
  1708  	outGc := make(map[string]struct{})
  1709  	for i := iter.Next(); i != nil; i = iter.Next() {
  1710  		j := i.(*structs.Job)
  1711  		outGc[j.ID] = struct{}{}
  1712  	}
  1713  
  1714  	iter, err = state.JobsByGC(ws, false)
  1715  	if err != nil {
  1716  		t.Fatalf("err: %v", err)
  1717  	}
  1718  
  1719  	outNonGc := make(map[string]struct{})
  1720  	for i := iter.Next(); i != nil; i = iter.Next() {
  1721  		j := i.(*structs.Job)
  1722  		outNonGc[j.ID] = struct{}{}
  1723  	}
  1724  
  1725  	if !reflect.DeepEqual(gc, outGc) {
  1726  		t.Fatalf("bad: %#v %#v", gc, outGc)
  1727  	}
  1728  
  1729  	if !reflect.DeepEqual(nonGc, outNonGc) {
  1730  		t.Fatalf("bad: %#v %#v", nonGc, outNonGc)
  1731  	}
  1732  	if watchFired(ws) {
  1733  		t.Fatalf("bad")
  1734  	}
  1735  }
  1736  
  1737  func TestStateStore_RestoreJob(t *testing.T) {
  1738  	state := testStateStore(t)
  1739  	job := mock.Job()
  1740  
  1741  	restore, err := state.Restore()
  1742  	if err != nil {
  1743  		t.Fatalf("err: %v", err)
  1744  	}
  1745  
  1746  	err = restore.JobRestore(job)
  1747  	if err != nil {
  1748  		t.Fatalf("err: %v", err)
  1749  	}
  1750  	restore.Commit()
  1751  
  1752  	ws := memdb.NewWatchSet()
  1753  	out, err := state.JobByID(ws, job.ID)
  1754  	if err != nil {
  1755  		t.Fatalf("err: %v", err)
  1756  	}
  1757  
  1758  	if !reflect.DeepEqual(out, job) {
  1759  		t.Fatalf("Bad: %#v %#v", out, job)
  1760  	}
  1761  }
  1762  
  1763  // This test ensures that the state restore creates the EphemeralDisk for a job if
  1764  // it doesn't have one
  1765  // COMPAT 0.4.1 -> 0.5
  1766  func TestStateStore_Jobs_NoEphemeralDisk(t *testing.T) {
  1767  	state := testStateStore(t)
  1768  	job := mock.Job()
  1769  
  1770  	// Set EphemeralDisk to nil and set the DiskMB to 150
  1771  	job.TaskGroups[0].EphemeralDisk = nil
  1772  	job.TaskGroups[0].Tasks[0].Resources.DiskMB = 150
  1773  
  1774  	restore, err := state.Restore()
  1775  	if err != nil {
  1776  		t.Fatalf("err: %v", err)
  1777  	}
  1778  
  1779  	err = restore.JobRestore(job)
  1780  	if err != nil {
  1781  		t.Fatalf("err: %v", err)
  1782  	}
  1783  	restore.Commit()
  1784  
  1785  	ws := memdb.NewWatchSet()
  1786  	out, err := state.JobByID(ws, job.ID)
  1787  	if err != nil {
  1788  		t.Fatalf("err: %v", err)
  1789  	}
  1790  
  1791  	// Expect job to have local disk and clear out the task's disk resource ask
  1792  	expected := job.Copy()
  1793  	expected.TaskGroups[0].EphemeralDisk = &structs.EphemeralDisk{
  1794  		SizeMB: 150,
  1795  	}
  1796  	expected.TaskGroups[0].Tasks[0].Resources.DiskMB = 0
  1797  	if !reflect.DeepEqual(out, expected) {
  1798  		t.Fatalf("Bad: %#v %#v", out, job)
  1799  	}
  1800  }
  1801  
  1802  func TestStateStore_UpsertPeriodicLaunch(t *testing.T) {
  1803  	state := testStateStore(t)
  1804  	job := mock.Job()
  1805  	launch := &structs.PeriodicLaunch{ID: job.ID, Launch: time.Now()}
  1806  
  1807  	// Create a watchset so we can test that upsert fires the watch
  1808  	ws := memdb.NewWatchSet()
  1809  	if _, err := state.PeriodicLaunchByID(ws, launch.ID); err != nil {
  1810  		t.Fatalf("bad: %v", err)
  1811  	}
  1812  
  1813  	err := state.UpsertPeriodicLaunch(1000, launch)
  1814  	if err != nil {
  1815  		t.Fatalf("err: %v", err)
  1816  	}
  1817  
  1818  	if !watchFired(ws) {
  1819  		t.Fatalf("bad")
  1820  	}
  1821  
  1822  	ws = memdb.NewWatchSet()
  1823  	out, err := state.PeriodicLaunchByID(ws, job.ID)
  1824  	if err != nil {
  1825  		t.Fatalf("err: %v", err)
  1826  	}
  1827  	if out.CreateIndex != 1000 {
  1828  		t.Fatalf("bad: %#v", out)
  1829  	}
  1830  	if out.ModifyIndex != 1000 {
  1831  		t.Fatalf("bad: %#v", out)
  1832  	}
  1833  
  1834  	if !reflect.DeepEqual(launch, out) {
  1835  		t.Fatalf("bad: %#v %#v", job, out)
  1836  	}
  1837  
  1838  	index, err := state.Index("periodic_launch")
  1839  	if err != nil {
  1840  		t.Fatalf("err: %v", err)
  1841  	}
  1842  	if index != 1000 {
  1843  		t.Fatalf("bad: %d", index)
  1844  	}
  1845  
  1846  	if watchFired(ws) {
  1847  		t.Fatalf("bad")
  1848  	}
  1849  }
  1850  
  1851  func TestStateStore_UpdateUpsertPeriodicLaunch(t *testing.T) {
  1852  	state := testStateStore(t)
  1853  	job := mock.Job()
  1854  	launch := &structs.PeriodicLaunch{ID: job.ID, Launch: time.Now()}
  1855  
  1856  	err := state.UpsertPeriodicLaunch(1000, launch)
  1857  	if err != nil {
  1858  		t.Fatalf("err: %v", err)
  1859  	}
  1860  
  1861  	// Create a watchset so we can test that upsert fires the watch
  1862  	ws := memdb.NewWatchSet()
  1863  	if _, err := state.PeriodicLaunchByID(ws, launch.ID); err != nil {
  1864  		t.Fatalf("bad: %v", err)
  1865  	}
  1866  
  1867  	launch2 := &structs.PeriodicLaunch{
  1868  		ID:     job.ID,
  1869  		Launch: launch.Launch.Add(1 * time.Second),
  1870  	}
  1871  	err = state.UpsertPeriodicLaunch(1001, launch2)
  1872  	if err != nil {
  1873  		t.Fatalf("err: %v", err)
  1874  	}
  1875  
  1876  	if !watchFired(ws) {
  1877  		t.Fatalf("bad")
  1878  	}
  1879  
  1880  	ws = memdb.NewWatchSet()
  1881  	out, err := state.PeriodicLaunchByID(ws, job.ID)
  1882  	if err != nil {
  1883  		t.Fatalf("err: %v", err)
  1884  	}
  1885  	if out.CreateIndex != 1000 {
  1886  		t.Fatalf("bad: %#v", out)
  1887  	}
  1888  	if out.ModifyIndex != 1001 {
  1889  		t.Fatalf("bad: %#v", out)
  1890  	}
  1891  
  1892  	if !reflect.DeepEqual(launch2, out) {
  1893  		t.Fatalf("bad: %#v %#v", launch2, out)
  1894  	}
  1895  
  1896  	index, err := state.Index("periodic_launch")
  1897  	if err != nil {
  1898  		t.Fatalf("err: %v", err)
  1899  	}
  1900  	if index != 1001 {
  1901  		t.Fatalf("bad: %d", index)
  1902  	}
  1903  
  1904  	if watchFired(ws) {
  1905  		t.Fatalf("bad")
  1906  	}
  1907  }
  1908  
  1909  func TestStateStore_DeletePeriodicLaunch(t *testing.T) {
  1910  	state := testStateStore(t)
  1911  	job := mock.Job()
  1912  	launch := &structs.PeriodicLaunch{ID: job.ID, Launch: time.Now()}
  1913  
  1914  	err := state.UpsertPeriodicLaunch(1000, launch)
  1915  	if err != nil {
  1916  		t.Fatalf("err: %v", err)
  1917  	}
  1918  
  1919  	// Create a watchset so we can test that delete fires the watch
  1920  	ws := memdb.NewWatchSet()
  1921  	if _, err := state.PeriodicLaunchByID(ws, launch.ID); err != nil {
  1922  		t.Fatalf("bad: %v", err)
  1923  	}
  1924  
  1925  	err = state.DeletePeriodicLaunch(1001, launch.ID)
  1926  	if err != nil {
  1927  		t.Fatalf("err: %v", err)
  1928  	}
  1929  
  1930  	if !watchFired(ws) {
  1931  		t.Fatalf("bad")
  1932  	}
  1933  
  1934  	ws = memdb.NewWatchSet()
  1935  	out, err := state.PeriodicLaunchByID(ws, job.ID)
  1936  	if err != nil {
  1937  		t.Fatalf("err: %v", err)
  1938  	}
  1939  
  1940  	if out != nil {
  1941  		t.Fatalf("bad: %#v %#v", job, out)
  1942  	}
  1943  
  1944  	index, err := state.Index("periodic_launch")
  1945  	if err != nil {
  1946  		t.Fatalf("err: %v", err)
  1947  	}
  1948  	if index != 1001 {
  1949  		t.Fatalf("bad: %d", index)
  1950  	}
  1951  
  1952  	if watchFired(ws) {
  1953  		t.Fatalf("bad")
  1954  	}
  1955  }
  1956  
  1957  func TestStateStore_PeriodicLaunches(t *testing.T) {
  1958  	state := testStateStore(t)
  1959  	var launches []*structs.PeriodicLaunch
  1960  
  1961  	for i := 0; i < 10; i++ {
  1962  		job := mock.Job()
  1963  		launch := &structs.PeriodicLaunch{ID: job.ID, Launch: time.Now()}
  1964  		launches = append(launches, launch)
  1965  
  1966  		err := state.UpsertPeriodicLaunch(1000+uint64(i), launch)
  1967  		if err != nil {
  1968  			t.Fatalf("err: %v", err)
  1969  		}
  1970  	}
  1971  
  1972  	ws := memdb.NewWatchSet()
  1973  	iter, err := state.PeriodicLaunches(ws)
  1974  	if err != nil {
  1975  		t.Fatalf("err: %v", err)
  1976  	}
  1977  
  1978  	out := make(map[string]*structs.PeriodicLaunch, 10)
  1979  	for {
  1980  		raw := iter.Next()
  1981  		if raw == nil {
  1982  			break
  1983  		}
  1984  		launch := raw.(*structs.PeriodicLaunch)
  1985  		if _, ok := out[launch.ID]; ok {
  1986  			t.Fatalf("duplicate: %v", launch.ID)
  1987  		}
  1988  
  1989  		out[launch.ID] = launch
  1990  	}
  1991  
  1992  	for _, launch := range launches {
  1993  		l, ok := out[launch.ID]
  1994  		if !ok {
  1995  			t.Fatalf("bad %v", launch.ID)
  1996  		}
  1997  
  1998  		if !reflect.DeepEqual(launch, l) {
  1999  			t.Fatalf("bad: %#v %#v", launch, l)
  2000  		}
  2001  
  2002  		delete(out, launch.ID)
  2003  	}
  2004  
  2005  	if len(out) != 0 {
  2006  		t.Fatalf("leftover: %#v", out)
  2007  	}
  2008  
  2009  	if watchFired(ws) {
  2010  		t.Fatalf("bad")
  2011  	}
  2012  }
  2013  
  2014  func TestStateStore_RestorePeriodicLaunch(t *testing.T) {
  2015  	state := testStateStore(t)
  2016  	job := mock.Job()
  2017  	launch := &structs.PeriodicLaunch{ID: job.ID, Launch: time.Now()}
  2018  
  2019  	restore, err := state.Restore()
  2020  	if err != nil {
  2021  		t.Fatalf("err: %v", err)
  2022  	}
  2023  
  2024  	err = restore.PeriodicLaunchRestore(launch)
  2025  	if err != nil {
  2026  		t.Fatalf("err: %v", err)
  2027  	}
  2028  	restore.Commit()
  2029  
  2030  	ws := memdb.NewWatchSet()
  2031  	out, err := state.PeriodicLaunchByID(ws, job.ID)
  2032  	if err != nil {
  2033  		t.Fatalf("err: %v", err)
  2034  	}
  2035  
  2036  	if !reflect.DeepEqual(out, launch) {
  2037  		t.Fatalf("Bad: %#v %#v", out, job)
  2038  	}
  2039  
  2040  	if watchFired(ws) {
  2041  		t.Fatalf("bad")
  2042  	}
  2043  }
  2044  
  2045  func TestStateStore_RestoreJobVersion(t *testing.T) {
  2046  	state := testStateStore(t)
  2047  	job := mock.Job()
  2048  
  2049  	restore, err := state.Restore()
  2050  	if err != nil {
  2051  		t.Fatalf("err: %v", err)
  2052  	}
  2053  
  2054  	err = restore.JobVersionRestore(job)
  2055  	if err != nil {
  2056  		t.Fatalf("err: %v", err)
  2057  	}
  2058  	restore.Commit()
  2059  
  2060  	ws := memdb.NewWatchSet()
  2061  	out, err := state.JobByIDAndVersion(ws, job.ID, job.Version)
  2062  	if err != nil {
  2063  		t.Fatalf("err: %v", err)
  2064  	}
  2065  
  2066  	if !reflect.DeepEqual(out, job) {
  2067  		t.Fatalf("Bad: %#v %#v", out, job)
  2068  	}
  2069  
  2070  	if watchFired(ws) {
  2071  		t.Fatalf("bad")
  2072  	}
  2073  }
  2074  
  2075  func TestStateStore_RestoreDeployment(t *testing.T) {
  2076  	state := testStateStore(t)
  2077  	d := mock.Deployment()
  2078  
  2079  	restore, err := state.Restore()
  2080  	if err != nil {
  2081  		t.Fatalf("err: %v", err)
  2082  	}
  2083  
  2084  	err = restore.DeploymentRestore(d)
  2085  	if err != nil {
  2086  		t.Fatalf("err: %v", err)
  2087  	}
  2088  	restore.Commit()
  2089  
  2090  	ws := memdb.NewWatchSet()
  2091  	out, err := state.DeploymentByID(ws, d.ID)
  2092  	if err != nil {
  2093  		t.Fatalf("err: %v", err)
  2094  	}
  2095  
  2096  	if !reflect.DeepEqual(out, d) {
  2097  		t.Fatalf("Bad: %#v %#v", out, d)
  2098  	}
  2099  
  2100  	if watchFired(ws) {
  2101  		t.Fatalf("bad")
  2102  	}
  2103  }
  2104  
  2105  func TestStateStore_RestoreJobSummary(t *testing.T) {
  2106  	state := testStateStore(t)
  2107  	job := mock.Job()
  2108  	jobSummary := &structs.JobSummary{
  2109  		JobID: job.ID,
  2110  		Summary: map[string]structs.TaskGroupSummary{
  2111  			"web": structs.TaskGroupSummary{
  2112  				Starting: 10,
  2113  			},
  2114  		},
  2115  	}
  2116  	restore, err := state.Restore()
  2117  	if err != nil {
  2118  		t.Fatalf("err: %v", err)
  2119  	}
  2120  
  2121  	err = restore.JobSummaryRestore(jobSummary)
  2122  	if err != nil {
  2123  		t.Fatalf("err: %v", err)
  2124  	}
  2125  	restore.Commit()
  2126  
  2127  	ws := memdb.NewWatchSet()
  2128  	out, err := state.JobSummaryByID(ws, job.ID)
  2129  	if err != nil {
  2130  		t.Fatalf("err: %v", err)
  2131  	}
  2132  
  2133  	if !reflect.DeepEqual(out, jobSummary) {
  2134  		t.Fatalf("Bad: %#v %#v", out, jobSummary)
  2135  	}
  2136  }
  2137  
  2138  func TestStateStore_Indexes(t *testing.T) {
  2139  	state := testStateStore(t)
  2140  	node := mock.Node()
  2141  
  2142  	err := state.UpsertNode(1000, node)
  2143  	if err != nil {
  2144  		t.Fatalf("err: %v", err)
  2145  	}
  2146  
  2147  	iter, err := state.Indexes()
  2148  	if err != nil {
  2149  		t.Fatalf("err: %v", err)
  2150  	}
  2151  
  2152  	var out []*IndexEntry
  2153  	for {
  2154  		raw := iter.Next()
  2155  		if raw == nil {
  2156  			break
  2157  		}
  2158  		out = append(out, raw.(*IndexEntry))
  2159  	}
  2160  
  2161  	expect := []*IndexEntry{
  2162  		&IndexEntry{"nodes", 1000},
  2163  	}
  2164  
  2165  	if !reflect.DeepEqual(expect, out) {
  2166  		t.Fatalf("bad: %#v %#v", expect, out)
  2167  	}
  2168  }
  2169  
  2170  func TestStateStore_LatestIndex(t *testing.T) {
  2171  	state := testStateStore(t)
  2172  
  2173  	if err := state.UpsertNode(1000, mock.Node()); err != nil {
  2174  		t.Fatalf("err: %v", err)
  2175  	}
  2176  
  2177  	exp := uint64(2000)
  2178  	if err := state.UpsertJob(exp, mock.Job()); err != nil {
  2179  		t.Fatalf("err: %v", err)
  2180  	}
  2181  
  2182  	latest, err := state.LatestIndex()
  2183  	if err != nil {
  2184  		t.Fatalf("err: %v", err)
  2185  	}
  2186  
  2187  	if latest != exp {
  2188  		t.Fatalf("LatestIndex() returned %d; want %d", latest, exp)
  2189  	}
  2190  }
  2191  
  2192  func TestStateStore_RestoreIndex(t *testing.T) {
  2193  	state := testStateStore(t)
  2194  
  2195  	restore, err := state.Restore()
  2196  	if err != nil {
  2197  		t.Fatalf("err: %v", err)
  2198  	}
  2199  
  2200  	index := &IndexEntry{"jobs", 1000}
  2201  	err = restore.IndexRestore(index)
  2202  	if err != nil {
  2203  		t.Fatalf("err: %v", err)
  2204  	}
  2205  
  2206  	restore.Commit()
  2207  
  2208  	out, err := state.Index("jobs")
  2209  	if err != nil {
  2210  		t.Fatalf("err: %v", err)
  2211  	}
  2212  
  2213  	if out != 1000 {
  2214  		t.Fatalf("Bad: %#v %#v", out, 1000)
  2215  	}
  2216  }
  2217  
  2218  func TestStateStore_UpsertEvals_Eval(t *testing.T) {
  2219  	state := testStateStore(t)
  2220  	eval := mock.Eval()
  2221  
  2222  	// Create a watchset so we can test that upsert fires the watch
  2223  	ws := memdb.NewWatchSet()
  2224  	if _, err := state.EvalByID(ws, eval.ID); err != nil {
  2225  		t.Fatalf("bad: %v", err)
  2226  	}
  2227  
  2228  	err := state.UpsertEvals(1000, []*structs.Evaluation{eval})
  2229  	if err != nil {
  2230  		t.Fatalf("err: %v", err)
  2231  	}
  2232  
  2233  	if !watchFired(ws) {
  2234  		t.Fatalf("bad")
  2235  	}
  2236  
  2237  	ws = memdb.NewWatchSet()
  2238  	out, err := state.EvalByID(ws, eval.ID)
  2239  	if err != nil {
  2240  		t.Fatalf("err: %v", err)
  2241  	}
  2242  
  2243  	if !reflect.DeepEqual(eval, out) {
  2244  		t.Fatalf("bad: %#v %#v", eval, out)
  2245  	}
  2246  
  2247  	index, err := state.Index("evals")
  2248  	if err != nil {
  2249  		t.Fatalf("err: %v", err)
  2250  	}
  2251  	if index != 1000 {
  2252  		t.Fatalf("bad: %d", index)
  2253  	}
  2254  
  2255  	if watchFired(ws) {
  2256  		t.Fatalf("bad")
  2257  	}
  2258  }
  2259  
  2260  func TestStateStore_UpsertEvals_CancelBlocked(t *testing.T) {
  2261  	state := testStateStore(t)
  2262  
  2263  	// Create two blocked evals for the same job
  2264  	j := "test-job"
  2265  	b1, b2 := mock.Eval(), mock.Eval()
  2266  	b1.JobID = j
  2267  	b1.Status = structs.EvalStatusBlocked
  2268  	b2.JobID = j
  2269  	b2.Status = structs.EvalStatusBlocked
  2270  
  2271  	err := state.UpsertEvals(999, []*structs.Evaluation{b1, b2})
  2272  	if err != nil {
  2273  		t.Fatalf("err: %v", err)
  2274  	}
  2275  
  2276  	// Create one complete and successful eval for the job
  2277  	eval := mock.Eval()
  2278  	eval.JobID = j
  2279  	eval.Status = structs.EvalStatusComplete
  2280  
  2281  	// Create a watchset so we can test that the upsert of the complete eval
  2282  	// fires the watch
  2283  	ws := memdb.NewWatchSet()
  2284  	if _, err := state.EvalByID(ws, b1.ID); err != nil {
  2285  		t.Fatalf("bad: %v", err)
  2286  	}
  2287  	if _, err := state.EvalByID(ws, b2.ID); err != nil {
  2288  		t.Fatalf("bad: %v", err)
  2289  	}
  2290  
  2291  	if err := state.UpsertEvals(1000, []*structs.Evaluation{eval}); err != nil {
  2292  		t.Fatalf("err: %v", err)
  2293  	}
  2294  
  2295  	if !watchFired(ws) {
  2296  		t.Fatalf("bad")
  2297  	}
  2298  
  2299  	ws = memdb.NewWatchSet()
  2300  	out, err := state.EvalByID(ws, eval.ID)
  2301  	if err != nil {
  2302  		t.Fatalf("err: %v", err)
  2303  	}
  2304  
  2305  	if !reflect.DeepEqual(eval, out) {
  2306  		t.Fatalf("bad: %#v %#v", eval, out)
  2307  	}
  2308  
  2309  	index, err := state.Index("evals")
  2310  	if err != nil {
  2311  		t.Fatalf("err: %v", err)
  2312  	}
  2313  	if index != 1000 {
  2314  		t.Fatalf("bad: %d", index)
  2315  	}
  2316  
  2317  	// Get b1/b2 and check they are cancelled
  2318  	out1, err := state.EvalByID(ws, b1.ID)
  2319  	if err != nil {
  2320  		t.Fatalf("err: %v", err)
  2321  	}
  2322  
  2323  	out2, err := state.EvalByID(ws, b2.ID)
  2324  	if err != nil {
  2325  		t.Fatalf("err: %v", err)
  2326  	}
  2327  
  2328  	if out1.Status != structs.EvalStatusCancelled || out2.Status != structs.EvalStatusCancelled {
  2329  		t.Fatalf("bad: %#v %#v", out1, out2)
  2330  	}
  2331  
  2332  	if watchFired(ws) {
  2333  		t.Fatalf("bad")
  2334  	}
  2335  }
  2336  
  2337  func TestStateStore_Update_UpsertEvals_Eval(t *testing.T) {
  2338  	state := testStateStore(t)
  2339  	eval := mock.Eval()
  2340  
  2341  	err := state.UpsertEvals(1000, []*structs.Evaluation{eval})
  2342  	if err != nil {
  2343  		t.Fatalf("err: %v", err)
  2344  	}
  2345  
  2346  	// Create a watchset so we can test that delete fires the watch
  2347  	ws := memdb.NewWatchSet()
  2348  	ws2 := memdb.NewWatchSet()
  2349  	if _, err := state.EvalByID(ws, eval.ID); err != nil {
  2350  		t.Fatalf("bad: %v", err)
  2351  	}
  2352  
  2353  	if _, err := state.EvalsByJob(ws2, eval.JobID); err != nil {
  2354  		t.Fatalf("bad: %v", err)
  2355  	}
  2356  
  2357  	eval2 := mock.Eval()
  2358  	eval2.ID = eval.ID
  2359  	eval2.JobID = eval.JobID
  2360  	err = state.UpsertEvals(1001, []*structs.Evaluation{eval2})
  2361  	if err != nil {
  2362  		t.Fatalf("err: %v", err)
  2363  	}
  2364  
  2365  	if !watchFired(ws) {
  2366  		t.Fatalf("bad")
  2367  	}
  2368  	if !watchFired(ws2) {
  2369  		t.Fatalf("bad")
  2370  	}
  2371  
  2372  	ws = memdb.NewWatchSet()
  2373  	out, err := state.EvalByID(ws, eval.ID)
  2374  	if err != nil {
  2375  		t.Fatalf("err: %v", err)
  2376  	}
  2377  
  2378  	if !reflect.DeepEqual(eval2, out) {
  2379  		t.Fatalf("bad: %#v %#v", eval2, out)
  2380  	}
  2381  
  2382  	if out.CreateIndex != 1000 {
  2383  		t.Fatalf("bad: %#v", out)
  2384  	}
  2385  	if out.ModifyIndex != 1001 {
  2386  		t.Fatalf("bad: %#v", out)
  2387  	}
  2388  
  2389  	index, err := state.Index("evals")
  2390  	if err != nil {
  2391  		t.Fatalf("err: %v", err)
  2392  	}
  2393  	if index != 1001 {
  2394  		t.Fatalf("bad: %d", index)
  2395  	}
  2396  
  2397  	if watchFired(ws) {
  2398  		t.Fatalf("bad")
  2399  	}
  2400  }
  2401  
  2402  func TestStateStore_UpsertEvals_Eval_ChildJob(t *testing.T) {
  2403  	state := testStateStore(t)
  2404  
  2405  	parent := mock.Job()
  2406  	if err := state.UpsertJob(998, parent); err != nil {
  2407  		t.Fatalf("err: %v", err)
  2408  	}
  2409  
  2410  	child := mock.Job()
  2411  	child.ParentID = parent.ID
  2412  
  2413  	if err := state.UpsertJob(999, child); err != nil {
  2414  		t.Fatalf("err: %v", err)
  2415  	}
  2416  
  2417  	eval := mock.Eval()
  2418  	eval.Status = structs.EvalStatusComplete
  2419  	eval.JobID = child.ID
  2420  
  2421  	// Create watchsets so we can test that upsert fires the watch
  2422  	ws := memdb.NewWatchSet()
  2423  	ws2 := memdb.NewWatchSet()
  2424  	ws3 := memdb.NewWatchSet()
  2425  	if _, err := state.JobSummaryByID(ws, parent.ID); err != nil {
  2426  		t.Fatalf("bad: %v", err)
  2427  	}
  2428  	if _, err := state.EvalByID(ws2, eval.ID); err != nil {
  2429  		t.Fatalf("bad: %v", err)
  2430  	}
  2431  	if _, err := state.EvalsByJob(ws3, eval.JobID); err != nil {
  2432  		t.Fatalf("bad: %v", err)
  2433  	}
  2434  
  2435  	err := state.UpsertEvals(1000, []*structs.Evaluation{eval})
  2436  	if err != nil {
  2437  		t.Fatalf("err: %v", err)
  2438  	}
  2439  
  2440  	if !watchFired(ws) {
  2441  		t.Fatalf("bad")
  2442  	}
  2443  	if !watchFired(ws2) {
  2444  		t.Fatalf("bad")
  2445  	}
  2446  	if !watchFired(ws3) {
  2447  		t.Fatalf("bad")
  2448  	}
  2449  
  2450  	ws = memdb.NewWatchSet()
  2451  	out, err := state.EvalByID(ws, eval.ID)
  2452  	if err != nil {
  2453  		t.Fatalf("err: %v", err)
  2454  	}
  2455  
  2456  	if !reflect.DeepEqual(eval, out) {
  2457  		t.Fatalf("bad: %#v %#v", eval, out)
  2458  	}
  2459  
  2460  	index, err := state.Index("evals")
  2461  	if err != nil {
  2462  		t.Fatalf("err: %v", err)
  2463  	}
  2464  	if index != 1000 {
  2465  		t.Fatalf("bad: %d", index)
  2466  	}
  2467  
  2468  	summary, err := state.JobSummaryByID(ws, parent.ID)
  2469  	if err != nil {
  2470  		t.Fatalf("err: %v", err)
  2471  	}
  2472  	if summary == nil {
  2473  		t.Fatalf("nil summary")
  2474  	}
  2475  	if summary.JobID != parent.ID {
  2476  		t.Fatalf("bad summary id: %v", parent.ID)
  2477  	}
  2478  	if summary.Children == nil {
  2479  		t.Fatalf("nil children summary")
  2480  	}
  2481  	if summary.Children.Pending != 0 || summary.Children.Running != 0 || summary.Children.Dead != 1 {
  2482  		t.Fatalf("bad children summary: %v", summary.Children)
  2483  	}
  2484  
  2485  	if watchFired(ws) {
  2486  		t.Fatalf("bad")
  2487  	}
  2488  }
  2489  
  2490  func TestStateStore_DeleteEval_Eval(t *testing.T) {
  2491  	state := testStateStore(t)
  2492  	eval1 := mock.Eval()
  2493  	eval2 := mock.Eval()
  2494  	alloc1 := mock.Alloc()
  2495  	alloc2 := mock.Alloc()
  2496  
  2497  	// Create watchsets so we can test that upsert fires the watch
  2498  	watches := make([]memdb.WatchSet, 12)
  2499  	for i := 0; i < 12; i++ {
  2500  		watches[i] = memdb.NewWatchSet()
  2501  	}
  2502  	if _, err := state.EvalByID(watches[0], eval1.ID); err != nil {
  2503  		t.Fatalf("bad: %v", err)
  2504  	}
  2505  	if _, err := state.EvalByID(watches[1], eval2.ID); err != nil {
  2506  		t.Fatalf("bad: %v", err)
  2507  	}
  2508  	if _, err := state.EvalsByJob(watches[2], eval1.JobID); err != nil {
  2509  		t.Fatalf("bad: %v", err)
  2510  	}
  2511  	if _, err := state.EvalsByJob(watches[3], eval2.JobID); err != nil {
  2512  		t.Fatalf("bad: %v", err)
  2513  	}
  2514  	if _, err := state.AllocByID(watches[4], alloc1.ID); err != nil {
  2515  		t.Fatalf("bad: %v", err)
  2516  	}
  2517  	if _, err := state.AllocByID(watches[5], alloc2.ID); err != nil {
  2518  		t.Fatalf("bad: %v", err)
  2519  	}
  2520  	if _, err := state.AllocsByEval(watches[6], alloc1.EvalID); err != nil {
  2521  		t.Fatalf("bad: %v", err)
  2522  	}
  2523  	if _, err := state.AllocsByEval(watches[7], alloc2.EvalID); err != nil {
  2524  		t.Fatalf("bad: %v", err)
  2525  	}
  2526  	if _, err := state.AllocsByJob(watches[8], alloc1.JobID, false); err != nil {
  2527  		t.Fatalf("bad: %v", err)
  2528  	}
  2529  	if _, err := state.AllocsByJob(watches[9], alloc2.JobID, false); err != nil {
  2530  		t.Fatalf("bad: %v", err)
  2531  	}
  2532  	if _, err := state.AllocsByNode(watches[10], alloc1.NodeID); err != nil {
  2533  		t.Fatalf("bad: %v", err)
  2534  	}
  2535  	if _, err := state.AllocsByNode(watches[11], alloc2.NodeID); err != nil {
  2536  		t.Fatalf("bad: %v", err)
  2537  	}
  2538  
  2539  	state.UpsertJobSummary(900, mock.JobSummary(eval1.JobID))
  2540  	state.UpsertJobSummary(901, mock.JobSummary(eval2.JobID))
  2541  	state.UpsertJobSummary(902, mock.JobSummary(alloc1.JobID))
  2542  	state.UpsertJobSummary(903, mock.JobSummary(alloc2.JobID))
  2543  	err := state.UpsertEvals(1000, []*structs.Evaluation{eval1, eval2})
  2544  	if err != nil {
  2545  		t.Fatalf("err: %v", err)
  2546  	}
  2547  
  2548  	err = state.UpsertAllocs(1001, []*structs.Allocation{alloc1, alloc2})
  2549  	if err != nil {
  2550  		t.Fatalf("err: %v", err)
  2551  	}
  2552  
  2553  	err = state.DeleteEval(1002, []string{eval1.ID, eval2.ID}, []string{alloc1.ID, alloc2.ID})
  2554  	if err != nil {
  2555  		t.Fatalf("err: %v", err)
  2556  	}
  2557  
  2558  	for i, ws := range watches {
  2559  		if !watchFired(ws) {
  2560  			t.Fatalf("bad %d", i)
  2561  		}
  2562  	}
  2563  
  2564  	ws := memdb.NewWatchSet()
  2565  	out, err := state.EvalByID(ws, eval1.ID)
  2566  	if err != nil {
  2567  		t.Fatalf("err: %v", err)
  2568  	}
  2569  
  2570  	if out != nil {
  2571  		t.Fatalf("bad: %#v %#v", eval1, out)
  2572  	}
  2573  
  2574  	out, err = state.EvalByID(ws, eval2.ID)
  2575  	if err != nil {
  2576  		t.Fatalf("err: %v", err)
  2577  	}
  2578  
  2579  	if out != nil {
  2580  		t.Fatalf("bad: %#v %#v", eval1, out)
  2581  	}
  2582  
  2583  	outA, err := state.AllocByID(ws, alloc1.ID)
  2584  	if err != nil {
  2585  		t.Fatalf("err: %v", err)
  2586  	}
  2587  
  2588  	if out != nil {
  2589  		t.Fatalf("bad: %#v %#v", alloc1, outA)
  2590  	}
  2591  
  2592  	outA, err = state.AllocByID(ws, alloc2.ID)
  2593  	if err != nil {
  2594  		t.Fatalf("err: %v", err)
  2595  	}
  2596  
  2597  	if out != nil {
  2598  		t.Fatalf("bad: %#v %#v", alloc1, outA)
  2599  	}
  2600  
  2601  	index, err := state.Index("evals")
  2602  	if err != nil {
  2603  		t.Fatalf("err: %v", err)
  2604  	}
  2605  	if index != 1002 {
  2606  		t.Fatalf("bad: %d", index)
  2607  	}
  2608  
  2609  	index, err = state.Index("allocs")
  2610  	if err != nil {
  2611  		t.Fatalf("err: %v", err)
  2612  	}
  2613  	if index != 1002 {
  2614  		t.Fatalf("bad: %d", index)
  2615  	}
  2616  
  2617  	if watchFired(ws) {
  2618  		t.Fatalf("bad")
  2619  	}
  2620  }
  2621  
  2622  func TestStateStore_DeleteEval_ChildJob(t *testing.T) {
  2623  	state := testStateStore(t)
  2624  
  2625  	parent := mock.Job()
  2626  	if err := state.UpsertJob(998, parent); err != nil {
  2627  		t.Fatalf("err: %v", err)
  2628  	}
  2629  
  2630  	child := mock.Job()
  2631  	child.ParentID = parent.ID
  2632  
  2633  	if err := state.UpsertJob(999, child); err != nil {
  2634  		t.Fatalf("err: %v", err)
  2635  	}
  2636  
  2637  	eval1 := mock.Eval()
  2638  	eval1.JobID = child.ID
  2639  	alloc1 := mock.Alloc()
  2640  	alloc1.JobID = child.ID
  2641  
  2642  	err := state.UpsertEvals(1000, []*structs.Evaluation{eval1})
  2643  	if err != nil {
  2644  		t.Fatalf("err: %v", err)
  2645  	}
  2646  
  2647  	err = state.UpsertAllocs(1001, []*structs.Allocation{alloc1})
  2648  	if err != nil {
  2649  		t.Fatalf("err: %v", err)
  2650  	}
  2651  
  2652  	// Create watchsets so we can test that delete fires the watch
  2653  	ws := memdb.NewWatchSet()
  2654  	if _, err := state.JobSummaryByID(ws, parent.ID); err != nil {
  2655  		t.Fatalf("bad: %v", err)
  2656  	}
  2657  
  2658  	err = state.DeleteEval(1002, []string{eval1.ID}, []string{alloc1.ID})
  2659  	if err != nil {
  2660  		t.Fatalf("err: %v", err)
  2661  	}
  2662  
  2663  	if !watchFired(ws) {
  2664  		t.Fatalf("bad")
  2665  	}
  2666  
  2667  	ws = memdb.NewWatchSet()
  2668  	summary, err := state.JobSummaryByID(ws, parent.ID)
  2669  	if err != nil {
  2670  		t.Fatalf("err: %v", err)
  2671  	}
  2672  	if summary == nil {
  2673  		t.Fatalf("nil summary")
  2674  	}
  2675  	if summary.JobID != parent.ID {
  2676  		t.Fatalf("bad summary id: %v", parent.ID)
  2677  	}
  2678  	if summary.Children == nil {
  2679  		t.Fatalf("nil children summary")
  2680  	}
  2681  	if summary.Children.Pending != 0 || summary.Children.Running != 0 || summary.Children.Dead != 1 {
  2682  		t.Fatalf("bad children summary: %v", summary.Children)
  2683  	}
  2684  
  2685  	if watchFired(ws) {
  2686  		t.Fatalf("bad")
  2687  	}
  2688  }
  2689  
  2690  func TestStateStore_EvalsByJob(t *testing.T) {
  2691  	state := testStateStore(t)
  2692  
  2693  	eval1 := mock.Eval()
  2694  	eval2 := mock.Eval()
  2695  	eval2.JobID = eval1.JobID
  2696  	eval3 := mock.Eval()
  2697  	evals := []*structs.Evaluation{eval1, eval2}
  2698  
  2699  	err := state.UpsertEvals(1000, evals)
  2700  	if err != nil {
  2701  		t.Fatalf("err: %v", err)
  2702  	}
  2703  	err = state.UpsertEvals(1001, []*structs.Evaluation{eval3})
  2704  	if err != nil {
  2705  		t.Fatalf("err: %v", err)
  2706  	}
  2707  
  2708  	ws := memdb.NewWatchSet()
  2709  	out, err := state.EvalsByJob(ws, eval1.JobID)
  2710  	if err != nil {
  2711  		t.Fatalf("err: %v", err)
  2712  	}
  2713  
  2714  	sort.Sort(EvalIDSort(evals))
  2715  	sort.Sort(EvalIDSort(out))
  2716  
  2717  	if !reflect.DeepEqual(evals, out) {
  2718  		t.Fatalf("bad: %#v %#v", evals, out)
  2719  	}
  2720  
  2721  	if watchFired(ws) {
  2722  		t.Fatalf("bad")
  2723  	}
  2724  }
  2725  
  2726  func TestStateStore_Evals(t *testing.T) {
  2727  	state := testStateStore(t)
  2728  	var evals []*structs.Evaluation
  2729  
  2730  	for i := 0; i < 10; i++ {
  2731  		eval := mock.Eval()
  2732  		evals = append(evals, eval)
  2733  
  2734  		err := state.UpsertEvals(1000+uint64(i), []*structs.Evaluation{eval})
  2735  		if err != nil {
  2736  			t.Fatalf("err: %v", err)
  2737  		}
  2738  	}
  2739  
  2740  	ws := memdb.NewWatchSet()
  2741  	iter, err := state.Evals(ws)
  2742  	if err != nil {
  2743  		t.Fatalf("err: %v", err)
  2744  	}
  2745  
  2746  	var out []*structs.Evaluation
  2747  	for {
  2748  		raw := iter.Next()
  2749  		if raw == nil {
  2750  			break
  2751  		}
  2752  		out = append(out, raw.(*structs.Evaluation))
  2753  	}
  2754  
  2755  	sort.Sort(EvalIDSort(evals))
  2756  	sort.Sort(EvalIDSort(out))
  2757  
  2758  	if !reflect.DeepEqual(evals, out) {
  2759  		t.Fatalf("bad: %#v %#v", evals, out)
  2760  	}
  2761  
  2762  	if watchFired(ws) {
  2763  		t.Fatalf("bad")
  2764  	}
  2765  }
  2766  
  2767  func TestStateStore_EvalsByIDPrefix(t *testing.T) {
  2768  	state := testStateStore(t)
  2769  	var evals []*structs.Evaluation
  2770  
  2771  	ids := []string{
  2772  		"aaaaaaaa-7bfb-395d-eb95-0685af2176b2",
  2773  		"aaaaaaab-7bfb-395d-eb95-0685af2176b2",
  2774  		"aaaaaabb-7bfb-395d-eb95-0685af2176b2",
  2775  		"aaaaabbb-7bfb-395d-eb95-0685af2176b2",
  2776  		"aaaabbbb-7bfb-395d-eb95-0685af2176b2",
  2777  		"aaabbbbb-7bfb-395d-eb95-0685af2176b2",
  2778  		"aabbbbbb-7bfb-395d-eb95-0685af2176b2",
  2779  		"abbbbbbb-7bfb-395d-eb95-0685af2176b2",
  2780  		"bbbbbbbb-7bfb-395d-eb95-0685af2176b2",
  2781  	}
  2782  	for i := 0; i < 9; i++ {
  2783  		eval := mock.Eval()
  2784  		eval.ID = ids[i]
  2785  		evals = append(evals, eval)
  2786  	}
  2787  
  2788  	err := state.UpsertEvals(1000, evals)
  2789  	if err != nil {
  2790  		t.Fatalf("err: %v", err)
  2791  	}
  2792  
  2793  	ws := memdb.NewWatchSet()
  2794  	iter, err := state.EvalsByIDPrefix(ws, "aaaa")
  2795  	if err != nil {
  2796  		t.Fatalf("err: %v", err)
  2797  	}
  2798  
  2799  	gatherEvals := func(iter memdb.ResultIterator) []*structs.Evaluation {
  2800  		var evals []*structs.Evaluation
  2801  		for {
  2802  			raw := iter.Next()
  2803  			if raw == nil {
  2804  				break
  2805  			}
  2806  			evals = append(evals, raw.(*structs.Evaluation))
  2807  		}
  2808  		return evals
  2809  	}
  2810  
  2811  	out := gatherEvals(iter)
  2812  	if len(out) != 5 {
  2813  		t.Fatalf("bad: expected five evaluations, got: %#v", out)
  2814  	}
  2815  
  2816  	sort.Sort(EvalIDSort(evals))
  2817  
  2818  	for index, eval := range out {
  2819  		if ids[index] != eval.ID {
  2820  			t.Fatalf("bad: got unexpected id: %s", eval.ID)
  2821  		}
  2822  	}
  2823  
  2824  	iter, err = state.EvalsByIDPrefix(ws, "b-a7bfb")
  2825  	if err != nil {
  2826  		t.Fatalf("err: %v", err)
  2827  	}
  2828  
  2829  	out = gatherEvals(iter)
  2830  	if len(out) != 0 {
  2831  		t.Fatalf("bad: unexpected zero evaluations, got: %#v", out)
  2832  	}
  2833  
  2834  	if watchFired(ws) {
  2835  		t.Fatalf("bad")
  2836  	}
  2837  }
  2838  
  2839  func TestStateStore_RestoreEval(t *testing.T) {
  2840  	state := testStateStore(t)
  2841  	eval := mock.Eval()
  2842  
  2843  	restore, err := state.Restore()
  2844  	if err != nil {
  2845  		t.Fatalf("err: %v", err)
  2846  	}
  2847  
  2848  	err = restore.EvalRestore(eval)
  2849  	if err != nil {
  2850  		t.Fatalf("err: %v", err)
  2851  	}
  2852  	restore.Commit()
  2853  
  2854  	ws := memdb.NewWatchSet()
  2855  	out, err := state.EvalByID(ws, eval.ID)
  2856  	if err != nil {
  2857  		t.Fatalf("err: %v", err)
  2858  	}
  2859  
  2860  	if !reflect.DeepEqual(out, eval) {
  2861  		t.Fatalf("Bad: %#v %#v", out, eval)
  2862  	}
  2863  }
  2864  
  2865  func TestStateStore_UpdateAllocsFromClient(t *testing.T) {
  2866  	state := testStateStore(t)
  2867  	parent := mock.Job()
  2868  	if err := state.UpsertJob(998, parent); err != nil {
  2869  		t.Fatalf("err: %v", err)
  2870  	}
  2871  
  2872  	child := mock.Job()
  2873  	child.ParentID = parent.ID
  2874  	if err := state.UpsertJob(999, child); err != nil {
  2875  		t.Fatalf("err: %v", err)
  2876  	}
  2877  
  2878  	alloc := mock.Alloc()
  2879  	alloc.JobID = child.ID
  2880  	alloc.Job = child
  2881  
  2882  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
  2883  	if err != nil {
  2884  		t.Fatalf("err: %v", err)
  2885  	}
  2886  
  2887  	ws := memdb.NewWatchSet()
  2888  	summary, err := state.JobSummaryByID(ws, parent.ID)
  2889  	if err != nil {
  2890  		t.Fatalf("err: %v", err)
  2891  	}
  2892  	if summary == nil {
  2893  		t.Fatalf("nil summary")
  2894  	}
  2895  	if summary.JobID != parent.ID {
  2896  		t.Fatalf("bad summary id: %v", parent.ID)
  2897  	}
  2898  	if summary.Children == nil {
  2899  		t.Fatalf("nil children summary")
  2900  	}
  2901  	if summary.Children.Pending != 0 || summary.Children.Running != 1 || summary.Children.Dead != 0 {
  2902  		t.Fatalf("bad children summary: %v", summary.Children)
  2903  	}
  2904  
  2905  	// Create watchsets so we can test that update fires the watch
  2906  	ws = memdb.NewWatchSet()
  2907  	if _, err := state.JobSummaryByID(ws, parent.ID); err != nil {
  2908  		t.Fatalf("bad: %v", err)
  2909  	}
  2910  
  2911  	// Create the delta updates
  2912  	ts := map[string]*structs.TaskState{"web": &structs.TaskState{State: structs.TaskStateRunning}}
  2913  	update := &structs.Allocation{
  2914  		ID:           alloc.ID,
  2915  		ClientStatus: structs.AllocClientStatusComplete,
  2916  		TaskStates:   ts,
  2917  		JobID:        alloc.JobID,
  2918  		TaskGroup:    alloc.TaskGroup,
  2919  	}
  2920  	err = state.UpdateAllocsFromClient(1001, []*structs.Allocation{update})
  2921  	if err != nil {
  2922  		t.Fatalf("err: %v", err)
  2923  	}
  2924  
  2925  	if !watchFired(ws) {
  2926  		t.Fatalf("bad")
  2927  	}
  2928  
  2929  	ws = memdb.NewWatchSet()
  2930  	summary, err = state.JobSummaryByID(ws, parent.ID)
  2931  	if err != nil {
  2932  		t.Fatalf("err: %v", err)
  2933  	}
  2934  	if summary == nil {
  2935  		t.Fatalf("nil summary")
  2936  	}
  2937  	if summary.JobID != parent.ID {
  2938  		t.Fatalf("bad summary id: %v", parent.ID)
  2939  	}
  2940  	if summary.Children == nil {
  2941  		t.Fatalf("nil children summary")
  2942  	}
  2943  	if summary.Children.Pending != 0 || summary.Children.Running != 0 || summary.Children.Dead != 1 {
  2944  		t.Fatalf("bad children summary: %v", summary.Children)
  2945  	}
  2946  
  2947  	if watchFired(ws) {
  2948  		t.Fatalf("bad")
  2949  	}
  2950  }
  2951  
  2952  func TestStateStore_UpdateAllocsFromClient_ChildJob(t *testing.T) {
  2953  	state := testStateStore(t)
  2954  	alloc1 := mock.Alloc()
  2955  	alloc2 := mock.Alloc()
  2956  
  2957  	if err := state.UpsertJob(999, alloc1.Job); err != nil {
  2958  		t.Fatalf("err: %v", err)
  2959  	}
  2960  	if err := state.UpsertJob(999, alloc2.Job); err != nil {
  2961  		t.Fatalf("err: %v", err)
  2962  	}
  2963  
  2964  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc1, alloc2})
  2965  	if err != nil {
  2966  		t.Fatalf("err: %v", err)
  2967  	}
  2968  
  2969  	// Create watchsets so we can test that update fires the watch
  2970  	watches := make([]memdb.WatchSet, 8)
  2971  	for i := 0; i < 8; i++ {
  2972  		watches[i] = memdb.NewWatchSet()
  2973  	}
  2974  	if _, err := state.AllocByID(watches[0], alloc1.ID); err != nil {
  2975  		t.Fatalf("bad: %v", err)
  2976  	}
  2977  	if _, err := state.AllocByID(watches[1], alloc2.ID); err != nil {
  2978  		t.Fatalf("bad: %v", err)
  2979  	}
  2980  	if _, err := state.AllocsByEval(watches[2], alloc1.EvalID); err != nil {
  2981  		t.Fatalf("bad: %v", err)
  2982  	}
  2983  	if _, err := state.AllocsByEval(watches[3], alloc2.EvalID); err != nil {
  2984  		t.Fatalf("bad: %v", err)
  2985  	}
  2986  	if _, err := state.AllocsByJob(watches[4], alloc1.JobID, false); err != nil {
  2987  		t.Fatalf("bad: %v", err)
  2988  	}
  2989  	if _, err := state.AllocsByJob(watches[5], alloc2.JobID, false); err != nil {
  2990  		t.Fatalf("bad: %v", err)
  2991  	}
  2992  	if _, err := state.AllocsByNode(watches[6], alloc1.NodeID); err != nil {
  2993  		t.Fatalf("bad: %v", err)
  2994  	}
  2995  	if _, err := state.AllocsByNode(watches[7], alloc2.NodeID); err != nil {
  2996  		t.Fatalf("bad: %v", err)
  2997  	}
  2998  
  2999  	// Create the delta updates
  3000  	ts := map[string]*structs.TaskState{"web": &structs.TaskState{State: structs.TaskStatePending}}
  3001  	update := &structs.Allocation{
  3002  		ID:           alloc1.ID,
  3003  		ClientStatus: structs.AllocClientStatusFailed,
  3004  		TaskStates:   ts,
  3005  		JobID:        alloc1.JobID,
  3006  		TaskGroup:    alloc1.TaskGroup,
  3007  	}
  3008  	update2 := &structs.Allocation{
  3009  		ID:           alloc2.ID,
  3010  		ClientStatus: structs.AllocClientStatusRunning,
  3011  		TaskStates:   ts,
  3012  		JobID:        alloc2.JobID,
  3013  		TaskGroup:    alloc2.TaskGroup,
  3014  	}
  3015  
  3016  	err = state.UpdateAllocsFromClient(1001, []*structs.Allocation{update, update2})
  3017  	if err != nil {
  3018  		t.Fatalf("err: %v", err)
  3019  	}
  3020  
  3021  	for i, ws := range watches {
  3022  		if !watchFired(ws) {
  3023  			t.Fatalf("bad %d", i)
  3024  		}
  3025  	}
  3026  
  3027  	ws := memdb.NewWatchSet()
  3028  	out, err := state.AllocByID(ws, alloc1.ID)
  3029  	if err != nil {
  3030  		t.Fatalf("err: %v", err)
  3031  	}
  3032  
  3033  	alloc1.CreateIndex = 1000
  3034  	alloc1.ModifyIndex = 1001
  3035  	alloc1.TaskStates = ts
  3036  	alloc1.ClientStatus = structs.AllocClientStatusFailed
  3037  	if !reflect.DeepEqual(alloc1, out) {
  3038  		t.Fatalf("bad: %#v %#v", alloc1, out)
  3039  	}
  3040  
  3041  	out, err = state.AllocByID(ws, alloc2.ID)
  3042  	if err != nil {
  3043  		t.Fatalf("err: %v", err)
  3044  	}
  3045  
  3046  	alloc2.ModifyIndex = 1000
  3047  	alloc2.ModifyIndex = 1001
  3048  	alloc2.ClientStatus = structs.AllocClientStatusRunning
  3049  	alloc2.TaskStates = ts
  3050  	if !reflect.DeepEqual(alloc2, out) {
  3051  		t.Fatalf("bad: %#v %#v", alloc2, out)
  3052  	}
  3053  
  3054  	index, err := state.Index("allocs")
  3055  	if err != nil {
  3056  		t.Fatalf("err: %v", err)
  3057  	}
  3058  	if index != 1001 {
  3059  		t.Fatalf("bad: %d", index)
  3060  	}
  3061  
  3062  	// Ensure summaries have been updated
  3063  	summary, err := state.JobSummaryByID(ws, alloc1.JobID)
  3064  	if err != nil {
  3065  		t.Fatalf("err: %v", err)
  3066  	}
  3067  	tgSummary := summary.Summary["web"]
  3068  	if tgSummary.Failed != 1 {
  3069  		t.Fatalf("expected failed: %v, actual: %v, summary: %#v", 1, tgSummary.Failed, tgSummary)
  3070  	}
  3071  
  3072  	summary2, err := state.JobSummaryByID(ws, alloc2.JobID)
  3073  	if err != nil {
  3074  		t.Fatalf("err: %v", err)
  3075  	}
  3076  	tgSummary2 := summary2.Summary["web"]
  3077  	if tgSummary2.Running != 1 {
  3078  		t.Fatalf("expected running: %v, actual: %v", 1, tgSummary2.Running)
  3079  	}
  3080  
  3081  	if watchFired(ws) {
  3082  		t.Fatalf("bad")
  3083  	}
  3084  }
  3085  
  3086  func TestStateStore_UpdateMultipleAllocsFromClient(t *testing.T) {
  3087  	state := testStateStore(t)
  3088  	alloc := mock.Alloc()
  3089  
  3090  	if err := state.UpsertJob(999, alloc.Job); err != nil {
  3091  		t.Fatalf("err: %v", err)
  3092  	}
  3093  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
  3094  	if err != nil {
  3095  		t.Fatalf("err: %v", err)
  3096  	}
  3097  
  3098  	// Create the delta updates
  3099  	ts := map[string]*structs.TaskState{"web": &structs.TaskState{State: structs.TaskStatePending}}
  3100  	update := &structs.Allocation{
  3101  		ID:           alloc.ID,
  3102  		ClientStatus: structs.AllocClientStatusRunning,
  3103  		TaskStates:   ts,
  3104  		JobID:        alloc.JobID,
  3105  		TaskGroup:    alloc.TaskGroup,
  3106  	}
  3107  	update2 := &structs.Allocation{
  3108  		ID:           alloc.ID,
  3109  		ClientStatus: structs.AllocClientStatusPending,
  3110  		TaskStates:   ts,
  3111  		JobID:        alloc.JobID,
  3112  		TaskGroup:    alloc.TaskGroup,
  3113  	}
  3114  
  3115  	err = state.UpdateAllocsFromClient(1001, []*structs.Allocation{update, update2})
  3116  	if err != nil {
  3117  		t.Fatalf("err: %v", err)
  3118  	}
  3119  
  3120  	ws := memdb.NewWatchSet()
  3121  	out, err := state.AllocByID(ws, alloc.ID)
  3122  	if err != nil {
  3123  		t.Fatalf("err: %v", err)
  3124  	}
  3125  
  3126  	alloc.CreateIndex = 1000
  3127  	alloc.ModifyIndex = 1001
  3128  	alloc.TaskStates = ts
  3129  	alloc.ClientStatus = structs.AllocClientStatusPending
  3130  	if !reflect.DeepEqual(alloc, out) {
  3131  		t.Fatalf("bad: %#v , actual:%#v", alloc, out)
  3132  	}
  3133  
  3134  	summary, err := state.JobSummaryByID(ws, alloc.JobID)
  3135  	expectedSummary := &structs.JobSummary{
  3136  		JobID: alloc.JobID,
  3137  		Summary: map[string]structs.TaskGroupSummary{
  3138  			"web": structs.TaskGroupSummary{
  3139  				Starting: 1,
  3140  			},
  3141  		},
  3142  		Children:    new(structs.JobChildrenSummary),
  3143  		CreateIndex: 999,
  3144  		ModifyIndex: 1001,
  3145  	}
  3146  	if err != nil {
  3147  		t.Fatalf("err: %v", err)
  3148  	}
  3149  	if !reflect.DeepEqual(summary, expectedSummary) {
  3150  		t.Fatalf("expected: %#v, actual: %#v", expectedSummary, summary)
  3151  	}
  3152  }
  3153  
  3154  func TestStateStore_UpsertAlloc_Alloc(t *testing.T) {
  3155  	state := testStateStore(t)
  3156  	alloc := mock.Alloc()
  3157  
  3158  	if err := state.UpsertJob(999, alloc.Job); err != nil {
  3159  		t.Fatalf("err: %v", err)
  3160  	}
  3161  
  3162  	// Create watchsets so we can test that update fires the watch
  3163  	watches := make([]memdb.WatchSet, 4)
  3164  	for i := 0; i < 4; i++ {
  3165  		watches[i] = memdb.NewWatchSet()
  3166  	}
  3167  	if _, err := state.AllocByID(watches[0], alloc.ID); err != nil {
  3168  		t.Fatalf("bad: %v", err)
  3169  	}
  3170  	if _, err := state.AllocsByEval(watches[1], alloc.EvalID); err != nil {
  3171  		t.Fatalf("bad: %v", err)
  3172  	}
  3173  	if _, err := state.AllocsByJob(watches[2], alloc.JobID, false); err != nil {
  3174  		t.Fatalf("bad: %v", err)
  3175  	}
  3176  	if _, err := state.AllocsByNode(watches[3], alloc.NodeID); err != nil {
  3177  		t.Fatalf("bad: %v", err)
  3178  	}
  3179  
  3180  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
  3181  	if err != nil {
  3182  		t.Fatalf("err: %v", err)
  3183  	}
  3184  
  3185  	for i, ws := range watches {
  3186  		if !watchFired(ws) {
  3187  			t.Fatalf("bad %d", i)
  3188  		}
  3189  	}
  3190  
  3191  	ws := memdb.NewWatchSet()
  3192  	out, err := state.AllocByID(ws, alloc.ID)
  3193  	if err != nil {
  3194  		t.Fatalf("err: %v", err)
  3195  	}
  3196  
  3197  	if !reflect.DeepEqual(alloc, out) {
  3198  		t.Fatalf("bad: %#v %#v", alloc, out)
  3199  	}
  3200  
  3201  	index, err := state.Index("allocs")
  3202  	if err != nil {
  3203  		t.Fatalf("err: %v", err)
  3204  	}
  3205  	if index != 1000 {
  3206  		t.Fatalf("bad: %d", index)
  3207  	}
  3208  
  3209  	summary, err := state.JobSummaryByID(ws, alloc.JobID)
  3210  	if err != nil {
  3211  		t.Fatalf("err: %v", err)
  3212  	}
  3213  
  3214  	tgSummary, ok := summary.Summary["web"]
  3215  	if !ok {
  3216  		t.Fatalf("no summary for task group web")
  3217  	}
  3218  	if tgSummary.Starting != 1 {
  3219  		t.Fatalf("expected queued: %v, actual: %v", 1, tgSummary.Starting)
  3220  	}
  3221  
  3222  	if watchFired(ws) {
  3223  		t.Fatalf("bad")
  3224  	}
  3225  }
  3226  
  3227  func TestStateStore_UpsertAlloc_Deployment(t *testing.T) {
  3228  	state := testStateStore(t)
  3229  	deployment := mock.Deployment()
  3230  	alloc := mock.Alloc()
  3231  	alloc.DeploymentID = deployment.ID
  3232  
  3233  	if err := state.UpsertJob(999, alloc.Job); err != nil {
  3234  		t.Fatalf("err: %v", err)
  3235  	}
  3236  	if err := state.UpsertDeployment(1000, deployment); err != nil {
  3237  		t.Fatalf("err: %v", err)
  3238  	}
  3239  
  3240  	// Create a watch set so we can test that update fires the watch
  3241  	ws := memdb.NewWatchSet()
  3242  	if _, err := state.AllocsByDeployment(ws, alloc.DeploymentID); err != nil {
  3243  		t.Fatalf("bad: %v", err)
  3244  	}
  3245  
  3246  	err := state.UpsertAllocs(1001, []*structs.Allocation{alloc})
  3247  	if err != nil {
  3248  		t.Fatalf("err: %v", err)
  3249  	}
  3250  
  3251  	if !watchFired(ws) {
  3252  		t.Fatalf("watch not fired")
  3253  	}
  3254  
  3255  	ws = memdb.NewWatchSet()
  3256  	allocs, err := state.AllocsByDeployment(ws, alloc.DeploymentID)
  3257  	if err != nil {
  3258  		t.Fatalf("err: %v", err)
  3259  	}
  3260  
  3261  	if len(allocs) != 1 {
  3262  		t.Fatalf("bad: %#v", allocs)
  3263  	}
  3264  
  3265  	if !reflect.DeepEqual(alloc, allocs[0]) {
  3266  		t.Fatalf("bad: %#v %#v", alloc, allocs[0])
  3267  	}
  3268  
  3269  	index, err := state.Index("allocs")
  3270  	if err != nil {
  3271  		t.Fatalf("err: %v", err)
  3272  	}
  3273  	if index != 1001 {
  3274  		t.Fatalf("bad: %d", index)
  3275  	}
  3276  
  3277  	if watchFired(ws) {
  3278  		t.Fatalf("bad")
  3279  	}
  3280  }
  3281  
  3282  // Testing to ensure we keep issue
  3283  // https://github.com/hashicorp/nomad/issues/2583 fixed
  3284  func TestStateStore_UpsertAlloc_No_Job(t *testing.T) {
  3285  	state := testStateStore(t)
  3286  	alloc := mock.Alloc()
  3287  	alloc.Job = nil
  3288  
  3289  	err := state.UpsertAllocs(999, []*structs.Allocation{alloc})
  3290  	if err == nil || !strings.Contains(err.Error(), "without a job") {
  3291  		t.Fatalf("expect err: %v", err)
  3292  	}
  3293  }
  3294  
  3295  func TestStateStore_UpsertAlloc_NoEphemeralDisk(t *testing.T) {
  3296  	state := testStateStore(t)
  3297  	alloc := mock.Alloc()
  3298  	alloc.Job.TaskGroups[0].EphemeralDisk = nil
  3299  	alloc.Job.TaskGroups[0].Tasks[0].Resources.DiskMB = 120
  3300  
  3301  	if err := state.UpsertJob(999, alloc.Job); err != nil {
  3302  		t.Fatalf("err: %v", err)
  3303  	}
  3304  
  3305  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
  3306  	if err != nil {
  3307  		t.Fatalf("err: %v", err)
  3308  	}
  3309  
  3310  	ws := memdb.NewWatchSet()
  3311  	out, err := state.AllocByID(ws, alloc.ID)
  3312  	if err != nil {
  3313  		t.Fatalf("err: %v", err)
  3314  	}
  3315  
  3316  	expected := alloc.Copy()
  3317  	expected.Job.TaskGroups[0].EphemeralDisk = &structs.EphemeralDisk{SizeMB: 120}
  3318  	if !reflect.DeepEqual(expected, out) {
  3319  		t.Fatalf("bad: %#v %#v", expected, out)
  3320  	}
  3321  }
  3322  
  3323  func TestStateStore_UpsertAlloc_ChildJob(t *testing.T) {
  3324  	state := testStateStore(t)
  3325  
  3326  	parent := mock.Job()
  3327  	if err := state.UpsertJob(998, parent); err != nil {
  3328  		t.Fatalf("err: %v", err)
  3329  	}
  3330  
  3331  	child := mock.Job()
  3332  	child.ParentID = parent.ID
  3333  
  3334  	if err := state.UpsertJob(999, child); err != nil {
  3335  		t.Fatalf("err: %v", err)
  3336  	}
  3337  
  3338  	alloc := mock.Alloc()
  3339  	alloc.JobID = child.ID
  3340  	alloc.Job = child
  3341  
  3342  	// Create watchsets so we can test that delete fires the watch
  3343  	ws := memdb.NewWatchSet()
  3344  	if _, err := state.JobSummaryByID(ws, parent.ID); err != nil {
  3345  		t.Fatalf("bad: %v", err)
  3346  	}
  3347  
  3348  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
  3349  	if err != nil {
  3350  		t.Fatalf("err: %v", err)
  3351  	}
  3352  
  3353  	if !watchFired(ws) {
  3354  		t.Fatalf("bad")
  3355  	}
  3356  
  3357  	ws = memdb.NewWatchSet()
  3358  	summary, err := state.JobSummaryByID(ws, parent.ID)
  3359  	if err != nil {
  3360  		t.Fatalf("err: %v", err)
  3361  	}
  3362  	if summary == nil {
  3363  		t.Fatalf("nil summary")
  3364  	}
  3365  	if summary.JobID != parent.ID {
  3366  		t.Fatalf("bad summary id: %v", parent.ID)
  3367  	}
  3368  	if summary.Children == nil {
  3369  		t.Fatalf("nil children summary")
  3370  	}
  3371  	if summary.Children.Pending != 0 || summary.Children.Running != 1 || summary.Children.Dead != 0 {
  3372  		t.Fatalf("bad children summary: %v", summary.Children)
  3373  	}
  3374  
  3375  	if watchFired(ws) {
  3376  		t.Fatalf("bad")
  3377  	}
  3378  }
  3379  
  3380  func TestStateStore_UpdateAlloc_Alloc(t *testing.T) {
  3381  	state := testStateStore(t)
  3382  	alloc := mock.Alloc()
  3383  
  3384  	if err := state.UpsertJob(999, alloc.Job); err != nil {
  3385  		t.Fatalf("err: %v", err)
  3386  	}
  3387  
  3388  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
  3389  	if err != nil {
  3390  		t.Fatalf("err: %v", err)
  3391  	}
  3392  
  3393  	ws := memdb.NewWatchSet()
  3394  	summary, err := state.JobSummaryByID(ws, alloc.JobID)
  3395  	if err != nil {
  3396  		t.Fatalf("err: %v", err)
  3397  	}
  3398  	tgSummary := summary.Summary["web"]
  3399  	if tgSummary.Starting != 1 {
  3400  		t.Fatalf("expected starting: %v, actual: %v", 1, tgSummary.Starting)
  3401  	}
  3402  
  3403  	alloc2 := mock.Alloc()
  3404  	alloc2.ID = alloc.ID
  3405  	alloc2.NodeID = alloc.NodeID + ".new"
  3406  	state.UpsertJobSummary(1001, mock.JobSummary(alloc2.JobID))
  3407  
  3408  	// Create watchsets so we can test that update fires the watch
  3409  	watches := make([]memdb.WatchSet, 4)
  3410  	for i := 0; i < 4; i++ {
  3411  		watches[i] = memdb.NewWatchSet()
  3412  	}
  3413  	if _, err := state.AllocByID(watches[0], alloc2.ID); err != nil {
  3414  		t.Fatalf("bad: %v", err)
  3415  	}
  3416  	if _, err := state.AllocsByEval(watches[1], alloc2.EvalID); err != nil {
  3417  		t.Fatalf("bad: %v", err)
  3418  	}
  3419  	if _, err := state.AllocsByJob(watches[2], alloc2.JobID, false); err != nil {
  3420  		t.Fatalf("bad: %v", err)
  3421  	}
  3422  	if _, err := state.AllocsByNode(watches[3], alloc2.NodeID); err != nil {
  3423  		t.Fatalf("bad: %v", err)
  3424  	}
  3425  
  3426  	err = state.UpsertAllocs(1002, []*structs.Allocation{alloc2})
  3427  	if err != nil {
  3428  		t.Fatalf("err: %v", err)
  3429  	}
  3430  
  3431  	for i, ws := range watches {
  3432  		if !watchFired(ws) {
  3433  			t.Fatalf("bad %d", i)
  3434  		}
  3435  	}
  3436  
  3437  	ws = memdb.NewWatchSet()
  3438  	out, err := state.AllocByID(ws, alloc.ID)
  3439  	if err != nil {
  3440  		t.Fatalf("err: %v", err)
  3441  	}
  3442  
  3443  	if !reflect.DeepEqual(alloc2, out) {
  3444  		t.Fatalf("bad: %#v %#v", alloc2, out)
  3445  	}
  3446  
  3447  	if out.CreateIndex != 1000 {
  3448  		t.Fatalf("bad: %#v", out)
  3449  	}
  3450  	if out.ModifyIndex != 1002 {
  3451  		t.Fatalf("bad: %#v", out)
  3452  	}
  3453  
  3454  	index, err := state.Index("allocs")
  3455  	if err != nil {
  3456  		t.Fatalf("err: %v", err)
  3457  	}
  3458  	if index != 1002 {
  3459  		t.Fatalf("bad: %d", index)
  3460  	}
  3461  
  3462  	// Ensure that summary hasb't changed
  3463  	summary, err = state.JobSummaryByID(ws, alloc.JobID)
  3464  	if err != nil {
  3465  		t.Fatalf("err: %v", err)
  3466  	}
  3467  	tgSummary = summary.Summary["web"]
  3468  	if tgSummary.Starting != 1 {
  3469  		t.Fatalf("expected starting: %v, actual: %v", 1, tgSummary.Starting)
  3470  	}
  3471  
  3472  	if watchFired(ws) {
  3473  		t.Fatalf("bad")
  3474  	}
  3475  }
  3476  
  3477  // This test ensures that the state store will mark the clients status as lost
  3478  // when set rather than preferring the existing status.
  3479  func TestStateStore_UpdateAlloc_Lost(t *testing.T) {
  3480  	state := testStateStore(t)
  3481  	alloc := mock.Alloc()
  3482  	alloc.ClientStatus = "foo"
  3483  
  3484  	if err := state.UpsertJob(999, alloc.Job); err != nil {
  3485  		t.Fatalf("err: %v", err)
  3486  	}
  3487  
  3488  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
  3489  	if err != nil {
  3490  		t.Fatalf("err: %v", err)
  3491  	}
  3492  
  3493  	alloc2 := new(structs.Allocation)
  3494  	*alloc2 = *alloc
  3495  	alloc2.ClientStatus = structs.AllocClientStatusLost
  3496  	if err := state.UpsertAllocs(1001, []*structs.Allocation{alloc2}); err != nil {
  3497  		t.Fatalf("err: %v", err)
  3498  	}
  3499  
  3500  	ws := memdb.NewWatchSet()
  3501  	out, err := state.AllocByID(ws, alloc2.ID)
  3502  	if err != nil {
  3503  		t.Fatalf("err: %v", err)
  3504  	}
  3505  
  3506  	if out.ClientStatus != structs.AllocClientStatusLost {
  3507  		t.Fatalf("bad: %#v", out)
  3508  	}
  3509  }
  3510  
  3511  // This test ensures an allocation can be updated when there is no job
  3512  // associated with it. This will happen when a job is stopped by an user which
  3513  // has non-terminal allocations on clients
  3514  func TestStateStore_UpdateAlloc_NoJob(t *testing.T) {
  3515  	state := testStateStore(t)
  3516  	alloc := mock.Alloc()
  3517  
  3518  	// Upsert a job
  3519  	state.UpsertJobSummary(998, mock.JobSummary(alloc.JobID))
  3520  	if err := state.UpsertJob(999, alloc.Job); err != nil {
  3521  		t.Fatalf("err: %v", err)
  3522  	}
  3523  
  3524  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
  3525  	if err != nil {
  3526  		t.Fatalf("err: %v", err)
  3527  	}
  3528  
  3529  	if err := state.DeleteJob(1001, alloc.JobID); err != nil {
  3530  		t.Fatalf("err: %v", err)
  3531  	}
  3532  
  3533  	// Update the desired state of the allocation to stop
  3534  	allocCopy := alloc.Copy()
  3535  	allocCopy.DesiredStatus = structs.AllocDesiredStatusStop
  3536  	if err := state.UpsertAllocs(1002, []*structs.Allocation{allocCopy}); err != nil {
  3537  		t.Fatalf("err: %v", err)
  3538  	}
  3539  
  3540  	// Update the client state of the allocation to complete
  3541  	allocCopy1 := allocCopy.Copy()
  3542  	allocCopy1.ClientStatus = structs.AllocClientStatusComplete
  3543  	if err := state.UpdateAllocsFromClient(1003, []*structs.Allocation{allocCopy1}); err != nil {
  3544  		t.Fatalf("err: %v", err)
  3545  	}
  3546  
  3547  	ws := memdb.NewWatchSet()
  3548  	out, _ := state.AllocByID(ws, alloc.ID)
  3549  	// Update the modify index of the alloc before comparing
  3550  	allocCopy1.ModifyIndex = 1003
  3551  	if !reflect.DeepEqual(out, allocCopy1) {
  3552  		t.Fatalf("expected: %#v \n actual: %#v", allocCopy1, out)
  3553  	}
  3554  }
  3555  
  3556  func TestStateStore_JobSummary(t *testing.T) {
  3557  	state := testStateStore(t)
  3558  
  3559  	// Add a job
  3560  	job := mock.Job()
  3561  	state.UpsertJob(900, job)
  3562  
  3563  	// Get the job back
  3564  	ws := memdb.NewWatchSet()
  3565  	outJob, _ := state.JobByID(ws, job.ID)
  3566  	if outJob.CreateIndex != 900 {
  3567  		t.Fatalf("bad create index: %v", outJob.CreateIndex)
  3568  	}
  3569  	summary, _ := state.JobSummaryByID(ws, job.ID)
  3570  	if summary.CreateIndex != 900 {
  3571  		t.Fatalf("bad create index: %v", summary.CreateIndex)
  3572  	}
  3573  
  3574  	// Upsert an allocation
  3575  	alloc := mock.Alloc()
  3576  	alloc.JobID = job.ID
  3577  	alloc.Job = job
  3578  	state.UpsertAllocs(910, []*structs.Allocation{alloc})
  3579  
  3580  	// Update the alloc from client
  3581  	alloc1 := alloc.Copy()
  3582  	alloc1.ClientStatus = structs.AllocClientStatusPending
  3583  	alloc1.DesiredStatus = ""
  3584  	state.UpdateAllocsFromClient(920, []*structs.Allocation{alloc})
  3585  
  3586  	alloc3 := alloc.Copy()
  3587  	alloc3.ClientStatus = structs.AllocClientStatusRunning
  3588  	alloc3.DesiredStatus = ""
  3589  	state.UpdateAllocsFromClient(930, []*structs.Allocation{alloc3})
  3590  
  3591  	// Upsert the alloc
  3592  	alloc4 := alloc.Copy()
  3593  	alloc4.ClientStatus = structs.AllocClientStatusPending
  3594  	alloc4.DesiredStatus = structs.AllocDesiredStatusRun
  3595  	state.UpsertAllocs(950, []*structs.Allocation{alloc4})
  3596  
  3597  	// Again upsert the alloc
  3598  	alloc5 := alloc.Copy()
  3599  	alloc5.ClientStatus = structs.AllocClientStatusPending
  3600  	alloc5.DesiredStatus = structs.AllocDesiredStatusRun
  3601  	state.UpsertAllocs(970, []*structs.Allocation{alloc5})
  3602  
  3603  	if !watchFired(ws) {
  3604  		t.Fatalf("bad")
  3605  	}
  3606  
  3607  	expectedSummary := structs.JobSummary{
  3608  		JobID: job.ID,
  3609  		Summary: map[string]structs.TaskGroupSummary{
  3610  			"web": structs.TaskGroupSummary{
  3611  				Running: 1,
  3612  			},
  3613  		},
  3614  		Children:    new(structs.JobChildrenSummary),
  3615  		CreateIndex: 900,
  3616  		ModifyIndex: 930,
  3617  	}
  3618  
  3619  	summary, _ = state.JobSummaryByID(ws, job.ID)
  3620  	if !reflect.DeepEqual(&expectedSummary, summary) {
  3621  		t.Fatalf("expected: %#v, actual: %v", expectedSummary, summary)
  3622  	}
  3623  
  3624  	// De-register the job.
  3625  	state.DeleteJob(980, job.ID)
  3626  
  3627  	// Shouldn't have any effect on the summary
  3628  	alloc6 := alloc.Copy()
  3629  	alloc6.ClientStatus = structs.AllocClientStatusRunning
  3630  	alloc6.DesiredStatus = ""
  3631  	state.UpdateAllocsFromClient(990, []*structs.Allocation{alloc6})
  3632  
  3633  	// We shouldn't have any summary at this point
  3634  	summary, _ = state.JobSummaryByID(ws, job.ID)
  3635  	if summary != nil {
  3636  		t.Fatalf("expected nil, actual: %#v", summary)
  3637  	}
  3638  
  3639  	// Re-register the same job
  3640  	job1 := mock.Job()
  3641  	job1.ID = job.ID
  3642  	state.UpsertJob(1000, job1)
  3643  	outJob2, _ := state.JobByID(ws, job1.ID)
  3644  	if outJob2.CreateIndex != 1000 {
  3645  		t.Fatalf("bad create index: %v", outJob2.CreateIndex)
  3646  	}
  3647  	summary, _ = state.JobSummaryByID(ws, job1.ID)
  3648  	if summary.CreateIndex != 1000 {
  3649  		t.Fatalf("bad create index: %v", summary.CreateIndex)
  3650  	}
  3651  
  3652  	// Upsert an allocation
  3653  	alloc7 := alloc.Copy()
  3654  	alloc7.JobID = outJob.ID
  3655  	alloc7.Job = outJob
  3656  	alloc7.ClientStatus = structs.AllocClientStatusComplete
  3657  	alloc7.DesiredStatus = structs.AllocDesiredStatusRun
  3658  	state.UpdateAllocsFromClient(1020, []*structs.Allocation{alloc7})
  3659  
  3660  	expectedSummary = structs.JobSummary{
  3661  		JobID: job.ID,
  3662  		Summary: map[string]structs.TaskGroupSummary{
  3663  			"web": structs.TaskGroupSummary{},
  3664  		},
  3665  		Children:    new(structs.JobChildrenSummary),
  3666  		CreateIndex: 1000,
  3667  		ModifyIndex: 1000,
  3668  	}
  3669  
  3670  	summary, _ = state.JobSummaryByID(ws, job1.ID)
  3671  	if !reflect.DeepEqual(&expectedSummary, summary) {
  3672  		t.Fatalf("expected: %#v, actual: %#v", expectedSummary, summary)
  3673  	}
  3674  }
  3675  
  3676  func TestStateStore_ReconcileJobSummary(t *testing.T) {
  3677  	state := testStateStore(t)
  3678  
  3679  	// Create an alloc
  3680  	alloc := mock.Alloc()
  3681  
  3682  	// Add another task group to the job
  3683  	tg2 := alloc.Job.TaskGroups[0].Copy()
  3684  	tg2.Name = "db"
  3685  	alloc.Job.TaskGroups = append(alloc.Job.TaskGroups, tg2)
  3686  	state.UpsertJob(100, alloc.Job)
  3687  
  3688  	// Create one more alloc for the db task group
  3689  	alloc2 := mock.Alloc()
  3690  	alloc2.TaskGroup = "db"
  3691  	alloc2.JobID = alloc.JobID
  3692  	alloc2.Job = alloc.Job
  3693  
  3694  	// Upserts the alloc
  3695  	state.UpsertAllocs(110, []*structs.Allocation{alloc, alloc2})
  3696  
  3697  	// Change the state of the first alloc to running
  3698  	alloc3 := alloc.Copy()
  3699  	alloc3.ClientStatus = structs.AllocClientStatusRunning
  3700  	state.UpdateAllocsFromClient(120, []*structs.Allocation{alloc3})
  3701  
  3702  	//Add some more allocs to the second tg
  3703  	alloc4 := mock.Alloc()
  3704  	alloc4.JobID = alloc.JobID
  3705  	alloc4.Job = alloc.Job
  3706  	alloc4.TaskGroup = "db"
  3707  	alloc5 := alloc4.Copy()
  3708  	alloc5.ClientStatus = structs.AllocClientStatusRunning
  3709  
  3710  	alloc6 := mock.Alloc()
  3711  	alloc6.JobID = alloc.JobID
  3712  	alloc6.Job = alloc.Job
  3713  	alloc6.TaskGroup = "db"
  3714  	alloc7 := alloc6.Copy()
  3715  	alloc7.ClientStatus = structs.AllocClientStatusComplete
  3716  
  3717  	alloc8 := mock.Alloc()
  3718  	alloc8.JobID = alloc.JobID
  3719  	alloc8.Job = alloc.Job
  3720  	alloc8.TaskGroup = "db"
  3721  	alloc9 := alloc8.Copy()
  3722  	alloc9.ClientStatus = structs.AllocClientStatusFailed
  3723  
  3724  	alloc10 := mock.Alloc()
  3725  	alloc10.JobID = alloc.JobID
  3726  	alloc10.Job = alloc.Job
  3727  	alloc10.TaskGroup = "db"
  3728  	alloc11 := alloc10.Copy()
  3729  	alloc11.ClientStatus = structs.AllocClientStatusLost
  3730  
  3731  	state.UpsertAllocs(130, []*structs.Allocation{alloc4, alloc6, alloc8, alloc10})
  3732  
  3733  	state.UpdateAllocsFromClient(150, []*structs.Allocation{alloc5, alloc7, alloc9, alloc11})
  3734  
  3735  	// DeleteJobSummary is a helper method and doesn't modify the indexes table
  3736  	state.DeleteJobSummary(130, alloc.Job.ID)
  3737  
  3738  	state.ReconcileJobSummaries(120)
  3739  
  3740  	ws := memdb.NewWatchSet()
  3741  	summary, _ := state.JobSummaryByID(ws, alloc.Job.ID)
  3742  	expectedSummary := structs.JobSummary{
  3743  		JobID: alloc.Job.ID,
  3744  		Summary: map[string]structs.TaskGroupSummary{
  3745  			"web": structs.TaskGroupSummary{
  3746  				Running: 1,
  3747  			},
  3748  			"db": structs.TaskGroupSummary{
  3749  				Starting: 1,
  3750  				Running:  1,
  3751  				Failed:   1,
  3752  				Complete: 1,
  3753  				Lost:     1,
  3754  			},
  3755  		},
  3756  		CreateIndex: 100,
  3757  		ModifyIndex: 120,
  3758  	}
  3759  	if !reflect.DeepEqual(&expectedSummary, summary) {
  3760  		t.Fatalf("expected: %v, actual: %v", expectedSummary, summary)
  3761  	}
  3762  }
  3763  
  3764  func TestStateStore_UpdateAlloc_JobNotPresent(t *testing.T) {
  3765  	state := testStateStore(t)
  3766  
  3767  	alloc := mock.Alloc()
  3768  	state.UpsertJob(100, alloc.Job)
  3769  	state.UpsertAllocs(200, []*structs.Allocation{alloc})
  3770  
  3771  	// Delete the job
  3772  	state.DeleteJob(300, alloc.Job.ID)
  3773  
  3774  	// Update the alloc
  3775  	alloc1 := alloc.Copy()
  3776  	alloc1.ClientStatus = structs.AllocClientStatusRunning
  3777  
  3778  	// Updating allocation should not throw any error
  3779  	if err := state.UpdateAllocsFromClient(400, []*structs.Allocation{alloc1}); err != nil {
  3780  		t.Fatalf("expect err: %v", err)
  3781  	}
  3782  
  3783  	// Re-Register the job
  3784  	state.UpsertJob(500, alloc.Job)
  3785  
  3786  	// Update the alloc again
  3787  	alloc2 := alloc.Copy()
  3788  	alloc2.ClientStatus = structs.AllocClientStatusComplete
  3789  	if err := state.UpdateAllocsFromClient(400, []*structs.Allocation{alloc1}); err != nil {
  3790  		t.Fatalf("expect err: %v", err)
  3791  	}
  3792  
  3793  	// Job Summary of the newly registered job shouldn't account for the
  3794  	// allocation update for the older job
  3795  	expectedSummary := structs.JobSummary{
  3796  		JobID: alloc1.JobID,
  3797  		Summary: map[string]structs.TaskGroupSummary{
  3798  			"web": structs.TaskGroupSummary{},
  3799  		},
  3800  		Children:    new(structs.JobChildrenSummary),
  3801  		CreateIndex: 500,
  3802  		ModifyIndex: 500,
  3803  	}
  3804  
  3805  	ws := memdb.NewWatchSet()
  3806  	summary, _ := state.JobSummaryByID(ws, alloc.Job.ID)
  3807  	if !reflect.DeepEqual(&expectedSummary, summary) {
  3808  		t.Fatalf("expected: %v, actual: %v", expectedSummary, summary)
  3809  	}
  3810  }
  3811  
  3812  func TestStateStore_EvictAlloc_Alloc(t *testing.T) {
  3813  	state := testStateStore(t)
  3814  	alloc := mock.Alloc()
  3815  
  3816  	state.UpsertJobSummary(999, mock.JobSummary(alloc.JobID))
  3817  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
  3818  	if err != nil {
  3819  		t.Fatalf("err: %v", err)
  3820  	}
  3821  
  3822  	alloc2 := new(structs.Allocation)
  3823  	*alloc2 = *alloc
  3824  	alloc2.DesiredStatus = structs.AllocDesiredStatusEvict
  3825  	err = state.UpsertAllocs(1001, []*structs.Allocation{alloc2})
  3826  	if err != nil {
  3827  		t.Fatalf("err: %v", err)
  3828  	}
  3829  
  3830  	ws := memdb.NewWatchSet()
  3831  	out, err := state.AllocByID(ws, alloc.ID)
  3832  	if err != nil {
  3833  		t.Fatalf("err: %v", err)
  3834  	}
  3835  
  3836  	if out.DesiredStatus != structs.AllocDesiredStatusEvict {
  3837  		t.Fatalf("bad: %#v %#v", alloc, out)
  3838  	}
  3839  
  3840  	index, err := state.Index("allocs")
  3841  	if err != nil {
  3842  		t.Fatalf("err: %v", err)
  3843  	}
  3844  	if index != 1001 {
  3845  		t.Fatalf("bad: %d", index)
  3846  	}
  3847  }
  3848  
  3849  func TestStateStore_AllocsByNode(t *testing.T) {
  3850  	state := testStateStore(t)
  3851  	var allocs []*structs.Allocation
  3852  
  3853  	for i := 0; i < 10; i++ {
  3854  		alloc := mock.Alloc()
  3855  		alloc.NodeID = "foo"
  3856  		allocs = append(allocs, alloc)
  3857  	}
  3858  
  3859  	for idx, alloc := range allocs {
  3860  		state.UpsertJobSummary(uint64(900+idx), mock.JobSummary(alloc.JobID))
  3861  	}
  3862  
  3863  	err := state.UpsertAllocs(1000, allocs)
  3864  	if err != nil {
  3865  		t.Fatalf("err: %v", err)
  3866  	}
  3867  
  3868  	ws := memdb.NewWatchSet()
  3869  	out, err := state.AllocsByNode(ws, "foo")
  3870  	if err != nil {
  3871  		t.Fatalf("err: %v", err)
  3872  	}
  3873  
  3874  	sort.Sort(AllocIDSort(allocs))
  3875  	sort.Sort(AllocIDSort(out))
  3876  
  3877  	if !reflect.DeepEqual(allocs, out) {
  3878  		t.Fatalf("bad: %#v %#v", allocs, out)
  3879  	}
  3880  
  3881  	if watchFired(ws) {
  3882  		t.Fatalf("bad")
  3883  	}
  3884  }
  3885  
  3886  func TestStateStore_AllocsByNodeTerminal(t *testing.T) {
  3887  	state := testStateStore(t)
  3888  	var allocs, term, nonterm []*structs.Allocation
  3889  
  3890  	for i := 0; i < 10; i++ {
  3891  		alloc := mock.Alloc()
  3892  		alloc.NodeID = "foo"
  3893  		if i%2 == 0 {
  3894  			alloc.DesiredStatus = structs.AllocDesiredStatusStop
  3895  			term = append(term, alloc)
  3896  		} else {
  3897  			nonterm = append(nonterm, alloc)
  3898  		}
  3899  		allocs = append(allocs, alloc)
  3900  	}
  3901  
  3902  	for idx, alloc := range allocs {
  3903  		state.UpsertJobSummary(uint64(900+idx), mock.JobSummary(alloc.JobID))
  3904  	}
  3905  
  3906  	err := state.UpsertAllocs(1000, allocs)
  3907  	if err != nil {
  3908  		t.Fatalf("err: %v", err)
  3909  	}
  3910  
  3911  	// Verify the terminal allocs
  3912  	ws := memdb.NewWatchSet()
  3913  	out, err := state.AllocsByNodeTerminal(ws, "foo", true)
  3914  	if err != nil {
  3915  		t.Fatalf("err: %v", err)
  3916  	}
  3917  
  3918  	sort.Sort(AllocIDSort(term))
  3919  	sort.Sort(AllocIDSort(out))
  3920  
  3921  	if !reflect.DeepEqual(term, out) {
  3922  		t.Fatalf("bad: %#v %#v", term, out)
  3923  	}
  3924  
  3925  	// Verify the non-terminal allocs
  3926  	out, err = state.AllocsByNodeTerminal(ws, "foo", false)
  3927  	if err != nil {
  3928  		t.Fatalf("err: %v", err)
  3929  	}
  3930  
  3931  	sort.Sort(AllocIDSort(nonterm))
  3932  	sort.Sort(AllocIDSort(out))
  3933  
  3934  	if !reflect.DeepEqual(nonterm, out) {
  3935  		t.Fatalf("bad: %#v %#v", nonterm, out)
  3936  	}
  3937  
  3938  	if watchFired(ws) {
  3939  		t.Fatalf("bad")
  3940  	}
  3941  }
  3942  
  3943  func TestStateStore_AllocsByJob(t *testing.T) {
  3944  	state := testStateStore(t)
  3945  	var allocs []*structs.Allocation
  3946  
  3947  	for i := 0; i < 10; i++ {
  3948  		alloc := mock.Alloc()
  3949  		alloc.JobID = "foo"
  3950  		allocs = append(allocs, alloc)
  3951  	}
  3952  
  3953  	for i, alloc := range allocs {
  3954  		state.UpsertJobSummary(uint64(900+i), mock.JobSummary(alloc.JobID))
  3955  	}
  3956  
  3957  	err := state.UpsertAllocs(1000, allocs)
  3958  	if err != nil {
  3959  		t.Fatalf("err: %v", err)
  3960  	}
  3961  
  3962  	ws := memdb.NewWatchSet()
  3963  	out, err := state.AllocsByJob(ws, "foo", false)
  3964  	if err != nil {
  3965  		t.Fatalf("err: %v", err)
  3966  	}
  3967  
  3968  	sort.Sort(AllocIDSort(allocs))
  3969  	sort.Sort(AllocIDSort(out))
  3970  
  3971  	if !reflect.DeepEqual(allocs, out) {
  3972  		t.Fatalf("bad: %#v %#v", allocs, out)
  3973  	}
  3974  
  3975  	if watchFired(ws) {
  3976  		t.Fatalf("bad")
  3977  	}
  3978  }
  3979  
  3980  func TestStateStore_AllocsForRegisteredJob(t *testing.T) {
  3981  	state := testStateStore(t)
  3982  	var allocs []*structs.Allocation
  3983  	var allocs1 []*structs.Allocation
  3984  
  3985  	job := mock.Job()
  3986  	job.ID = "foo"
  3987  	state.UpsertJob(100, job)
  3988  	for i := 0; i < 3; i++ {
  3989  		alloc := mock.Alloc()
  3990  		alloc.Job = job
  3991  		alloc.JobID = job.ID
  3992  		allocs = append(allocs, alloc)
  3993  	}
  3994  	if err := state.UpsertAllocs(200, allocs); err != nil {
  3995  		t.Fatalf("err: %v", err)
  3996  	}
  3997  
  3998  	if err := state.DeleteJob(250, job.ID); err != nil {
  3999  		t.Fatalf("err: %v", err)
  4000  	}
  4001  
  4002  	job1 := mock.Job()
  4003  	job1.ID = "foo"
  4004  	job1.CreateIndex = 50
  4005  	state.UpsertJob(300, job1)
  4006  	for i := 0; i < 4; i++ {
  4007  		alloc := mock.Alloc()
  4008  		alloc.Job = job1
  4009  		alloc.JobID = job1.ID
  4010  		allocs1 = append(allocs1, alloc)
  4011  	}
  4012  
  4013  	if err := state.UpsertAllocs(1000, allocs1); err != nil {
  4014  		t.Fatalf("err: %v", err)
  4015  	}
  4016  
  4017  	ws := memdb.NewWatchSet()
  4018  	out, err := state.AllocsByJob(ws, job1.ID, true)
  4019  	if err != nil {
  4020  		t.Fatalf("err: %v", err)
  4021  	}
  4022  
  4023  	expected := len(allocs) + len(allocs1)
  4024  	if len(out) != expected {
  4025  		t.Fatalf("expected: %v, actual: %v", expected, len(out))
  4026  	}
  4027  
  4028  	out1, err := state.AllocsByJob(ws, job1.ID, false)
  4029  	expected = len(allocs1)
  4030  	if len(out1) != expected {
  4031  		t.Fatalf("expected: %v, actual: %v", expected, len(out1))
  4032  	}
  4033  
  4034  	if watchFired(ws) {
  4035  		t.Fatalf("bad")
  4036  	}
  4037  }
  4038  
  4039  func TestStateStore_AllocsByIDPrefix(t *testing.T) {
  4040  	state := testStateStore(t)
  4041  	var allocs []*structs.Allocation
  4042  
  4043  	ids := []string{
  4044  		"aaaaaaaa-7bfb-395d-eb95-0685af2176b2",
  4045  		"aaaaaaab-7bfb-395d-eb95-0685af2176b2",
  4046  		"aaaaaabb-7bfb-395d-eb95-0685af2176b2",
  4047  		"aaaaabbb-7bfb-395d-eb95-0685af2176b2",
  4048  		"aaaabbbb-7bfb-395d-eb95-0685af2176b2",
  4049  		"aaabbbbb-7bfb-395d-eb95-0685af2176b2",
  4050  		"aabbbbbb-7bfb-395d-eb95-0685af2176b2",
  4051  		"abbbbbbb-7bfb-395d-eb95-0685af2176b2",
  4052  		"bbbbbbbb-7bfb-395d-eb95-0685af2176b2",
  4053  	}
  4054  	for i := 0; i < 9; i++ {
  4055  		alloc := mock.Alloc()
  4056  		alloc.ID = ids[i]
  4057  		allocs = append(allocs, alloc)
  4058  	}
  4059  
  4060  	for i, alloc := range allocs {
  4061  		state.UpsertJobSummary(uint64(900+i), mock.JobSummary(alloc.JobID))
  4062  	}
  4063  
  4064  	err := state.UpsertAllocs(1000, allocs)
  4065  	if err != nil {
  4066  		t.Fatalf("err: %v", err)
  4067  	}
  4068  
  4069  	ws := memdb.NewWatchSet()
  4070  	iter, err := state.AllocsByIDPrefix(ws, "aaaa")
  4071  	if err != nil {
  4072  		t.Fatalf("err: %v", err)
  4073  	}
  4074  
  4075  	gatherAllocs := func(iter memdb.ResultIterator) []*structs.Allocation {
  4076  		var allocs []*structs.Allocation
  4077  		for {
  4078  			raw := iter.Next()
  4079  			if raw == nil {
  4080  				break
  4081  			}
  4082  			allocs = append(allocs, raw.(*structs.Allocation))
  4083  		}
  4084  		return allocs
  4085  	}
  4086  
  4087  	out := gatherAllocs(iter)
  4088  	if len(out) != 5 {
  4089  		t.Fatalf("bad: expected five allocations, got: %#v", out)
  4090  	}
  4091  
  4092  	sort.Sort(AllocIDSort(allocs))
  4093  
  4094  	for index, alloc := range out {
  4095  		if ids[index] != alloc.ID {
  4096  			t.Fatalf("bad: got unexpected id: %s", alloc.ID)
  4097  		}
  4098  	}
  4099  
  4100  	iter, err = state.AllocsByIDPrefix(ws, "b-a7bfb")
  4101  	if err != nil {
  4102  		t.Fatalf("err: %v", err)
  4103  	}
  4104  
  4105  	out = gatherAllocs(iter)
  4106  	if len(out) != 0 {
  4107  		t.Fatalf("bad: unexpected zero allocations, got: %#v", out)
  4108  	}
  4109  
  4110  	if watchFired(ws) {
  4111  		t.Fatalf("bad")
  4112  	}
  4113  }
  4114  
  4115  func TestStateStore_Allocs(t *testing.T) {
  4116  	state := testStateStore(t)
  4117  	var allocs []*structs.Allocation
  4118  
  4119  	for i := 0; i < 10; i++ {
  4120  		alloc := mock.Alloc()
  4121  		allocs = append(allocs, alloc)
  4122  	}
  4123  	for i, alloc := range allocs {
  4124  		state.UpsertJobSummary(uint64(900+i), mock.JobSummary(alloc.JobID))
  4125  	}
  4126  
  4127  	err := state.UpsertAllocs(1000, allocs)
  4128  	if err != nil {
  4129  		t.Fatalf("err: %v", err)
  4130  	}
  4131  
  4132  	ws := memdb.NewWatchSet()
  4133  	iter, err := state.Allocs(ws)
  4134  	if err != nil {
  4135  		t.Fatalf("err: %v", err)
  4136  	}
  4137  
  4138  	var out []*structs.Allocation
  4139  	for {
  4140  		raw := iter.Next()
  4141  		if raw == nil {
  4142  			break
  4143  		}
  4144  		out = append(out, raw.(*structs.Allocation))
  4145  	}
  4146  
  4147  	sort.Sort(AllocIDSort(allocs))
  4148  	sort.Sort(AllocIDSort(out))
  4149  
  4150  	if !reflect.DeepEqual(allocs, out) {
  4151  		t.Fatalf("bad: %#v %#v", allocs, out)
  4152  	}
  4153  
  4154  	if watchFired(ws) {
  4155  		t.Fatalf("bad")
  4156  	}
  4157  }
  4158  
  4159  func TestStateStore_RestoreAlloc(t *testing.T) {
  4160  	state := testStateStore(t)
  4161  	alloc := mock.Alloc()
  4162  
  4163  	restore, err := state.Restore()
  4164  	if err != nil {
  4165  		t.Fatalf("err: %v", err)
  4166  	}
  4167  
  4168  	err = restore.AllocRestore(alloc)
  4169  	if err != nil {
  4170  		t.Fatalf("err: %v", err)
  4171  	}
  4172  
  4173  	restore.Commit()
  4174  
  4175  	ws := memdb.NewWatchSet()
  4176  	out, err := state.AllocByID(ws, alloc.ID)
  4177  	if err != nil {
  4178  		t.Fatalf("err: %v", err)
  4179  	}
  4180  
  4181  	if !reflect.DeepEqual(out, alloc) {
  4182  		t.Fatalf("Bad: %#v %#v", out, alloc)
  4183  	}
  4184  
  4185  	if watchFired(ws) {
  4186  		t.Fatalf("bad")
  4187  	}
  4188  }
  4189  
  4190  func TestStateStore_RestoreAlloc_NoEphemeralDisk(t *testing.T) {
  4191  	state := testStateStore(t)
  4192  	alloc := mock.Alloc()
  4193  	alloc.Job.TaskGroups[0].EphemeralDisk = nil
  4194  	alloc.Job.TaskGroups[0].Tasks[0].Resources.DiskMB = 120
  4195  
  4196  	restore, err := state.Restore()
  4197  	if err != nil {
  4198  		t.Fatalf("err: %v", err)
  4199  	}
  4200  
  4201  	err = restore.AllocRestore(alloc)
  4202  	if err != nil {
  4203  		t.Fatalf("err: %v", err)
  4204  	}
  4205  
  4206  	restore.Commit()
  4207  
  4208  	ws := memdb.NewWatchSet()
  4209  	out, err := state.AllocByID(ws, alloc.ID)
  4210  	if err != nil {
  4211  		t.Fatalf("err: %v", err)
  4212  	}
  4213  
  4214  	expected := alloc.Copy()
  4215  	expected.Job.TaskGroups[0].EphemeralDisk = &structs.EphemeralDisk{SizeMB: 120}
  4216  	expected.Job.TaskGroups[0].Tasks[0].Resources.DiskMB = 0
  4217  
  4218  	if !reflect.DeepEqual(out, expected) {
  4219  		t.Fatalf("Bad: %#v %#v", out, expected)
  4220  	}
  4221  
  4222  	if watchFired(ws) {
  4223  		t.Fatalf("bad")
  4224  	}
  4225  }
  4226  
  4227  func TestStateStore_SetJobStatus_ForceStatus(t *testing.T) {
  4228  	state := testStateStore(t)
  4229  	txn := state.db.Txn(true)
  4230  
  4231  	// Create and insert a mock job.
  4232  	job := mock.Job()
  4233  	job.Status = ""
  4234  	job.ModifyIndex = 0
  4235  	if err := txn.Insert("jobs", job); err != nil {
  4236  		t.Fatalf("job insert failed: %v", err)
  4237  	}
  4238  
  4239  	exp := "foobar"
  4240  	index := uint64(1000)
  4241  	if err := state.setJobStatus(index, txn, job, false, exp); err != nil {
  4242  		t.Fatalf("setJobStatus() failed: %v", err)
  4243  	}
  4244  
  4245  	i, err := txn.First("jobs", "id", job.ID)
  4246  	if err != nil {
  4247  		t.Fatalf("job lookup failed: %v", err)
  4248  	}
  4249  	updated := i.(*structs.Job)
  4250  
  4251  	if updated.Status != exp {
  4252  		t.Fatalf("setJobStatus() set %v; expected %v", updated.Status, exp)
  4253  	}
  4254  
  4255  	if updated.ModifyIndex != index {
  4256  		t.Fatalf("setJobStatus() set %d; expected %d", updated.ModifyIndex, index)
  4257  	}
  4258  }
  4259  
  4260  func TestStateStore_SetJobStatus_NoOp(t *testing.T) {
  4261  	state := testStateStore(t)
  4262  	txn := state.db.Txn(true)
  4263  
  4264  	// Create and insert a mock job that should be pending.
  4265  	job := mock.Job()
  4266  	job.Status = structs.JobStatusPending
  4267  	job.ModifyIndex = 10
  4268  	if err := txn.Insert("jobs", job); err != nil {
  4269  		t.Fatalf("job insert failed: %v", err)
  4270  	}
  4271  
  4272  	index := uint64(1000)
  4273  	if err := state.setJobStatus(index, txn, job, false, ""); err != nil {
  4274  		t.Fatalf("setJobStatus() failed: %v", err)
  4275  	}
  4276  
  4277  	i, err := txn.First("jobs", "id", job.ID)
  4278  	if err != nil {
  4279  		t.Fatalf("job lookup failed: %v", err)
  4280  	}
  4281  	updated := i.(*structs.Job)
  4282  
  4283  	if updated.ModifyIndex == index {
  4284  		t.Fatalf("setJobStatus() should have been a no-op")
  4285  	}
  4286  }
  4287  
  4288  func TestStateStore_SetJobStatus(t *testing.T) {
  4289  	state := testStateStore(t)
  4290  	txn := state.db.Txn(true)
  4291  
  4292  	// Create and insert a mock job that should be pending but has an incorrect
  4293  	// status.
  4294  	job := mock.Job()
  4295  	job.Status = "foobar"
  4296  	job.ModifyIndex = 10
  4297  	if err := txn.Insert("jobs", job); err != nil {
  4298  		t.Fatalf("job insert failed: %v", err)
  4299  	}
  4300  
  4301  	index := uint64(1000)
  4302  	if err := state.setJobStatus(index, txn, job, false, ""); err != nil {
  4303  		t.Fatalf("setJobStatus() failed: %v", err)
  4304  	}
  4305  
  4306  	i, err := txn.First("jobs", "id", job.ID)
  4307  	if err != nil {
  4308  		t.Fatalf("job lookup failed: %v", err)
  4309  	}
  4310  	updated := i.(*structs.Job)
  4311  
  4312  	if updated.Status != structs.JobStatusPending {
  4313  		t.Fatalf("setJobStatus() set %v; expected %v", updated.Status, structs.JobStatusPending)
  4314  	}
  4315  
  4316  	if updated.ModifyIndex != index {
  4317  		t.Fatalf("setJobStatus() set %d; expected %d", updated.ModifyIndex, index)
  4318  	}
  4319  }
  4320  
  4321  func TestStateStore_GetJobStatus_NoEvalsOrAllocs(t *testing.T) {
  4322  	job := mock.Job()
  4323  	state := testStateStore(t)
  4324  	txn := state.db.Txn(false)
  4325  	status, err := state.getJobStatus(txn, job, false)
  4326  	if err != nil {
  4327  		t.Fatalf("getJobStatus() failed: %v", err)
  4328  	}
  4329  
  4330  	if status != structs.JobStatusPending {
  4331  		t.Fatalf("getJobStatus() returned %v; expected %v", status, structs.JobStatusPending)
  4332  	}
  4333  }
  4334  
  4335  func TestStateStore_GetJobStatus_NoEvalsOrAllocs_Periodic(t *testing.T) {
  4336  	job := mock.PeriodicJob()
  4337  	state := testStateStore(t)
  4338  	txn := state.db.Txn(false)
  4339  	status, err := state.getJobStatus(txn, job, false)
  4340  	if err != nil {
  4341  		t.Fatalf("getJobStatus() failed: %v", err)
  4342  	}
  4343  
  4344  	if status != structs.JobStatusRunning {
  4345  		t.Fatalf("getJobStatus() returned %v; expected %v", status, structs.JobStatusRunning)
  4346  	}
  4347  }
  4348  
  4349  func TestStateStore_GetJobStatus_NoEvalsOrAllocs_EvalDelete(t *testing.T) {
  4350  	job := mock.Job()
  4351  	state := testStateStore(t)
  4352  	txn := state.db.Txn(false)
  4353  	status, err := state.getJobStatus(txn, job, true)
  4354  	if err != nil {
  4355  		t.Fatalf("getJobStatus() failed: %v", err)
  4356  	}
  4357  
  4358  	if status != structs.JobStatusDead {
  4359  		t.Fatalf("getJobStatus() returned %v; expected %v", status, structs.JobStatusDead)
  4360  	}
  4361  }
  4362  
  4363  func TestStateStore_GetJobStatus_DeadEvalsAndAllocs(t *testing.T) {
  4364  	state := testStateStore(t)
  4365  	job := mock.Job()
  4366  
  4367  	// Create a mock alloc that is dead.
  4368  	alloc := mock.Alloc()
  4369  	alloc.JobID = job.ID
  4370  	alloc.DesiredStatus = structs.AllocDesiredStatusStop
  4371  	state.UpsertJobSummary(999, mock.JobSummary(alloc.JobID))
  4372  	if err := state.UpsertAllocs(1000, []*structs.Allocation{alloc}); err != nil {
  4373  		t.Fatalf("err: %v", err)
  4374  	}
  4375  
  4376  	// Create a mock eval that is complete
  4377  	eval := mock.Eval()
  4378  	eval.JobID = job.ID
  4379  	eval.Status = structs.EvalStatusComplete
  4380  	if err := state.UpsertEvals(1001, []*structs.Evaluation{eval}); err != nil {
  4381  		t.Fatalf("err: %v", err)
  4382  	}
  4383  
  4384  	txn := state.db.Txn(false)
  4385  	status, err := state.getJobStatus(txn, job, false)
  4386  	if err != nil {
  4387  		t.Fatalf("getJobStatus() failed: %v", err)
  4388  	}
  4389  
  4390  	if status != structs.JobStatusDead {
  4391  		t.Fatalf("getJobStatus() returned %v; expected %v", status, structs.JobStatusDead)
  4392  	}
  4393  }
  4394  
  4395  func TestStateStore_GetJobStatus_RunningAlloc(t *testing.T) {
  4396  	state := testStateStore(t)
  4397  	job := mock.Job()
  4398  
  4399  	// Create a mock alloc that is running.
  4400  	alloc := mock.Alloc()
  4401  	alloc.JobID = job.ID
  4402  	alloc.DesiredStatus = structs.AllocDesiredStatusRun
  4403  	state.UpsertJobSummary(999, mock.JobSummary(alloc.JobID))
  4404  	if err := state.UpsertAllocs(1000, []*structs.Allocation{alloc}); err != nil {
  4405  		t.Fatalf("err: %v", err)
  4406  	}
  4407  
  4408  	txn := state.db.Txn(false)
  4409  	status, err := state.getJobStatus(txn, job, true)
  4410  	if err != nil {
  4411  		t.Fatalf("getJobStatus() failed: %v", err)
  4412  	}
  4413  
  4414  	if status != structs.JobStatusRunning {
  4415  		t.Fatalf("getJobStatus() returned %v; expected %v", status, structs.JobStatusRunning)
  4416  	}
  4417  }
  4418  
  4419  func TestStateStore_GetJobStatus_PeriodicJob(t *testing.T) {
  4420  	state := testStateStore(t)
  4421  	job := mock.PeriodicJob()
  4422  
  4423  	txn := state.db.Txn(false)
  4424  	status, err := state.getJobStatus(txn, job, false)
  4425  	if err != nil {
  4426  		t.Fatalf("getJobStatus() failed: %v", err)
  4427  	}
  4428  
  4429  	if status != structs.JobStatusRunning {
  4430  		t.Fatalf("getJobStatus() returned %v; expected %v", status, structs.JobStatusRunning)
  4431  	}
  4432  
  4433  	// Mark it as stopped
  4434  	job.Stop = true
  4435  	status, err = state.getJobStatus(txn, job, false)
  4436  	if err != nil {
  4437  		t.Fatalf("getJobStatus() failed: %v", err)
  4438  	}
  4439  
  4440  	if status != structs.JobStatusDead {
  4441  		t.Fatalf("getJobStatus() returned %v; expected %v", status, structs.JobStatusDead)
  4442  	}
  4443  }
  4444  
  4445  func TestStateStore_GetJobStatus_ParameterizedJob(t *testing.T) {
  4446  	state := testStateStore(t)
  4447  	job := mock.Job()
  4448  	job.ParameterizedJob = &structs.ParameterizedJobConfig{}
  4449  
  4450  	txn := state.db.Txn(false)
  4451  	status, err := state.getJobStatus(txn, job, false)
  4452  	if err != nil {
  4453  		t.Fatalf("getJobStatus() failed: %v", err)
  4454  	}
  4455  
  4456  	if status != structs.JobStatusRunning {
  4457  		t.Fatalf("getJobStatus() returned %v; expected %v", status, structs.JobStatusRunning)
  4458  	}
  4459  
  4460  	// Mark it as stopped
  4461  	job.Stop = true
  4462  	status, err = state.getJobStatus(txn, job, false)
  4463  	if err != nil {
  4464  		t.Fatalf("getJobStatus() failed: %v", err)
  4465  	}
  4466  
  4467  	if status != structs.JobStatusDead {
  4468  		t.Fatalf("getJobStatus() returned %v; expected %v", status, structs.JobStatusDead)
  4469  	}
  4470  }
  4471  
  4472  func TestStateStore_SetJobStatus_PendingEval(t *testing.T) {
  4473  	state := testStateStore(t)
  4474  	job := mock.Job()
  4475  
  4476  	// Create a mock eval that is pending.
  4477  	eval := mock.Eval()
  4478  	eval.JobID = job.ID
  4479  	eval.Status = structs.EvalStatusPending
  4480  	if err := state.UpsertEvals(1000, []*structs.Evaluation{eval}); err != nil {
  4481  		t.Fatalf("err: %v", err)
  4482  	}
  4483  
  4484  	txn := state.db.Txn(false)
  4485  	status, err := state.getJobStatus(txn, job, true)
  4486  	if err != nil {
  4487  		t.Fatalf("getJobStatus() failed: %v", err)
  4488  	}
  4489  
  4490  	if status != structs.JobStatusPending {
  4491  		t.Fatalf("getJobStatus() returned %v; expected %v", status, structs.JobStatusPending)
  4492  	}
  4493  }
  4494  
  4495  // TestStateStore_SetJobStatus_SystemJob asserts that system jobs are still
  4496  // considered running until explicitly stopped.
  4497  func TestStateStore_SetJobStatus_SystemJob(t *testing.T) {
  4498  	state := testStateStore(t)
  4499  	job := mock.SystemJob()
  4500  
  4501  	// Create a mock eval that is pending.
  4502  	eval := mock.Eval()
  4503  	eval.JobID = job.ID
  4504  	eval.Type = job.Type
  4505  	eval.Status = structs.EvalStatusComplete
  4506  	if err := state.UpsertEvals(1000, []*structs.Evaluation{eval}); err != nil {
  4507  		t.Fatalf("err: %v", err)
  4508  	}
  4509  
  4510  	txn := state.db.Txn(false)
  4511  	status, err := state.getJobStatus(txn, job, true)
  4512  	if err != nil {
  4513  		t.Fatalf("getJobStatus() failed: %v", err)
  4514  	}
  4515  
  4516  	if expected := structs.JobStatusRunning; status != expected {
  4517  		t.Fatalf("getJobStatus() returned %v; expected %v", status, expected)
  4518  	}
  4519  
  4520  	// Stop the job
  4521  	job.Stop = true
  4522  	status, err = state.getJobStatus(txn, job, true)
  4523  	if err != nil {
  4524  		t.Fatalf("getJobStatus() failed: %v", err)
  4525  	}
  4526  
  4527  	if expected := structs.JobStatusDead; status != expected {
  4528  		t.Fatalf("getJobStatus() returned %v; expected %v", status, expected)
  4529  	}
  4530  }
  4531  
  4532  func TestStateJobSummary_UpdateJobCount(t *testing.T) {
  4533  	state := testStateStore(t)
  4534  	alloc := mock.Alloc()
  4535  	job := alloc.Job
  4536  	job.TaskGroups[0].Count = 3
  4537  
  4538  	// Create watchsets so we can test that upsert fires the watch
  4539  	ws := memdb.NewWatchSet()
  4540  	if _, err := state.JobSummaryByID(ws, job.ID); err != nil {
  4541  		t.Fatalf("bad: %v", err)
  4542  	}
  4543  
  4544  	if err := state.UpsertJob(1000, job); err != nil {
  4545  		t.Fatalf("err: %v", err)
  4546  	}
  4547  
  4548  	if err := state.UpsertAllocs(1001, []*structs.Allocation{alloc}); err != nil {
  4549  		t.Fatalf("err: %v", err)
  4550  	}
  4551  
  4552  	if !watchFired(ws) {
  4553  		t.Fatalf("bad")
  4554  	}
  4555  
  4556  	ws = memdb.NewWatchSet()
  4557  	summary, _ := state.JobSummaryByID(ws, job.ID)
  4558  	expectedSummary := structs.JobSummary{
  4559  		JobID: job.ID,
  4560  		Summary: map[string]structs.TaskGroupSummary{
  4561  			"web": {
  4562  				Starting: 1,
  4563  			},
  4564  		},
  4565  		Children:    new(structs.JobChildrenSummary),
  4566  		CreateIndex: 1000,
  4567  		ModifyIndex: 1001,
  4568  	}
  4569  	if !reflect.DeepEqual(summary, &expectedSummary) {
  4570  		t.Fatalf("expected: %v, actual: %v", expectedSummary, summary)
  4571  	}
  4572  
  4573  	// Create watchsets so we can test that upsert fires the watch
  4574  	ws2 := memdb.NewWatchSet()
  4575  	if _, err := state.JobSummaryByID(ws2, job.ID); err != nil {
  4576  		t.Fatalf("bad: %v", err)
  4577  	}
  4578  
  4579  	alloc2 := mock.Alloc()
  4580  	alloc2.Job = job
  4581  	alloc2.JobID = job.ID
  4582  
  4583  	alloc3 := mock.Alloc()
  4584  	alloc3.Job = job
  4585  	alloc3.JobID = job.ID
  4586  
  4587  	if err := state.UpsertAllocs(1002, []*structs.Allocation{alloc2, alloc3}); err != nil {
  4588  		t.Fatalf("err: %v", err)
  4589  	}
  4590  
  4591  	if !watchFired(ws2) {
  4592  		t.Fatalf("bad")
  4593  	}
  4594  
  4595  	outA, _ := state.AllocByID(ws, alloc3.ID)
  4596  
  4597  	summary, _ = state.JobSummaryByID(ws, job.ID)
  4598  	expectedSummary = structs.JobSummary{
  4599  		JobID: job.ID,
  4600  		Summary: map[string]structs.TaskGroupSummary{
  4601  			"web": {
  4602  				Starting: 3,
  4603  			},
  4604  		},
  4605  		Children:    new(structs.JobChildrenSummary),
  4606  		CreateIndex: job.CreateIndex,
  4607  		ModifyIndex: outA.ModifyIndex,
  4608  	}
  4609  	if !reflect.DeepEqual(summary, &expectedSummary) {
  4610  		t.Fatalf("expected summary: %v, actual: %v", expectedSummary, summary)
  4611  	}
  4612  
  4613  	// Create watchsets so we can test that upsert fires the watch
  4614  	ws3 := memdb.NewWatchSet()
  4615  	if _, err := state.JobSummaryByID(ws3, job.ID); err != nil {
  4616  		t.Fatalf("bad: %v", err)
  4617  	}
  4618  
  4619  	alloc4 := mock.Alloc()
  4620  	alloc4.ID = alloc2.ID
  4621  	alloc4.Job = alloc2.Job
  4622  	alloc4.JobID = alloc2.JobID
  4623  	alloc4.ClientStatus = structs.AllocClientStatusComplete
  4624  
  4625  	alloc5 := mock.Alloc()
  4626  	alloc5.ID = alloc3.ID
  4627  	alloc5.Job = alloc3.Job
  4628  	alloc5.JobID = alloc3.JobID
  4629  	alloc5.ClientStatus = structs.AllocClientStatusComplete
  4630  
  4631  	if err := state.UpdateAllocsFromClient(1004, []*structs.Allocation{alloc4, alloc5}); err != nil {
  4632  		t.Fatalf("err: %v", err)
  4633  	}
  4634  
  4635  	if !watchFired(ws2) {
  4636  		t.Fatalf("bad")
  4637  	}
  4638  
  4639  	outA, _ = state.AllocByID(ws, alloc5.ID)
  4640  	summary, _ = state.JobSummaryByID(ws, job.ID)
  4641  	expectedSummary = structs.JobSummary{
  4642  		JobID: job.ID,
  4643  		Summary: map[string]structs.TaskGroupSummary{
  4644  			"web": {
  4645  				Complete: 2,
  4646  				Starting: 1,
  4647  			},
  4648  		},
  4649  		Children:    new(structs.JobChildrenSummary),
  4650  		CreateIndex: job.CreateIndex,
  4651  		ModifyIndex: outA.ModifyIndex,
  4652  	}
  4653  	if !reflect.DeepEqual(summary, &expectedSummary) {
  4654  		t.Fatalf("expected: %v, actual: %v", expectedSummary, summary)
  4655  	}
  4656  }
  4657  
  4658  func TestJobSummary_UpdateClientStatus(t *testing.T) {
  4659  	state := testStateStore(t)
  4660  	alloc := mock.Alloc()
  4661  	job := alloc.Job
  4662  	job.TaskGroups[0].Count = 3
  4663  
  4664  	alloc2 := mock.Alloc()
  4665  	alloc2.Job = job
  4666  	alloc2.JobID = job.ID
  4667  
  4668  	alloc3 := mock.Alloc()
  4669  	alloc3.Job = job
  4670  	alloc3.JobID = job.ID
  4671  
  4672  	err := state.UpsertJob(1000, job)
  4673  	if err != nil {
  4674  		t.Fatalf("err: %v", err)
  4675  	}
  4676  
  4677  	if err := state.UpsertAllocs(1001, []*structs.Allocation{alloc, alloc2, alloc3}); err != nil {
  4678  		t.Fatalf("err: %v", err)
  4679  	}
  4680  
  4681  	ws := memdb.NewWatchSet()
  4682  	summary, _ := state.JobSummaryByID(ws, job.ID)
  4683  	if summary.Summary["web"].Starting != 3 {
  4684  		t.Fatalf("bad job summary: %v", summary)
  4685  	}
  4686  
  4687  	alloc4 := mock.Alloc()
  4688  	alloc4.ID = alloc2.ID
  4689  	alloc4.Job = alloc2.Job
  4690  	alloc4.JobID = alloc2.JobID
  4691  	alloc4.ClientStatus = structs.AllocClientStatusComplete
  4692  
  4693  	alloc5 := mock.Alloc()
  4694  	alloc5.ID = alloc3.ID
  4695  	alloc5.Job = alloc3.Job
  4696  	alloc5.JobID = alloc3.JobID
  4697  	alloc5.ClientStatus = structs.AllocClientStatusFailed
  4698  
  4699  	alloc6 := mock.Alloc()
  4700  	alloc6.ID = alloc.ID
  4701  	alloc6.Job = alloc.Job
  4702  	alloc6.JobID = alloc.JobID
  4703  	alloc6.ClientStatus = structs.AllocClientStatusRunning
  4704  
  4705  	if err := state.UpdateAllocsFromClient(1002, []*structs.Allocation{alloc4, alloc5, alloc6}); err != nil {
  4706  		t.Fatalf("err: %v", err)
  4707  	}
  4708  
  4709  	if !watchFired(ws) {
  4710  		t.Fatalf("bad")
  4711  	}
  4712  
  4713  	summary, _ = state.JobSummaryByID(ws, job.ID)
  4714  	if summary.Summary["web"].Running != 1 || summary.Summary["web"].Failed != 1 || summary.Summary["web"].Complete != 1 {
  4715  		t.Fatalf("bad job summary: %v", summary)
  4716  	}
  4717  
  4718  	alloc7 := mock.Alloc()
  4719  	alloc7.Job = alloc.Job
  4720  	alloc7.JobID = alloc.JobID
  4721  
  4722  	if err := state.UpsertAllocs(1003, []*structs.Allocation{alloc7}); err != nil {
  4723  		t.Fatalf("err: %v", err)
  4724  	}
  4725  	summary, _ = state.JobSummaryByID(ws, job.ID)
  4726  	if summary.Summary["web"].Starting != 1 || summary.Summary["web"].Running != 1 || summary.Summary["web"].Failed != 1 || summary.Summary["web"].Complete != 1 {
  4727  		t.Fatalf("bad job summary: %v", summary)
  4728  	}
  4729  }
  4730  
  4731  // Test that non-existant deployment can't be updated
  4732  func TestStateStore_UpsertDeploymentStatusUpdate_NonExistant(t *testing.T) {
  4733  	state := testStateStore(t)
  4734  
  4735  	// Update the non-existant deployment
  4736  	req := &structs.DeploymentStatusUpdateRequest{
  4737  		DeploymentUpdate: &structs.DeploymentStatusUpdate{
  4738  			DeploymentID: structs.GenerateUUID(),
  4739  			Status:       structs.DeploymentStatusRunning,
  4740  		},
  4741  	}
  4742  	err := state.UpdateDeploymentStatus(2, req)
  4743  	if err == nil || !strings.Contains(err.Error(), "does not exist") {
  4744  		t.Fatalf("expected error updating the status because the deployment doesn't exist")
  4745  	}
  4746  }
  4747  
  4748  // Test that terminal deployment can't be updated
  4749  func TestStateStore_UpsertDeploymentStatusUpdate_Terminal(t *testing.T) {
  4750  	state := testStateStore(t)
  4751  
  4752  	// Insert a terminal deployment
  4753  	d := mock.Deployment()
  4754  	d.Status = structs.DeploymentStatusFailed
  4755  
  4756  	if err := state.UpsertDeployment(1, d); err != nil {
  4757  		t.Fatalf("bad: %v", err)
  4758  	}
  4759  
  4760  	// Update the deployment
  4761  	req := &structs.DeploymentStatusUpdateRequest{
  4762  		DeploymentUpdate: &structs.DeploymentStatusUpdate{
  4763  			DeploymentID: d.ID,
  4764  			Status:       structs.DeploymentStatusRunning,
  4765  		},
  4766  	}
  4767  	err := state.UpdateDeploymentStatus(2, req)
  4768  	if err == nil || !strings.Contains(err.Error(), "has terminal status") {
  4769  		t.Fatalf("expected error updating the status because the deployment is terminal")
  4770  	}
  4771  }
  4772  
  4773  // Test that a non terminal deployment is updated and that a job and eval are
  4774  // created.
  4775  func TestStateStore_UpsertDeploymentStatusUpdate_NonTerminal(t *testing.T) {
  4776  	state := testStateStore(t)
  4777  
  4778  	// Insert a deployment
  4779  	d := mock.Deployment()
  4780  	if err := state.UpsertDeployment(1, d); err != nil {
  4781  		t.Fatalf("bad: %v", err)
  4782  	}
  4783  
  4784  	// Create an eval and a job
  4785  	e := mock.Eval()
  4786  	j := mock.Job()
  4787  
  4788  	// Update the deployment
  4789  	status, desc := structs.DeploymentStatusFailed, "foo"
  4790  	req := &structs.DeploymentStatusUpdateRequest{
  4791  		DeploymentUpdate: &structs.DeploymentStatusUpdate{
  4792  			DeploymentID:      d.ID,
  4793  			Status:            status,
  4794  			StatusDescription: desc,
  4795  		},
  4796  		Job:  j,
  4797  		Eval: e,
  4798  	}
  4799  	err := state.UpdateDeploymentStatus(2, req)
  4800  	if err != nil {
  4801  		t.Fatalf("bad: %v", err)
  4802  	}
  4803  
  4804  	// Check that the status was updated properly
  4805  	ws := memdb.NewWatchSet()
  4806  	dout, err := state.DeploymentByID(ws, d.ID)
  4807  	if err != nil {
  4808  		t.Fatalf("bad: %v", err)
  4809  	}
  4810  	if dout.Status != status || dout.StatusDescription != desc {
  4811  		t.Fatalf("bad: %#v", dout)
  4812  	}
  4813  
  4814  	// Check that the evaluation was created
  4815  	eout, _ := state.EvalByID(ws, e.ID)
  4816  	if err != nil {
  4817  		t.Fatalf("bad: %v", err)
  4818  	}
  4819  	if eout == nil {
  4820  		t.Fatalf("bad: %#v", eout)
  4821  	}
  4822  
  4823  	// Check that the job was created
  4824  	jout, _ := state.JobByID(ws, j.ID)
  4825  	if err != nil {
  4826  		t.Fatalf("bad: %v", err)
  4827  	}
  4828  	if jout == nil {
  4829  		t.Fatalf("bad: %#v", jout)
  4830  	}
  4831  }
  4832  
  4833  // Test that when a deployment is updated to successful the job is updated to
  4834  // stable
  4835  func TestStateStore_UpsertDeploymentStatusUpdate_Successful(t *testing.T) {
  4836  	state := testStateStore(t)
  4837  
  4838  	// Insert a job
  4839  	job := mock.Job()
  4840  	if err := state.UpsertJob(1, job); err != nil {
  4841  		t.Fatalf("bad: %v", err)
  4842  	}
  4843  
  4844  	// Insert a deployment
  4845  	d := structs.NewDeployment(job)
  4846  	if err := state.UpsertDeployment(2, d); err != nil {
  4847  		t.Fatalf("bad: %v", err)
  4848  	}
  4849  
  4850  	// Update the deployment
  4851  	req := &structs.DeploymentStatusUpdateRequest{
  4852  		DeploymentUpdate: &structs.DeploymentStatusUpdate{
  4853  			DeploymentID:      d.ID,
  4854  			Status:            structs.DeploymentStatusSuccessful,
  4855  			StatusDescription: structs.DeploymentStatusDescriptionSuccessful,
  4856  		},
  4857  	}
  4858  	err := state.UpdateDeploymentStatus(3, req)
  4859  	if err != nil {
  4860  		t.Fatalf("bad: %v", err)
  4861  	}
  4862  
  4863  	// Check that the status was updated properly
  4864  	ws := memdb.NewWatchSet()
  4865  	dout, err := state.DeploymentByID(ws, d.ID)
  4866  	if err != nil {
  4867  		t.Fatalf("bad: %v", err)
  4868  	}
  4869  	if dout.Status != structs.DeploymentStatusSuccessful ||
  4870  		dout.StatusDescription != structs.DeploymentStatusDescriptionSuccessful {
  4871  		t.Fatalf("bad: %#v", dout)
  4872  	}
  4873  
  4874  	// Check that the job was created
  4875  	jout, _ := state.JobByID(ws, job.ID)
  4876  	if err != nil {
  4877  		t.Fatalf("bad: %v", err)
  4878  	}
  4879  	if jout == nil {
  4880  		t.Fatalf("bad: %#v", jout)
  4881  	}
  4882  	if !jout.Stable {
  4883  		t.Fatalf("job not marked stable %#v", jout)
  4884  	}
  4885  	if jout.Version != d.JobVersion {
  4886  		t.Fatalf("job version changed; got %d; want %d", jout.Version, d.JobVersion)
  4887  	}
  4888  }
  4889  
  4890  func TestStateStore_UpdateJobStability(t *testing.T) {
  4891  	state := testStateStore(t)
  4892  
  4893  	// Insert a job twice to get two versions
  4894  	job := mock.Job()
  4895  	if err := state.UpsertJob(1, job); err != nil {
  4896  		t.Fatalf("bad: %v", err)
  4897  	}
  4898  
  4899  	if err := state.UpsertJob(2, job); err != nil {
  4900  		t.Fatalf("bad: %v", err)
  4901  	}
  4902  
  4903  	// Update the stability to true
  4904  	err := state.UpdateJobStability(3, job.ID, 0, true)
  4905  	if err != nil {
  4906  		t.Fatalf("bad: %v", err)
  4907  	}
  4908  
  4909  	// Check that the job was updated properly
  4910  	ws := memdb.NewWatchSet()
  4911  	jout, _ := state.JobByIDAndVersion(ws, job.ID, 0)
  4912  	if err != nil {
  4913  		t.Fatalf("bad: %v", err)
  4914  	}
  4915  	if jout == nil {
  4916  		t.Fatalf("bad: %#v", jout)
  4917  	}
  4918  	if !jout.Stable {
  4919  		t.Fatalf("job not marked stable %#v", jout)
  4920  	}
  4921  
  4922  	// Update the stability to false
  4923  	err = state.UpdateJobStability(3, job.ID, 0, false)
  4924  	if err != nil {
  4925  		t.Fatalf("bad: %v", err)
  4926  	}
  4927  
  4928  	// Check that the job was updated properly
  4929  	jout, _ = state.JobByIDAndVersion(ws, job.ID, 0)
  4930  	if err != nil {
  4931  		t.Fatalf("bad: %v", err)
  4932  	}
  4933  	if jout == nil {
  4934  		t.Fatalf("bad: %#v", jout)
  4935  	}
  4936  	if jout.Stable {
  4937  		t.Fatalf("job marked stable %#v", jout)
  4938  	}
  4939  }
  4940  
  4941  // Test that non-existant deployment can't be promoted
  4942  func TestStateStore_UpsertDeploymentPromotion_NonExistant(t *testing.T) {
  4943  	state := testStateStore(t)
  4944  
  4945  	// Promote the non-existant deployment
  4946  	req := &structs.ApplyDeploymentPromoteRequest{
  4947  		DeploymentPromoteRequest: structs.DeploymentPromoteRequest{
  4948  			DeploymentID: structs.GenerateUUID(),
  4949  			All:          true,
  4950  		},
  4951  	}
  4952  	err := state.UpdateDeploymentPromotion(2, req)
  4953  	if err == nil || !strings.Contains(err.Error(), "does not exist") {
  4954  		t.Fatalf("expected error promoting because the deployment doesn't exist")
  4955  	}
  4956  }
  4957  
  4958  // Test that terminal deployment can't be updated
  4959  func TestStateStore_UpsertDeploymentPromotion_Terminal(t *testing.T) {
  4960  	state := testStateStore(t)
  4961  
  4962  	// Insert a terminal deployment
  4963  	d := mock.Deployment()
  4964  	d.Status = structs.DeploymentStatusFailed
  4965  
  4966  	if err := state.UpsertDeployment(1, d); err != nil {
  4967  		t.Fatalf("bad: %v", err)
  4968  	}
  4969  
  4970  	// Promote the deployment
  4971  	req := &structs.ApplyDeploymentPromoteRequest{
  4972  		DeploymentPromoteRequest: structs.DeploymentPromoteRequest{
  4973  			DeploymentID: d.ID,
  4974  			All:          true,
  4975  		},
  4976  	}
  4977  	err := state.UpdateDeploymentPromotion(2, req)
  4978  	if err == nil || !strings.Contains(err.Error(), "has terminal status") {
  4979  		t.Fatalf("expected error updating the status because the deployment is terminal: %v", err)
  4980  	}
  4981  }
  4982  
  4983  // Test promoting unhealthy canaries in a deployment.
  4984  func TestStateStore_UpsertDeploymentPromotion_Unhealthy(t *testing.T) {
  4985  	state := testStateStore(t)
  4986  
  4987  	// Create a job
  4988  	j := mock.Job()
  4989  	if err := state.UpsertJob(1, j); err != nil {
  4990  		t.Fatalf("bad: %v", err)
  4991  	}
  4992  
  4993  	// Create a deployment
  4994  	d := mock.Deployment()
  4995  	d.JobID = j.ID
  4996  	if err := state.UpsertDeployment(2, d); err != nil {
  4997  		t.Fatalf("bad: %v", err)
  4998  	}
  4999  
  5000  	// Create a set of allocations
  5001  	c1 := mock.Alloc()
  5002  	c1.JobID = j.ID
  5003  	c1.DeploymentID = d.ID
  5004  	d.TaskGroups[c1.TaskGroup].PlacedCanaries = append(d.TaskGroups[c1.TaskGroup].PlacedCanaries, c1.ID)
  5005  	c2 := mock.Alloc()
  5006  	c2.JobID = j.ID
  5007  	c2.DeploymentID = d.ID
  5008  	d.TaskGroups[c2.TaskGroup].PlacedCanaries = append(d.TaskGroups[c2.TaskGroup].PlacedCanaries, c2.ID)
  5009  
  5010  	if err := state.UpsertAllocs(3, []*structs.Allocation{c1, c2}); err != nil {
  5011  		t.Fatalf("err: %v", err)
  5012  	}
  5013  
  5014  	// Promote the canaries
  5015  	req := &structs.ApplyDeploymentPromoteRequest{
  5016  		DeploymentPromoteRequest: structs.DeploymentPromoteRequest{
  5017  			DeploymentID: d.ID,
  5018  			All:          true,
  5019  		},
  5020  	}
  5021  	err := state.UpdateDeploymentPromotion(4, req)
  5022  	if err == nil {
  5023  		t.Fatalf("bad: %v", err)
  5024  	}
  5025  	if !strings.Contains(err.Error(), c1.ID) {
  5026  		t.Fatalf("expect canary %q to be listed as unhealth: %v", c1.ID, err)
  5027  	}
  5028  	if !strings.Contains(err.Error(), c2.ID) {
  5029  		t.Fatalf("expect canary %q to be listed as unhealth: %v", c2.ID, err)
  5030  	}
  5031  }
  5032  
  5033  // Test promoting all canaries in a deployment.
  5034  func TestStateStore_UpsertDeploymentPromotion_All(t *testing.T) {
  5035  	state := testStateStore(t)
  5036  
  5037  	// Create a job with two task groups
  5038  	j := mock.Job()
  5039  	tg1 := j.TaskGroups[0]
  5040  	tg2 := tg1.Copy()
  5041  	tg2.Name = "foo"
  5042  	j.TaskGroups = append(j.TaskGroups, tg2)
  5043  	if err := state.UpsertJob(1, j); err != nil {
  5044  		t.Fatalf("bad: %v", err)
  5045  	}
  5046  
  5047  	// Create a deployment
  5048  	d := mock.Deployment()
  5049  	d.StatusDescription = structs.DeploymentStatusDescriptionRunningNeedsPromotion
  5050  	d.JobID = j.ID
  5051  	d.TaskGroups = map[string]*structs.DeploymentState{
  5052  		"web": &structs.DeploymentState{
  5053  			DesiredTotal:    10,
  5054  			DesiredCanaries: 1,
  5055  		},
  5056  		"foo": &structs.DeploymentState{
  5057  			DesiredTotal:    10,
  5058  			DesiredCanaries: 1,
  5059  		},
  5060  	}
  5061  	if err := state.UpsertDeployment(2, d); err != nil {
  5062  		t.Fatalf("bad: %v", err)
  5063  	}
  5064  
  5065  	// Create a set of allocations
  5066  	c1 := mock.Alloc()
  5067  	c1.JobID = j.ID
  5068  	c1.DeploymentID = d.ID
  5069  	d.TaskGroups[c1.TaskGroup].PlacedCanaries = append(d.TaskGroups[c1.TaskGroup].PlacedCanaries, c1.ID)
  5070  	c1.DeploymentStatus = &structs.AllocDeploymentStatus{
  5071  		Healthy: helper.BoolToPtr(true),
  5072  	}
  5073  	c2 := mock.Alloc()
  5074  	c2.JobID = j.ID
  5075  	c2.DeploymentID = d.ID
  5076  	d.TaskGroups[c2.TaskGroup].PlacedCanaries = append(d.TaskGroups[c2.TaskGroup].PlacedCanaries, c2.ID)
  5077  	c2.TaskGroup = tg2.Name
  5078  	c2.DeploymentStatus = &structs.AllocDeploymentStatus{
  5079  		Healthy: helper.BoolToPtr(true),
  5080  	}
  5081  
  5082  	if err := state.UpsertAllocs(3, []*structs.Allocation{c1, c2}); err != nil {
  5083  		t.Fatalf("err: %v", err)
  5084  	}
  5085  
  5086  	// Create an eval
  5087  	e := mock.Eval()
  5088  
  5089  	// Promote the canaries
  5090  	req := &structs.ApplyDeploymentPromoteRequest{
  5091  		DeploymentPromoteRequest: structs.DeploymentPromoteRequest{
  5092  			DeploymentID: d.ID,
  5093  			All:          true,
  5094  		},
  5095  		Eval: e,
  5096  	}
  5097  	err := state.UpdateDeploymentPromotion(4, req)
  5098  	if err != nil {
  5099  		t.Fatalf("bad: %v", err)
  5100  	}
  5101  
  5102  	// Check that the status per task group was updated properly
  5103  	ws := memdb.NewWatchSet()
  5104  	dout, err := state.DeploymentByID(ws, d.ID)
  5105  	if err != nil {
  5106  		t.Fatalf("bad: %v", err)
  5107  	}
  5108  	if dout.StatusDescription != structs.DeploymentStatusDescriptionRunning {
  5109  		t.Fatalf("status description not updated: got %v; want %v", dout.StatusDescription, structs.DeploymentStatusDescriptionRunning)
  5110  	}
  5111  	if len(dout.TaskGroups) != 2 {
  5112  		t.Fatalf("bad: %#v", dout.TaskGroups)
  5113  	}
  5114  	for tg, state := range dout.TaskGroups {
  5115  		if !state.Promoted {
  5116  			t.Fatalf("bad: group %q not promoted %#v", tg, state)
  5117  		}
  5118  	}
  5119  
  5120  	// Check that the evaluation was created
  5121  	eout, _ := state.EvalByID(ws, e.ID)
  5122  	if err != nil {
  5123  		t.Fatalf("bad: %v", err)
  5124  	}
  5125  	if eout == nil {
  5126  		t.Fatalf("bad: %#v", eout)
  5127  	}
  5128  }
  5129  
  5130  // Test promoting a subset of canaries in a deployment.
  5131  func TestStateStore_UpsertDeploymentPromotion_Subset(t *testing.T) {
  5132  	state := testStateStore(t)
  5133  
  5134  	// Create a job with two task groups
  5135  	j := mock.Job()
  5136  	tg1 := j.TaskGroups[0]
  5137  	tg2 := tg1.Copy()
  5138  	tg2.Name = "foo"
  5139  	j.TaskGroups = append(j.TaskGroups, tg2)
  5140  	if err := state.UpsertJob(1, j); err != nil {
  5141  		t.Fatalf("bad: %v", err)
  5142  	}
  5143  
  5144  	// Create a deployment
  5145  	d := mock.Deployment()
  5146  	d.JobID = j.ID
  5147  	d.TaskGroups = map[string]*structs.DeploymentState{
  5148  		"web": &structs.DeploymentState{
  5149  			DesiredTotal:    10,
  5150  			DesiredCanaries: 1,
  5151  		},
  5152  		"foo": &structs.DeploymentState{
  5153  			DesiredTotal:    10,
  5154  			DesiredCanaries: 1,
  5155  		},
  5156  	}
  5157  	if err := state.UpsertDeployment(2, d); err != nil {
  5158  		t.Fatalf("bad: %v", err)
  5159  	}
  5160  
  5161  	// Create a set of allocations
  5162  	c1 := mock.Alloc()
  5163  	c1.JobID = j.ID
  5164  	c1.DeploymentID = d.ID
  5165  	d.TaskGroups[c1.TaskGroup].PlacedCanaries = append(d.TaskGroups[c1.TaskGroup].PlacedCanaries, c1.ID)
  5166  	c1.DeploymentStatus = &structs.AllocDeploymentStatus{
  5167  		Healthy: helper.BoolToPtr(true),
  5168  	}
  5169  	c2 := mock.Alloc()
  5170  	c2.JobID = j.ID
  5171  	c2.DeploymentID = d.ID
  5172  	d.TaskGroups[c2.TaskGroup].PlacedCanaries = append(d.TaskGroups[c2.TaskGroup].PlacedCanaries, c2.ID)
  5173  	c2.TaskGroup = tg2.Name
  5174  	c2.DeploymentStatus = &structs.AllocDeploymentStatus{
  5175  		Healthy: helper.BoolToPtr(true),
  5176  	}
  5177  
  5178  	if err := state.UpsertAllocs(3, []*structs.Allocation{c1, c2}); err != nil {
  5179  		t.Fatalf("err: %v", err)
  5180  	}
  5181  
  5182  	// Create an eval
  5183  	e := mock.Eval()
  5184  
  5185  	// Promote the canaries
  5186  	req := &structs.ApplyDeploymentPromoteRequest{
  5187  		DeploymentPromoteRequest: structs.DeploymentPromoteRequest{
  5188  			DeploymentID: d.ID,
  5189  			Groups:       []string{"web"},
  5190  		},
  5191  		Eval: e,
  5192  	}
  5193  	err := state.UpdateDeploymentPromotion(4, req)
  5194  	if err != nil {
  5195  		t.Fatalf("bad: %v", err)
  5196  	}
  5197  
  5198  	// Check that the status per task group was updated properly
  5199  	ws := memdb.NewWatchSet()
  5200  	dout, err := state.DeploymentByID(ws, d.ID)
  5201  	if err != nil {
  5202  		t.Fatalf("bad: %v", err)
  5203  	}
  5204  	if len(dout.TaskGroups) != 2 {
  5205  		t.Fatalf("bad: %#v", dout.TaskGroups)
  5206  	}
  5207  	stateout, ok := dout.TaskGroups["web"]
  5208  	if !ok {
  5209  		t.Fatalf("bad: no state for task group web")
  5210  	}
  5211  	if !stateout.Promoted {
  5212  		t.Fatalf("bad: task group web not promoted: %#v", stateout)
  5213  	}
  5214  
  5215  	// Check that the evaluation was created
  5216  	eout, _ := state.EvalByID(ws, e.ID)
  5217  	if err != nil {
  5218  		t.Fatalf("bad: %v", err)
  5219  	}
  5220  	if eout == nil {
  5221  		t.Fatalf("bad: %#v", eout)
  5222  	}
  5223  }
  5224  
  5225  // Test that allocation health can't be set against a non-existant deployment
  5226  func TestStateStore_UpsertDeploymentAllocHealth_NonExistant(t *testing.T) {
  5227  	state := testStateStore(t)
  5228  
  5229  	// Set health against the non-existant deployment
  5230  	req := &structs.ApplyDeploymentAllocHealthRequest{
  5231  		DeploymentAllocHealthRequest: structs.DeploymentAllocHealthRequest{
  5232  			DeploymentID:         structs.GenerateUUID(),
  5233  			HealthyAllocationIDs: []string{structs.GenerateUUID()},
  5234  		},
  5235  	}
  5236  	err := state.UpdateDeploymentAllocHealth(2, req)
  5237  	if err == nil || !strings.Contains(err.Error(), "does not exist") {
  5238  		t.Fatalf("expected error because the deployment doesn't exist: %v", err)
  5239  	}
  5240  }
  5241  
  5242  // Test that allocation health can't be set against a terminal deployment
  5243  func TestStateStore_UpsertDeploymentAllocHealth_Terminal(t *testing.T) {
  5244  	state := testStateStore(t)
  5245  
  5246  	// Insert a terminal deployment
  5247  	d := mock.Deployment()
  5248  	d.Status = structs.DeploymentStatusFailed
  5249  
  5250  	if err := state.UpsertDeployment(1, d); err != nil {
  5251  		t.Fatalf("bad: %v", err)
  5252  	}
  5253  
  5254  	// Set health against the terminal deployment
  5255  	req := &structs.ApplyDeploymentAllocHealthRequest{
  5256  		DeploymentAllocHealthRequest: structs.DeploymentAllocHealthRequest{
  5257  			DeploymentID:         d.ID,
  5258  			HealthyAllocationIDs: []string{structs.GenerateUUID()},
  5259  		},
  5260  	}
  5261  	err := state.UpdateDeploymentAllocHealth(2, req)
  5262  	if err == nil || !strings.Contains(err.Error(), "has terminal status") {
  5263  		t.Fatalf("expected error because the deployment is terminal: %v", err)
  5264  	}
  5265  }
  5266  
  5267  // Test that allocation health can't be set against a non-existant alloc
  5268  func TestStateStore_UpsertDeploymentAllocHealth_BadAlloc_NonExistant(t *testing.T) {
  5269  	state := testStateStore(t)
  5270  
  5271  	// Insert a deployment
  5272  	d := mock.Deployment()
  5273  	if err := state.UpsertDeployment(1, d); err != nil {
  5274  		t.Fatalf("bad: %v", err)
  5275  	}
  5276  
  5277  	// Set health against the terminal deployment
  5278  	req := &structs.ApplyDeploymentAllocHealthRequest{
  5279  		DeploymentAllocHealthRequest: structs.DeploymentAllocHealthRequest{
  5280  			DeploymentID:         d.ID,
  5281  			HealthyAllocationIDs: []string{structs.GenerateUUID()},
  5282  		},
  5283  	}
  5284  	err := state.UpdateDeploymentAllocHealth(2, req)
  5285  	if err == nil || !strings.Contains(err.Error(), "unknown alloc") {
  5286  		t.Fatalf("expected error because the alloc doesn't exist: %v", err)
  5287  	}
  5288  }
  5289  
  5290  // Test that allocation health can't be set for an alloc with mismatched
  5291  // deployment ids
  5292  func TestStateStore_UpsertDeploymentAllocHealth_BadAlloc_MismatchDeployment(t *testing.T) {
  5293  	state := testStateStore(t)
  5294  
  5295  	// Insert two  deployment
  5296  	d1 := mock.Deployment()
  5297  	d2 := mock.Deployment()
  5298  	if err := state.UpsertDeployment(1, d1); err != nil {
  5299  		t.Fatalf("bad: %v", err)
  5300  	}
  5301  	if err := state.UpsertDeployment(2, d2); err != nil {
  5302  		t.Fatalf("bad: %v", err)
  5303  	}
  5304  
  5305  	// Insert an alloc for a random deployment
  5306  	a := mock.Alloc()
  5307  	a.DeploymentID = d1.ID
  5308  	if err := state.UpsertAllocs(3, []*structs.Allocation{a}); err != nil {
  5309  		t.Fatalf("bad: %v", err)
  5310  	}
  5311  
  5312  	// Set health against the terminal deployment
  5313  	req := &structs.ApplyDeploymentAllocHealthRequest{
  5314  		DeploymentAllocHealthRequest: structs.DeploymentAllocHealthRequest{
  5315  			DeploymentID:         d2.ID,
  5316  			HealthyAllocationIDs: []string{a.ID},
  5317  		},
  5318  	}
  5319  	err := state.UpdateDeploymentAllocHealth(4, req)
  5320  	if err == nil || !strings.Contains(err.Error(), "not part of deployment") {
  5321  		t.Fatalf("expected error because the alloc isn't part of the deployment: %v", err)
  5322  	}
  5323  }
  5324  
  5325  // Test that allocation health is properly set
  5326  func TestStateStore_UpsertDeploymentAllocHealth(t *testing.T) {
  5327  	state := testStateStore(t)
  5328  
  5329  	// Insert a deployment
  5330  	d := mock.Deployment()
  5331  	if err := state.UpsertDeployment(1, d); err != nil {
  5332  		t.Fatalf("bad: %v", err)
  5333  	}
  5334  
  5335  	// Insert two allocations
  5336  	a1 := mock.Alloc()
  5337  	a1.DeploymentID = d.ID
  5338  	a2 := mock.Alloc()
  5339  	a2.DeploymentID = d.ID
  5340  	if err := state.UpsertAllocs(2, []*structs.Allocation{a1, a2}); err != nil {
  5341  		t.Fatalf("bad: %v", err)
  5342  	}
  5343  
  5344  	// Create a job to roll back to
  5345  	j := mock.Job()
  5346  
  5347  	// Create an eval that should be upserted
  5348  	e := mock.Eval()
  5349  
  5350  	// Create a status update for the deployment
  5351  	status, desc := structs.DeploymentStatusFailed, "foo"
  5352  	u := &structs.DeploymentStatusUpdate{
  5353  		DeploymentID:      d.ID,
  5354  		Status:            status,
  5355  		StatusDescription: desc,
  5356  	}
  5357  
  5358  	// Set health against the deployment
  5359  	req := &structs.ApplyDeploymentAllocHealthRequest{
  5360  		DeploymentAllocHealthRequest: structs.DeploymentAllocHealthRequest{
  5361  			DeploymentID:           d.ID,
  5362  			HealthyAllocationIDs:   []string{a1.ID},
  5363  			UnhealthyAllocationIDs: []string{a2.ID},
  5364  		},
  5365  		Job:              j,
  5366  		Eval:             e,
  5367  		DeploymentUpdate: u,
  5368  	}
  5369  	err := state.UpdateDeploymentAllocHealth(3, req)
  5370  	if err != nil {
  5371  		t.Fatalf("bad: %v", err)
  5372  	}
  5373  
  5374  	// Check that the status was updated properly
  5375  	ws := memdb.NewWatchSet()
  5376  	dout, err := state.DeploymentByID(ws, d.ID)
  5377  	if err != nil {
  5378  		t.Fatalf("bad: %v", err)
  5379  	}
  5380  	if dout.Status != status || dout.StatusDescription != desc {
  5381  		t.Fatalf("bad: %#v", dout)
  5382  	}
  5383  
  5384  	// Check that the evaluation was created
  5385  	eout, _ := state.EvalByID(ws, e.ID)
  5386  	if err != nil {
  5387  		t.Fatalf("bad: %v", err)
  5388  	}
  5389  	if eout == nil {
  5390  		t.Fatalf("bad: %#v", eout)
  5391  	}
  5392  
  5393  	// Check that the job was created
  5394  	jout, _ := state.JobByID(ws, j.ID)
  5395  	if err != nil {
  5396  		t.Fatalf("bad: %v", err)
  5397  	}
  5398  	if jout == nil {
  5399  		t.Fatalf("bad: %#v", jout)
  5400  	}
  5401  
  5402  	// Check the status of the allocs
  5403  	out1, err := state.AllocByID(ws, a1.ID)
  5404  	if err != nil {
  5405  		t.Fatalf("err: %v", err)
  5406  	}
  5407  	out2, err := state.AllocByID(ws, a2.ID)
  5408  	if err != nil {
  5409  		t.Fatalf("err: %v", err)
  5410  	}
  5411  
  5412  	if !out1.DeploymentStatus.IsHealthy() {
  5413  		t.Fatalf("bad: alloc %q not healthy", out1.ID)
  5414  	}
  5415  	if !out2.DeploymentStatus.IsUnhealthy() {
  5416  		t.Fatalf("bad: alloc %q not unhealthy", out2.ID)
  5417  	}
  5418  }
  5419  
  5420  func TestStateStore_UpsertVaultAccessors(t *testing.T) {
  5421  	state := testStateStore(t)
  5422  	a := mock.VaultAccessor()
  5423  	a2 := mock.VaultAccessor()
  5424  
  5425  	ws := memdb.NewWatchSet()
  5426  	if _, err := state.VaultAccessor(ws, a.Accessor); err != nil {
  5427  		t.Fatalf("err: %v", err)
  5428  	}
  5429  
  5430  	if _, err := state.VaultAccessor(ws, a2.Accessor); err != nil {
  5431  		t.Fatalf("err: %v", err)
  5432  	}
  5433  
  5434  	err := state.UpsertVaultAccessor(1000, []*structs.VaultAccessor{a, a2})
  5435  	if err != nil {
  5436  		t.Fatalf("err: %v", err)
  5437  	}
  5438  
  5439  	if !watchFired(ws) {
  5440  		t.Fatalf("bad")
  5441  	}
  5442  
  5443  	ws = memdb.NewWatchSet()
  5444  	out, err := state.VaultAccessor(ws, a.Accessor)
  5445  	if err != nil {
  5446  		t.Fatalf("err: %v", err)
  5447  	}
  5448  
  5449  	if !reflect.DeepEqual(a, out) {
  5450  		t.Fatalf("bad: %#v %#v", a, out)
  5451  	}
  5452  
  5453  	out, err = state.VaultAccessor(ws, a2.Accessor)
  5454  	if err != nil {
  5455  		t.Fatalf("err: %v", err)
  5456  	}
  5457  
  5458  	if !reflect.DeepEqual(a2, out) {
  5459  		t.Fatalf("bad: %#v %#v", a2, out)
  5460  	}
  5461  
  5462  	iter, err := state.VaultAccessors(ws)
  5463  	if err != nil {
  5464  		t.Fatalf("err: %v", err)
  5465  	}
  5466  
  5467  	count := 0
  5468  	for {
  5469  		raw := iter.Next()
  5470  		if raw == nil {
  5471  			break
  5472  		}
  5473  
  5474  		count++
  5475  		accessor := raw.(*structs.VaultAccessor)
  5476  
  5477  		if !reflect.DeepEqual(accessor, a) && !reflect.DeepEqual(accessor, a2) {
  5478  			t.Fatalf("bad: %#v", accessor)
  5479  		}
  5480  	}
  5481  
  5482  	if count != 2 {
  5483  		t.Fatalf("bad: %d", count)
  5484  	}
  5485  
  5486  	index, err := state.Index("vault_accessors")
  5487  	if err != nil {
  5488  		t.Fatalf("err: %v", err)
  5489  	}
  5490  	if index != 1000 {
  5491  		t.Fatalf("bad: %d", index)
  5492  	}
  5493  
  5494  	if watchFired(ws) {
  5495  		t.Fatalf("bad")
  5496  	}
  5497  }
  5498  
  5499  func TestStateStore_DeleteVaultAccessors(t *testing.T) {
  5500  	state := testStateStore(t)
  5501  	a1 := mock.VaultAccessor()
  5502  	a2 := mock.VaultAccessor()
  5503  	accessors := []*structs.VaultAccessor{a1, a2}
  5504  
  5505  	err := state.UpsertVaultAccessor(1000, accessors)
  5506  	if err != nil {
  5507  		t.Fatalf("err: %v", err)
  5508  	}
  5509  
  5510  	ws := memdb.NewWatchSet()
  5511  	if _, err := state.VaultAccessor(ws, a1.Accessor); err != nil {
  5512  		t.Fatalf("err: %v", err)
  5513  	}
  5514  
  5515  	err = state.DeleteVaultAccessors(1001, accessors)
  5516  	if err != nil {
  5517  		t.Fatalf("err: %v", err)
  5518  	}
  5519  
  5520  	if !watchFired(ws) {
  5521  		t.Fatalf("bad")
  5522  	}
  5523  
  5524  	ws = memdb.NewWatchSet()
  5525  	out, err := state.VaultAccessor(ws, a1.Accessor)
  5526  	if err != nil {
  5527  		t.Fatalf("err: %v", err)
  5528  	}
  5529  	if out != nil {
  5530  		t.Fatalf("bad: %#v %#v", a1, out)
  5531  	}
  5532  	out, err = state.VaultAccessor(ws, a2.Accessor)
  5533  	if err != nil {
  5534  		t.Fatalf("err: %v", err)
  5535  	}
  5536  	if out != nil {
  5537  		t.Fatalf("bad: %#v %#v", a2, out)
  5538  	}
  5539  
  5540  	index, err := state.Index("vault_accessors")
  5541  	if err != nil {
  5542  		t.Fatalf("err: %v", err)
  5543  	}
  5544  	if index != 1001 {
  5545  		t.Fatalf("bad: %d", index)
  5546  	}
  5547  
  5548  	if watchFired(ws) {
  5549  		t.Fatalf("bad")
  5550  	}
  5551  }
  5552  
  5553  func TestStateStore_VaultAccessorsByAlloc(t *testing.T) {
  5554  	state := testStateStore(t)
  5555  	alloc := mock.Alloc()
  5556  	var accessors []*structs.VaultAccessor
  5557  	var expected []*structs.VaultAccessor
  5558  
  5559  	for i := 0; i < 5; i++ {
  5560  		accessor := mock.VaultAccessor()
  5561  		accessor.AllocID = alloc.ID
  5562  		expected = append(expected, accessor)
  5563  		accessors = append(accessors, accessor)
  5564  	}
  5565  
  5566  	for i := 0; i < 10; i++ {
  5567  		accessor := mock.VaultAccessor()
  5568  		accessors = append(accessors, accessor)
  5569  	}
  5570  
  5571  	err := state.UpsertVaultAccessor(1000, accessors)
  5572  	if err != nil {
  5573  		t.Fatalf("err: %v", err)
  5574  	}
  5575  
  5576  	ws := memdb.NewWatchSet()
  5577  	out, err := state.VaultAccessorsByAlloc(ws, alloc.ID)
  5578  	if err != nil {
  5579  		t.Fatalf("err: %v", err)
  5580  	}
  5581  
  5582  	if len(expected) != len(out) {
  5583  		t.Fatalf("bad: %#v %#v", len(expected), len(out))
  5584  	}
  5585  
  5586  	index, err := state.Index("vault_accessors")
  5587  	if err != nil {
  5588  		t.Fatalf("err: %v", err)
  5589  	}
  5590  	if index != 1000 {
  5591  		t.Fatalf("bad: %d", index)
  5592  	}
  5593  
  5594  	if watchFired(ws) {
  5595  		t.Fatalf("bad")
  5596  	}
  5597  }
  5598  
  5599  func TestStateStore_VaultAccessorsByNode(t *testing.T) {
  5600  	state := testStateStore(t)
  5601  	node := mock.Node()
  5602  	var accessors []*structs.VaultAccessor
  5603  	var expected []*structs.VaultAccessor
  5604  
  5605  	for i := 0; i < 5; i++ {
  5606  		accessor := mock.VaultAccessor()
  5607  		accessor.NodeID = node.ID
  5608  		expected = append(expected, accessor)
  5609  		accessors = append(accessors, accessor)
  5610  	}
  5611  
  5612  	for i := 0; i < 10; i++ {
  5613  		accessor := mock.VaultAccessor()
  5614  		accessors = append(accessors, accessor)
  5615  	}
  5616  
  5617  	err := state.UpsertVaultAccessor(1000, accessors)
  5618  	if err != nil {
  5619  		t.Fatalf("err: %v", err)
  5620  	}
  5621  
  5622  	ws := memdb.NewWatchSet()
  5623  	out, err := state.VaultAccessorsByNode(ws, node.ID)
  5624  	if err != nil {
  5625  		t.Fatalf("err: %v", err)
  5626  	}
  5627  
  5628  	if len(expected) != len(out) {
  5629  		t.Fatalf("bad: %#v %#v", len(expected), len(out))
  5630  	}
  5631  
  5632  	index, err := state.Index("vault_accessors")
  5633  	if err != nil {
  5634  		t.Fatalf("err: %v", err)
  5635  	}
  5636  	if index != 1000 {
  5637  		t.Fatalf("bad: %d", index)
  5638  	}
  5639  
  5640  	if watchFired(ws) {
  5641  		t.Fatalf("bad")
  5642  	}
  5643  }
  5644  
  5645  func TestStateStore_RestoreVaultAccessor(t *testing.T) {
  5646  	state := testStateStore(t)
  5647  	a := mock.VaultAccessor()
  5648  
  5649  	restore, err := state.Restore()
  5650  	if err != nil {
  5651  		t.Fatalf("err: %v", err)
  5652  	}
  5653  
  5654  	err = restore.VaultAccessorRestore(a)
  5655  	if err != nil {
  5656  		t.Fatalf("err: %v", err)
  5657  	}
  5658  	restore.Commit()
  5659  
  5660  	ws := memdb.NewWatchSet()
  5661  	out, err := state.VaultAccessor(ws, a.Accessor)
  5662  	if err != nil {
  5663  		t.Fatalf("err: %v", err)
  5664  	}
  5665  
  5666  	if !reflect.DeepEqual(out, a) {
  5667  		t.Fatalf("Bad: %#v %#v", out, a)
  5668  	}
  5669  
  5670  	if watchFired(ws) {
  5671  		t.Fatalf("bad")
  5672  	}
  5673  }
  5674  
  5675  func TestStateStore_Abandon(t *testing.T) {
  5676  	s := testStateStore(t)
  5677  	abandonCh := s.AbandonCh()
  5678  	s.Abandon()
  5679  	select {
  5680  	case <-abandonCh:
  5681  	default:
  5682  		t.Fatalf("bad")
  5683  	}
  5684  }
  5685  
  5686  // watchFired is a helper for unit tests that returns if the given watch set
  5687  // fired (it doesn't care which watch actually fired). This uses a fixed
  5688  // timeout since we already expect the event happened before calling this and
  5689  // just need to distinguish a fire from a timeout. We do need a little time to
  5690  // allow the watch to set up any goroutines, though.
  5691  func watchFired(ws memdb.WatchSet) bool {
  5692  	timedOut := ws.Watch(time.After(50 * time.Millisecond))
  5693  	return !timedOut
  5694  }
  5695  
  5696  // NodeIDSort is used to sort nodes by ID
  5697  type NodeIDSort []*structs.Node
  5698  
  5699  func (n NodeIDSort) Len() int {
  5700  	return len(n)
  5701  }
  5702  
  5703  func (n NodeIDSort) Less(i, j int) bool {
  5704  	return n[i].ID < n[j].ID
  5705  }
  5706  
  5707  func (n NodeIDSort) Swap(i, j int) {
  5708  	n[i], n[j] = n[j], n[i]
  5709  }
  5710  
  5711  // JobIDis used to sort jobs by id
  5712  type JobIDSort []*structs.Job
  5713  
  5714  func (n JobIDSort) Len() int {
  5715  	return len(n)
  5716  }
  5717  
  5718  func (n JobIDSort) Less(i, j int) bool {
  5719  	return n[i].ID < n[j].ID
  5720  }
  5721  
  5722  func (n JobIDSort) Swap(i, j int) {
  5723  	n[i], n[j] = n[j], n[i]
  5724  }
  5725  
  5726  // EvalIDis used to sort evals by id
  5727  type EvalIDSort []*structs.Evaluation
  5728  
  5729  func (n EvalIDSort) Len() int {
  5730  	return len(n)
  5731  }
  5732  
  5733  func (n EvalIDSort) Less(i, j int) bool {
  5734  	return n[i].ID < n[j].ID
  5735  }
  5736  
  5737  func (n EvalIDSort) Swap(i, j int) {
  5738  	n[i], n[j] = n[j], n[i]
  5739  }
  5740  
  5741  // AllocIDsort used to sort allocations by id
  5742  type AllocIDSort []*structs.Allocation
  5743  
  5744  func (n AllocIDSort) Len() int {
  5745  	return len(n)
  5746  }
  5747  
  5748  func (n AllocIDSort) Less(i, j int) bool {
  5749  	return n[i].ID < n[j].ID
  5750  }
  5751  
  5752  func (n AllocIDSort) Swap(i, j int) {
  5753  	n[i], n[j] = n[j], n[i]
  5754  }