github.com/huiliang/nomad@v0.2.1-0.20151124023127-7a8b664699ff/nomad/state/state_store_test.go (about)

     1  package state
     2  
     3  import (
     4  	"os"
     5  	"reflect"
     6  	"sort"
     7  	"testing"
     8  
     9  	"github.com/hashicorp/nomad/nomad/mock"
    10  	"github.com/hashicorp/nomad/nomad/structs"
    11  	"github.com/hashicorp/nomad/nomad/watch"
    12  )
    13  
    14  func testStateStore(t *testing.T) *StateStore {
    15  	state, err := NewStateStore(os.Stderr)
    16  	if err != nil {
    17  		t.Fatalf("err: %v", err)
    18  	}
    19  	if state == nil {
    20  		t.Fatalf("missing state")
    21  	}
    22  	return state
    23  }
    24  
    25  func TestStateStore_UpsertNode_Node(t *testing.T) {
    26  	state := testStateStore(t)
    27  	node := mock.Node()
    28  
    29  	notify := setupNotifyTest(
    30  		state,
    31  		watch.Item{Table: "nodes"},
    32  		watch.Item{Node: node.ID})
    33  
    34  	err := state.UpsertNode(1000, node)
    35  	if err != nil {
    36  		t.Fatalf("err: %v", err)
    37  	}
    38  
    39  	out, err := state.NodeByID(node.ID)
    40  	if err != nil {
    41  		t.Fatalf("err: %v", err)
    42  	}
    43  
    44  	if !reflect.DeepEqual(node, out) {
    45  		t.Fatalf("bad: %#v %#v", node, out)
    46  	}
    47  
    48  	index, err := state.Index("nodes")
    49  	if err != nil {
    50  		t.Fatalf("err: %v", err)
    51  	}
    52  	if index != 1000 {
    53  		t.Fatalf("bad: %d", index)
    54  	}
    55  
    56  	notify.verify(t)
    57  }
    58  
    59  func TestStateStore_DeleteNode_Node(t *testing.T) {
    60  	state := testStateStore(t)
    61  	node := mock.Node()
    62  
    63  	notify := setupNotifyTest(
    64  		state,
    65  		watch.Item{Table: "nodes"},
    66  		watch.Item{Node: node.ID})
    67  
    68  	err := state.UpsertNode(1000, node)
    69  	if err != nil {
    70  		t.Fatalf("err: %v", err)
    71  	}
    72  
    73  	err = state.DeleteNode(1001, node.ID)
    74  	if err != nil {
    75  		t.Fatalf("err: %v", err)
    76  	}
    77  
    78  	out, err := state.NodeByID(node.ID)
    79  	if err != nil {
    80  		t.Fatalf("err: %v", err)
    81  	}
    82  
    83  	if out != nil {
    84  		t.Fatalf("bad: %#v %#v", node, out)
    85  	}
    86  
    87  	index, err := state.Index("nodes")
    88  	if err != nil {
    89  		t.Fatalf("err: %v", err)
    90  	}
    91  	if index != 1001 {
    92  		t.Fatalf("bad: %d", index)
    93  	}
    94  
    95  	notify.verify(t)
    96  }
    97  
    98  func TestStateStore_UpdateNodeStatus_Node(t *testing.T) {
    99  	state := testStateStore(t)
   100  	node := mock.Node()
   101  
   102  	notify := setupNotifyTest(
   103  		state,
   104  		watch.Item{Table: "nodes"},
   105  		watch.Item{Node: node.ID})
   106  
   107  	err := state.UpsertNode(1000, node)
   108  	if err != nil {
   109  		t.Fatalf("err: %v", err)
   110  	}
   111  
   112  	err = state.UpdateNodeStatus(1001, node.ID, structs.NodeStatusReady)
   113  	if err != nil {
   114  		t.Fatalf("err: %v", err)
   115  	}
   116  
   117  	out, err := state.NodeByID(node.ID)
   118  	if err != nil {
   119  		t.Fatalf("err: %v", err)
   120  	}
   121  
   122  	if out.Status != structs.NodeStatusReady {
   123  		t.Fatalf("bad: %#v", out)
   124  	}
   125  	if out.ModifyIndex != 1001 {
   126  		t.Fatalf("bad: %#v", out)
   127  	}
   128  
   129  	index, err := state.Index("nodes")
   130  	if err != nil {
   131  		t.Fatalf("err: %v", err)
   132  	}
   133  	if index != 1001 {
   134  		t.Fatalf("bad: %d", index)
   135  	}
   136  
   137  	notify.verify(t)
   138  }
   139  
   140  func TestStateStore_UpdateNodeDrain_Node(t *testing.T) {
   141  	state := testStateStore(t)
   142  	node := mock.Node()
   143  
   144  	notify := setupNotifyTest(
   145  		state,
   146  		watch.Item{Table: "nodes"},
   147  		watch.Item{Node: node.ID})
   148  
   149  	err := state.UpsertNode(1000, node)
   150  	if err != nil {
   151  		t.Fatalf("err: %v", err)
   152  	}
   153  
   154  	err = state.UpdateNodeDrain(1001, node.ID, true)
   155  	if err != nil {
   156  		t.Fatalf("err: %v", err)
   157  	}
   158  
   159  	out, err := state.NodeByID(node.ID)
   160  	if err != nil {
   161  		t.Fatalf("err: %v", err)
   162  	}
   163  
   164  	if !out.Drain {
   165  		t.Fatalf("bad: %#v", out)
   166  	}
   167  	if out.ModifyIndex != 1001 {
   168  		t.Fatalf("bad: %#v", out)
   169  	}
   170  
   171  	index, err := state.Index("nodes")
   172  	if err != nil {
   173  		t.Fatalf("err: %v", err)
   174  	}
   175  	if index != 1001 {
   176  		t.Fatalf("bad: %d", index)
   177  	}
   178  
   179  	notify.verify(t)
   180  }
   181  
   182  func TestStateStore_Nodes(t *testing.T) {
   183  	state := testStateStore(t)
   184  	var nodes []*structs.Node
   185  
   186  	for i := 0; i < 10; i++ {
   187  		node := mock.Node()
   188  		nodes = append(nodes, node)
   189  
   190  		err := state.UpsertNode(1000+uint64(i), node)
   191  		if err != nil {
   192  			t.Fatalf("err: %v", err)
   193  		}
   194  	}
   195  
   196  	iter, err := state.Nodes()
   197  	if err != nil {
   198  		t.Fatalf("err: %v", err)
   199  	}
   200  
   201  	var out []*structs.Node
   202  	for {
   203  		raw := iter.Next()
   204  		if raw == nil {
   205  			break
   206  		}
   207  		out = append(out, raw.(*structs.Node))
   208  	}
   209  
   210  	sort.Sort(NodeIDSort(nodes))
   211  	sort.Sort(NodeIDSort(out))
   212  
   213  	if !reflect.DeepEqual(nodes, out) {
   214  		t.Fatalf("bad: %#v %#v", nodes, out)
   215  	}
   216  }
   217  
   218  func TestStateStore_RestoreNode(t *testing.T) {
   219  	state := testStateStore(t)
   220  	node := mock.Node()
   221  
   222  	notify := setupNotifyTest(
   223  		state,
   224  		watch.Item{Table: "nodes"},
   225  		watch.Item{Node: node.ID})
   226  
   227  	restore, err := state.Restore()
   228  	if err != nil {
   229  		t.Fatalf("err: %v", err)
   230  	}
   231  
   232  	err = restore.NodeRestore(node)
   233  	if err != nil {
   234  		t.Fatalf("err: %v", err)
   235  	}
   236  	restore.Commit()
   237  
   238  	out, err := state.NodeByID(node.ID)
   239  	if err != nil {
   240  		t.Fatalf("err: %v", err)
   241  	}
   242  
   243  	if !reflect.DeepEqual(out, node) {
   244  		t.Fatalf("Bad: %#v %#v", out, node)
   245  	}
   246  
   247  	notify.verify(t)
   248  }
   249  
   250  func TestStateStore_UpsertJob_Job(t *testing.T) {
   251  	state := testStateStore(t)
   252  	job := mock.Job()
   253  
   254  	notify := setupNotifyTest(
   255  		state,
   256  		watch.Item{Table: "jobs"},
   257  		watch.Item{Job: job.ID})
   258  
   259  	err := state.UpsertJob(1000, job)
   260  	if err != nil {
   261  		t.Fatalf("err: %v", err)
   262  	}
   263  
   264  	out, err := state.JobByID(job.ID)
   265  	if err != nil {
   266  		t.Fatalf("err: %v", err)
   267  	}
   268  
   269  	if !reflect.DeepEqual(job, out) {
   270  		t.Fatalf("bad: %#v %#v", job, out)
   271  	}
   272  
   273  	index, err := state.Index("jobs")
   274  	if err != nil {
   275  		t.Fatalf("err: %v", err)
   276  	}
   277  	if index != 1000 {
   278  		t.Fatalf("bad: %d", index)
   279  	}
   280  
   281  	notify.verify(t)
   282  }
   283  
   284  func TestStateStore_UpdateUpsertJob_Job(t *testing.T) {
   285  	state := testStateStore(t)
   286  	job := mock.Job()
   287  
   288  	notify := setupNotifyTest(
   289  		state,
   290  		watch.Item{Table: "jobs"},
   291  		watch.Item{Job: job.ID})
   292  
   293  	err := state.UpsertJob(1000, job)
   294  	if err != nil {
   295  		t.Fatalf("err: %v", err)
   296  	}
   297  
   298  	job2 := mock.Job()
   299  	job2.ID = job.ID
   300  	err = state.UpsertJob(1001, job2)
   301  	if err != nil {
   302  		t.Fatalf("err: %v", err)
   303  	}
   304  
   305  	out, err := state.JobByID(job.ID)
   306  	if err != nil {
   307  		t.Fatalf("err: %v", err)
   308  	}
   309  
   310  	if !reflect.DeepEqual(job2, out) {
   311  		t.Fatalf("bad: %#v %#v", job2, out)
   312  	}
   313  
   314  	if out.CreateIndex != 1000 {
   315  		t.Fatalf("bad: %#v", out)
   316  	}
   317  	if out.ModifyIndex != 1001 {
   318  		t.Fatalf("bad: %#v", out)
   319  	}
   320  
   321  	index, err := state.Index("jobs")
   322  	if err != nil {
   323  		t.Fatalf("err: %v", err)
   324  	}
   325  	if index != 1001 {
   326  		t.Fatalf("bad: %d", index)
   327  	}
   328  
   329  	notify.verify(t)
   330  }
   331  
   332  func TestStateStore_DeleteJob_Job(t *testing.T) {
   333  	state := testStateStore(t)
   334  	job := mock.Job()
   335  
   336  	notify := setupNotifyTest(
   337  		state,
   338  		watch.Item{Table: "jobs"},
   339  		watch.Item{Job: job.ID})
   340  
   341  	err := state.UpsertJob(1000, job)
   342  	if err != nil {
   343  		t.Fatalf("err: %v", err)
   344  	}
   345  
   346  	err = state.DeleteJob(1001, job.ID)
   347  	if err != nil {
   348  		t.Fatalf("err: %v", err)
   349  	}
   350  
   351  	out, err := state.JobByID(job.ID)
   352  	if err != nil {
   353  		t.Fatalf("err: %v", err)
   354  	}
   355  
   356  	if out != nil {
   357  		t.Fatalf("bad: %#v %#v", job, out)
   358  	}
   359  
   360  	index, err := state.Index("jobs")
   361  	if err != nil {
   362  		t.Fatalf("err: %v", err)
   363  	}
   364  	if index != 1001 {
   365  		t.Fatalf("bad: %d", index)
   366  	}
   367  
   368  	notify.verify(t)
   369  }
   370  
   371  func TestStateStore_Jobs(t *testing.T) {
   372  	state := testStateStore(t)
   373  	var jobs []*structs.Job
   374  
   375  	for i := 0; i < 10; i++ {
   376  		job := mock.Job()
   377  		jobs = append(jobs, job)
   378  
   379  		err := state.UpsertJob(1000+uint64(i), job)
   380  		if err != nil {
   381  			t.Fatalf("err: %v", err)
   382  		}
   383  	}
   384  
   385  	iter, err := state.Jobs()
   386  	if err != nil {
   387  		t.Fatalf("err: %v", err)
   388  	}
   389  
   390  	var out []*structs.Job
   391  	for {
   392  		raw := iter.Next()
   393  		if raw == nil {
   394  			break
   395  		}
   396  		out = append(out, raw.(*structs.Job))
   397  	}
   398  
   399  	sort.Sort(JobIDSort(jobs))
   400  	sort.Sort(JobIDSort(out))
   401  
   402  	if !reflect.DeepEqual(jobs, out) {
   403  		t.Fatalf("bad: %#v %#v", jobs, out)
   404  	}
   405  }
   406  
   407  func TestStateStore_JobsByScheduler(t *testing.T) {
   408  	state := testStateStore(t)
   409  	var serviceJobs []*structs.Job
   410  	var sysJobs []*structs.Job
   411  
   412  	for i := 0; i < 10; i++ {
   413  		job := mock.Job()
   414  		serviceJobs = append(serviceJobs, job)
   415  
   416  		err := state.UpsertJob(1000+uint64(i), job)
   417  		if err != nil {
   418  			t.Fatalf("err: %v", err)
   419  		}
   420  	}
   421  
   422  	for i := 0; i < 10; i++ {
   423  		job := mock.SystemJob()
   424  		sysJobs = append(sysJobs, job)
   425  
   426  		err := state.UpsertJob(2000+uint64(i), job)
   427  		if err != nil {
   428  			t.Fatalf("err: %v", err)
   429  		}
   430  	}
   431  
   432  	iter, err := state.JobsByScheduler("service")
   433  	if err != nil {
   434  		t.Fatalf("err: %v", err)
   435  	}
   436  
   437  	var outService []*structs.Job
   438  	for {
   439  		raw := iter.Next()
   440  		if raw == nil {
   441  			break
   442  		}
   443  		outService = append(outService, raw.(*structs.Job))
   444  	}
   445  
   446  	iter, err = state.JobsByScheduler("system")
   447  	if err != nil {
   448  		t.Fatalf("err: %v", err)
   449  	}
   450  
   451  	var outSystem []*structs.Job
   452  	for {
   453  		raw := iter.Next()
   454  		if raw == nil {
   455  			break
   456  		}
   457  		outSystem = append(outSystem, raw.(*structs.Job))
   458  	}
   459  
   460  	sort.Sort(JobIDSort(serviceJobs))
   461  	sort.Sort(JobIDSort(sysJobs))
   462  	sort.Sort(JobIDSort(outService))
   463  	sort.Sort(JobIDSort(outSystem))
   464  
   465  	if !reflect.DeepEqual(serviceJobs, outService) {
   466  		t.Fatalf("bad: %#v %#v", serviceJobs, outService)
   467  	}
   468  
   469  	if !reflect.DeepEqual(sysJobs, outSystem) {
   470  		t.Fatalf("bad: %#v %#v", sysJobs, outSystem)
   471  	}
   472  }
   473  
   474  func TestStateStore_RestoreJob(t *testing.T) {
   475  	state := testStateStore(t)
   476  	job := mock.Job()
   477  
   478  	notify := setupNotifyTest(
   479  		state,
   480  		watch.Item{Table: "jobs"},
   481  		watch.Item{Job: job.ID})
   482  
   483  	restore, err := state.Restore()
   484  	if err != nil {
   485  		t.Fatalf("err: %v", err)
   486  	}
   487  
   488  	err = restore.JobRestore(job)
   489  	if err != nil {
   490  		t.Fatalf("err: %v", err)
   491  	}
   492  	restore.Commit()
   493  
   494  	out, err := state.JobByID(job.ID)
   495  	if err != nil {
   496  		t.Fatalf("err: %v", err)
   497  	}
   498  
   499  	if !reflect.DeepEqual(out, job) {
   500  		t.Fatalf("Bad: %#v %#v", out, job)
   501  	}
   502  
   503  	notify.verify(t)
   504  }
   505  
   506  func TestStateStore_Indexes(t *testing.T) {
   507  	state := testStateStore(t)
   508  	node := mock.Node()
   509  
   510  	err := state.UpsertNode(1000, node)
   511  	if err != nil {
   512  		t.Fatalf("err: %v", err)
   513  	}
   514  
   515  	iter, err := state.Indexes()
   516  	if err != nil {
   517  		t.Fatalf("err: %v", err)
   518  	}
   519  
   520  	var out []*IndexEntry
   521  	for {
   522  		raw := iter.Next()
   523  		if raw == nil {
   524  			break
   525  		}
   526  		out = append(out, raw.(*IndexEntry))
   527  	}
   528  
   529  	expect := []*IndexEntry{
   530  		&IndexEntry{"nodes", 1000},
   531  	}
   532  
   533  	if !reflect.DeepEqual(expect, out) {
   534  		t.Fatalf("bad: %#v %#v", expect, out)
   535  	}
   536  }
   537  
   538  func TestStateStore_RestoreIndex(t *testing.T) {
   539  	state := testStateStore(t)
   540  
   541  	restore, err := state.Restore()
   542  	if err != nil {
   543  		t.Fatalf("err: %v", err)
   544  	}
   545  
   546  	index := &IndexEntry{"jobs", 1000}
   547  	err = restore.IndexRestore(index)
   548  	if err != nil {
   549  		t.Fatalf("err: %v", err)
   550  	}
   551  
   552  	restore.Commit()
   553  
   554  	out, err := state.Index("jobs")
   555  	if err != nil {
   556  		t.Fatalf("err: %v", err)
   557  	}
   558  
   559  	if out != 1000 {
   560  		t.Fatalf("Bad: %#v %#v", out, 1000)
   561  	}
   562  }
   563  
   564  func TestStateStore_UpsertEvals_Eval(t *testing.T) {
   565  	state := testStateStore(t)
   566  	eval := mock.Eval()
   567  
   568  	notify := setupNotifyTest(
   569  		state,
   570  		watch.Item{Table: "evals"},
   571  		watch.Item{Eval: eval.ID})
   572  
   573  	err := state.UpsertEvals(1000, []*structs.Evaluation{eval})
   574  	if err != nil {
   575  		t.Fatalf("err: %v", err)
   576  	}
   577  
   578  	out, err := state.EvalByID(eval.ID)
   579  	if err != nil {
   580  		t.Fatalf("err: %v", err)
   581  	}
   582  
   583  	if !reflect.DeepEqual(eval, out) {
   584  		t.Fatalf("bad: %#v %#v", eval, out)
   585  	}
   586  
   587  	index, err := state.Index("evals")
   588  	if err != nil {
   589  		t.Fatalf("err: %v", err)
   590  	}
   591  	if index != 1000 {
   592  		t.Fatalf("bad: %d", index)
   593  	}
   594  
   595  	notify.verify(t)
   596  }
   597  
   598  func TestStateStore_Update_UpsertEvals_Eval(t *testing.T) {
   599  	state := testStateStore(t)
   600  	eval := mock.Eval()
   601  
   602  	err := state.UpsertEvals(1000, []*structs.Evaluation{eval})
   603  	if err != nil {
   604  		t.Fatalf("err: %v", err)
   605  	}
   606  
   607  	notify := setupNotifyTest(
   608  		state,
   609  		watch.Item{Table: "evals"},
   610  		watch.Item{Eval: eval.ID})
   611  
   612  	eval2 := mock.Eval()
   613  	eval2.ID = eval.ID
   614  	err = state.UpsertEvals(1001, []*structs.Evaluation{eval2})
   615  	if err != nil {
   616  		t.Fatalf("err: %v", err)
   617  	}
   618  
   619  	out, err := state.EvalByID(eval.ID)
   620  	if err != nil {
   621  		t.Fatalf("err: %v", err)
   622  	}
   623  
   624  	if !reflect.DeepEqual(eval2, out) {
   625  		t.Fatalf("bad: %#v %#v", eval2, out)
   626  	}
   627  
   628  	if out.CreateIndex != 1000 {
   629  		t.Fatalf("bad: %#v", out)
   630  	}
   631  	if out.ModifyIndex != 1001 {
   632  		t.Fatalf("bad: %#v", out)
   633  	}
   634  
   635  	index, err := state.Index("evals")
   636  	if err != nil {
   637  		t.Fatalf("err: %v", err)
   638  	}
   639  	if index != 1001 {
   640  		t.Fatalf("bad: %d", index)
   641  	}
   642  
   643  	notify.verify(t)
   644  }
   645  
   646  func TestStateStore_DeleteEval_Eval(t *testing.T) {
   647  	state := testStateStore(t)
   648  	eval1 := mock.Eval()
   649  	eval2 := mock.Eval()
   650  	alloc1 := mock.Alloc()
   651  	alloc2 := mock.Alloc()
   652  
   653  	notify := setupNotifyTest(
   654  		state,
   655  		watch.Item{Table: "evals"},
   656  		watch.Item{Table: "allocs"},
   657  		watch.Item{Eval: eval1.ID},
   658  		watch.Item{Eval: eval2.ID},
   659  		watch.Item{Alloc: alloc1.ID},
   660  		watch.Item{Alloc: alloc2.ID},
   661  		watch.Item{AllocEval: alloc1.EvalID},
   662  		watch.Item{AllocEval: alloc2.EvalID},
   663  		watch.Item{AllocJob: alloc1.JobID},
   664  		watch.Item{AllocJob: alloc2.JobID},
   665  		watch.Item{AllocNode: alloc1.NodeID},
   666  		watch.Item{AllocNode: alloc2.NodeID})
   667  
   668  	err := state.UpsertEvals(1000, []*structs.Evaluation{eval1, eval2})
   669  	if err != nil {
   670  		t.Fatalf("err: %v", err)
   671  	}
   672  
   673  	err = state.UpsertAllocs(1001, []*structs.Allocation{alloc1, alloc2})
   674  	if err != nil {
   675  		t.Fatalf("err: %v", err)
   676  	}
   677  
   678  	err = state.DeleteEval(1002, []string{eval1.ID, eval2.ID}, []string{alloc1.ID, alloc2.ID})
   679  	if err != nil {
   680  		t.Fatalf("err: %v", err)
   681  	}
   682  
   683  	out, err := state.EvalByID(eval1.ID)
   684  	if err != nil {
   685  		t.Fatalf("err: %v", err)
   686  	}
   687  
   688  	if out != nil {
   689  		t.Fatalf("bad: %#v %#v", eval1, out)
   690  	}
   691  
   692  	out, err = state.EvalByID(eval2.ID)
   693  	if err != nil {
   694  		t.Fatalf("err: %v", err)
   695  	}
   696  
   697  	if out != nil {
   698  		t.Fatalf("bad: %#v %#v", eval1, out)
   699  	}
   700  
   701  	outA, err := state.AllocByID(alloc1.ID)
   702  	if err != nil {
   703  		t.Fatalf("err: %v", err)
   704  	}
   705  
   706  	if out != nil {
   707  		t.Fatalf("bad: %#v %#v", alloc1, outA)
   708  	}
   709  
   710  	outA, err = state.AllocByID(alloc2.ID)
   711  	if err != nil {
   712  		t.Fatalf("err: %v", err)
   713  	}
   714  
   715  	if out != nil {
   716  		t.Fatalf("bad: %#v %#v", alloc1, outA)
   717  	}
   718  
   719  	index, err := state.Index("evals")
   720  	if err != nil {
   721  		t.Fatalf("err: %v", err)
   722  	}
   723  	if index != 1002 {
   724  		t.Fatalf("bad: %d", index)
   725  	}
   726  
   727  	index, err = state.Index("allocs")
   728  	if err != nil {
   729  		t.Fatalf("err: %v", err)
   730  	}
   731  	if index != 1002 {
   732  		t.Fatalf("bad: %d", index)
   733  	}
   734  
   735  	notify.verify(t)
   736  }
   737  
   738  func TestStateStore_EvalsByJob(t *testing.T) {
   739  	state := testStateStore(t)
   740  
   741  	eval1 := mock.Eval()
   742  	eval2 := mock.Eval()
   743  	eval2.JobID = eval1.JobID
   744  	eval3 := mock.Eval()
   745  	evals := []*structs.Evaluation{eval1, eval2}
   746  
   747  	err := state.UpsertEvals(1000, evals)
   748  	if err != nil {
   749  		t.Fatalf("err: %v", err)
   750  	}
   751  	err = state.UpsertEvals(1001, []*structs.Evaluation{eval3})
   752  	if err != nil {
   753  		t.Fatalf("err: %v", err)
   754  	}
   755  
   756  	out, err := state.EvalsByJob(eval1.JobID)
   757  	if err != nil {
   758  		t.Fatalf("err: %v", err)
   759  	}
   760  
   761  	sort.Sort(EvalIDSort(evals))
   762  	sort.Sort(EvalIDSort(out))
   763  
   764  	if !reflect.DeepEqual(evals, out) {
   765  		t.Fatalf("bad: %#v %#v", evals, out)
   766  	}
   767  }
   768  
   769  func TestStateStore_Evals(t *testing.T) {
   770  	state := testStateStore(t)
   771  	var evals []*structs.Evaluation
   772  
   773  	for i := 0; i < 10; i++ {
   774  		eval := mock.Eval()
   775  		evals = append(evals, eval)
   776  
   777  		err := state.UpsertEvals(1000+uint64(i), []*structs.Evaluation{eval})
   778  		if err != nil {
   779  			t.Fatalf("err: %v", err)
   780  		}
   781  	}
   782  
   783  	iter, err := state.Evals()
   784  	if err != nil {
   785  		t.Fatalf("err: %v", err)
   786  	}
   787  
   788  	var out []*structs.Evaluation
   789  	for {
   790  		raw := iter.Next()
   791  		if raw == nil {
   792  			break
   793  		}
   794  		out = append(out, raw.(*structs.Evaluation))
   795  	}
   796  
   797  	sort.Sort(EvalIDSort(evals))
   798  	sort.Sort(EvalIDSort(out))
   799  
   800  	if !reflect.DeepEqual(evals, out) {
   801  		t.Fatalf("bad: %#v %#v", evals, out)
   802  	}
   803  }
   804  
   805  func TestStateStore_RestoreEval(t *testing.T) {
   806  	state := testStateStore(t)
   807  	eval := mock.Eval()
   808  
   809  	notify := setupNotifyTest(
   810  		state,
   811  		watch.Item{Table: "evals"},
   812  		watch.Item{Eval: eval.ID})
   813  
   814  	restore, err := state.Restore()
   815  	if err != nil {
   816  		t.Fatalf("err: %v", err)
   817  	}
   818  
   819  	err = restore.EvalRestore(eval)
   820  	if err != nil {
   821  		t.Fatalf("err: %v", err)
   822  	}
   823  	restore.Commit()
   824  
   825  	out, err := state.EvalByID(eval.ID)
   826  	if err != nil {
   827  		t.Fatalf("err: %v", err)
   828  	}
   829  
   830  	if !reflect.DeepEqual(out, eval) {
   831  		t.Fatalf("Bad: %#v %#v", out, eval)
   832  	}
   833  
   834  	notify.verify(t)
   835  }
   836  
   837  func TestStateStore_UpdateAllocFromClient(t *testing.T) {
   838  	state := testStateStore(t)
   839  	alloc := mock.Alloc()
   840  
   841  	notify := setupNotifyTest(
   842  		state,
   843  		watch.Item{Table: "allocs"},
   844  		watch.Item{Alloc: alloc.ID},
   845  		watch.Item{AllocEval: alloc.EvalID},
   846  		watch.Item{AllocJob: alloc.JobID},
   847  		watch.Item{AllocNode: alloc.NodeID})
   848  
   849  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
   850  	if err != nil {
   851  		t.Fatalf("err: %v", err)
   852  	}
   853  
   854  	update := new(structs.Allocation)
   855  	*update = *alloc
   856  	update.ClientStatus = structs.AllocClientStatusFailed
   857  
   858  	err = state.UpdateAllocFromClient(1001, update)
   859  	if err != nil {
   860  		t.Fatalf("err: %v", err)
   861  	}
   862  
   863  	out, err := state.AllocByID(alloc.ID)
   864  	if err != nil {
   865  		t.Fatalf("err: %v", err)
   866  	}
   867  
   868  	update.ModifyIndex = 1001
   869  	if !reflect.DeepEqual(update, out) {
   870  		t.Fatalf("bad: %#v %#v", update, out)
   871  	}
   872  
   873  	index, err := state.Index("allocs")
   874  	if err != nil {
   875  		t.Fatalf("err: %v", err)
   876  	}
   877  	if index != 1001 {
   878  		t.Fatalf("bad: %d", index)
   879  	}
   880  
   881  	notify.verify(t)
   882  }
   883  
   884  func TestStateStore_UpsertAlloc_Alloc(t *testing.T) {
   885  	state := testStateStore(t)
   886  	alloc := mock.Alloc()
   887  
   888  	notify := setupNotifyTest(
   889  		state,
   890  		watch.Item{Table: "allocs"},
   891  		watch.Item{Alloc: alloc.ID},
   892  		watch.Item{AllocEval: alloc.EvalID},
   893  		watch.Item{AllocJob: alloc.JobID},
   894  		watch.Item{AllocNode: alloc.NodeID})
   895  
   896  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
   897  	if err != nil {
   898  		t.Fatalf("err: %v", err)
   899  	}
   900  
   901  	out, err := state.AllocByID(alloc.ID)
   902  	if err != nil {
   903  		t.Fatalf("err: %v", err)
   904  	}
   905  
   906  	if !reflect.DeepEqual(alloc, out) {
   907  		t.Fatalf("bad: %#v %#v", alloc, out)
   908  	}
   909  
   910  	index, err := state.Index("allocs")
   911  	if err != nil {
   912  		t.Fatalf("err: %v", err)
   913  	}
   914  	if index != 1000 {
   915  		t.Fatalf("bad: %d", index)
   916  	}
   917  
   918  	notify.verify(t)
   919  }
   920  
   921  func TestStateStore_UpdateAlloc_Alloc(t *testing.T) {
   922  	state := testStateStore(t)
   923  	alloc := mock.Alloc()
   924  
   925  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
   926  	if err != nil {
   927  		t.Fatalf("err: %v", err)
   928  	}
   929  
   930  	alloc2 := mock.Alloc()
   931  	alloc2.ID = alloc.ID
   932  	alloc2.NodeID = alloc.NodeID + ".new"
   933  
   934  	notify := setupNotifyTest(
   935  		state,
   936  		watch.Item{Table: "allocs"},
   937  		watch.Item{Alloc: alloc2.ID},
   938  		watch.Item{AllocEval: alloc2.EvalID},
   939  		watch.Item{AllocJob: alloc2.JobID},
   940  		watch.Item{AllocNode: alloc2.NodeID})
   941  
   942  	err = state.UpsertAllocs(1001, []*structs.Allocation{alloc2})
   943  	if err != nil {
   944  		t.Fatalf("err: %v", err)
   945  	}
   946  
   947  	out, err := state.AllocByID(alloc.ID)
   948  	if err != nil {
   949  		t.Fatalf("err: %v", err)
   950  	}
   951  
   952  	if !reflect.DeepEqual(alloc2, out) {
   953  		t.Fatalf("bad: %#v %#v", alloc2, out)
   954  	}
   955  
   956  	if out.CreateIndex != 1000 {
   957  		t.Fatalf("bad: %#v", out)
   958  	}
   959  	if out.ModifyIndex != 1001 {
   960  		t.Fatalf("bad: %#v", out)
   961  	}
   962  
   963  	index, err := state.Index("allocs")
   964  	if err != nil {
   965  		t.Fatalf("err: %v", err)
   966  	}
   967  	if index != 1001 {
   968  		t.Fatalf("bad: %d", index)
   969  	}
   970  
   971  	notify.verify(t)
   972  }
   973  
   974  func TestStateStore_EvictAlloc_Alloc(t *testing.T) {
   975  	state := testStateStore(t)
   976  	alloc := mock.Alloc()
   977  
   978  	err := state.UpsertAllocs(1000, []*structs.Allocation{alloc})
   979  	if err != nil {
   980  		t.Fatalf("err: %v", err)
   981  	}
   982  
   983  	alloc2 := new(structs.Allocation)
   984  	*alloc2 = *alloc
   985  	alloc2.DesiredStatus = structs.AllocDesiredStatusEvict
   986  	err = state.UpsertAllocs(1001, []*structs.Allocation{alloc2})
   987  	if err != nil {
   988  		t.Fatalf("err: %v", err)
   989  	}
   990  
   991  	out, err := state.AllocByID(alloc.ID)
   992  	if err != nil {
   993  		t.Fatalf("err: %v", err)
   994  	}
   995  
   996  	if out.DesiredStatus != structs.AllocDesiredStatusEvict {
   997  		t.Fatalf("bad: %#v %#v", alloc, out)
   998  	}
   999  
  1000  	index, err := state.Index("allocs")
  1001  	if err != nil {
  1002  		t.Fatalf("err: %v", err)
  1003  	}
  1004  	if index != 1001 {
  1005  		t.Fatalf("bad: %d", index)
  1006  	}
  1007  }
  1008  
  1009  func TestStateStore_AllocsByNode(t *testing.T) {
  1010  	state := testStateStore(t)
  1011  	var allocs []*structs.Allocation
  1012  
  1013  	for i := 0; i < 10; i++ {
  1014  		alloc := mock.Alloc()
  1015  		alloc.NodeID = "foo"
  1016  		allocs = append(allocs, alloc)
  1017  	}
  1018  
  1019  	err := state.UpsertAllocs(1000, allocs)
  1020  	if err != nil {
  1021  		t.Fatalf("err: %v", err)
  1022  	}
  1023  
  1024  	out, err := state.AllocsByNode("foo")
  1025  	if err != nil {
  1026  		t.Fatalf("err: %v", err)
  1027  	}
  1028  
  1029  	sort.Sort(AllocIDSort(allocs))
  1030  	sort.Sort(AllocIDSort(out))
  1031  
  1032  	if !reflect.DeepEqual(allocs, out) {
  1033  		t.Fatalf("bad: %#v %#v", allocs, out)
  1034  	}
  1035  }
  1036  
  1037  func TestStateStore_AllocsByJob(t *testing.T) {
  1038  	state := testStateStore(t)
  1039  	var allocs []*structs.Allocation
  1040  
  1041  	for i := 0; i < 10; i++ {
  1042  		alloc := mock.Alloc()
  1043  		alloc.JobID = "foo"
  1044  		allocs = append(allocs, alloc)
  1045  	}
  1046  
  1047  	err := state.UpsertAllocs(1000, allocs)
  1048  	if err != nil {
  1049  		t.Fatalf("err: %v", err)
  1050  	}
  1051  
  1052  	out, err := state.AllocsByJob("foo")
  1053  	if err != nil {
  1054  		t.Fatalf("err: %v", err)
  1055  	}
  1056  
  1057  	sort.Sort(AllocIDSort(allocs))
  1058  	sort.Sort(AllocIDSort(out))
  1059  
  1060  	if !reflect.DeepEqual(allocs, out) {
  1061  		t.Fatalf("bad: %#v %#v", allocs, out)
  1062  	}
  1063  }
  1064  
  1065  func TestStateStore_Allocs(t *testing.T) {
  1066  	state := testStateStore(t)
  1067  	var allocs []*structs.Allocation
  1068  
  1069  	for i := 0; i < 10; i++ {
  1070  		alloc := mock.Alloc()
  1071  		allocs = append(allocs, alloc)
  1072  	}
  1073  
  1074  	err := state.UpsertAllocs(1000, allocs)
  1075  	if err != nil {
  1076  		t.Fatalf("err: %v", err)
  1077  	}
  1078  
  1079  	iter, err := state.Allocs()
  1080  	if err != nil {
  1081  		t.Fatalf("err: %v", err)
  1082  	}
  1083  
  1084  	var out []*structs.Allocation
  1085  	for {
  1086  		raw := iter.Next()
  1087  		if raw == nil {
  1088  			break
  1089  		}
  1090  		out = append(out, raw.(*structs.Allocation))
  1091  	}
  1092  
  1093  	sort.Sort(AllocIDSort(allocs))
  1094  	sort.Sort(AllocIDSort(out))
  1095  
  1096  	if !reflect.DeepEqual(allocs, out) {
  1097  		t.Fatalf("bad: %#v %#v", allocs, out)
  1098  	}
  1099  }
  1100  
  1101  func TestStateStore_RestoreAlloc(t *testing.T) {
  1102  	state := testStateStore(t)
  1103  	alloc := mock.Alloc()
  1104  
  1105  	notify := setupNotifyTest(
  1106  		state,
  1107  		watch.Item{Table: "allocs"},
  1108  		watch.Item{Alloc: alloc.ID},
  1109  		watch.Item{AllocEval: alloc.EvalID},
  1110  		watch.Item{AllocJob: alloc.JobID},
  1111  		watch.Item{AllocNode: alloc.NodeID})
  1112  
  1113  	restore, err := state.Restore()
  1114  	if err != nil {
  1115  		t.Fatalf("err: %v", err)
  1116  	}
  1117  
  1118  	err = restore.AllocRestore(alloc)
  1119  	if err != nil {
  1120  		t.Fatalf("err: %v", err)
  1121  	}
  1122  
  1123  	restore.Commit()
  1124  
  1125  	out, err := state.AllocByID(alloc.ID)
  1126  	if err != nil {
  1127  		t.Fatalf("err: %v", err)
  1128  	}
  1129  
  1130  	if !reflect.DeepEqual(out, alloc) {
  1131  		t.Fatalf("Bad: %#v %#v", out, alloc)
  1132  	}
  1133  
  1134  	notify.verify(t)
  1135  }
  1136  
  1137  func TestStateWatch_watch(t *testing.T) {
  1138  	sw := newStateWatch()
  1139  	notify1 := make(chan struct{}, 1)
  1140  	notify2 := make(chan struct{}, 1)
  1141  	notify3 := make(chan struct{}, 1)
  1142  
  1143  	// Notifications trigger subscribed channels
  1144  	sw.watch(watch.NewItems(watch.Item{Table: "foo"}), notify1)
  1145  	sw.watch(watch.NewItems(watch.Item{Table: "bar"}), notify2)
  1146  	sw.watch(watch.NewItems(watch.Item{Table: "baz"}), notify3)
  1147  
  1148  	items := watch.NewItems()
  1149  	items.Add(watch.Item{Table: "foo"})
  1150  	items.Add(watch.Item{Table: "bar"})
  1151  
  1152  	sw.notify(items)
  1153  	if len(notify1) != 1 {
  1154  		t.Fatalf("should notify")
  1155  	}
  1156  	if len(notify2) != 1 {
  1157  		t.Fatalf("should notify")
  1158  	}
  1159  	if len(notify3) != 0 {
  1160  		t.Fatalf("should not notify")
  1161  	}
  1162  }
  1163  
  1164  func TestStateWatch_stopWatch(t *testing.T) {
  1165  	sw := newStateWatch()
  1166  	notify := make(chan struct{})
  1167  
  1168  	// First subscribe
  1169  	sw.watch(watch.NewItems(watch.Item{Table: "foo"}), notify)
  1170  
  1171  	// Unsubscribe stop notifications
  1172  	sw.stopWatch(watch.NewItems(watch.Item{Table: "foo"}), notify)
  1173  
  1174  	// Check that the group was removed
  1175  	if _, ok := sw.items[watch.Item{Table: "foo"}]; ok {
  1176  		t.Fatalf("should remove group")
  1177  	}
  1178  
  1179  	// Check that we are not notified
  1180  	sw.notify(watch.NewItems(watch.Item{Table: "foo"}))
  1181  	if len(notify) != 0 {
  1182  		t.Fatalf("should not notify")
  1183  	}
  1184  }
  1185  
  1186  // setupNotifyTest takes a state store and a set of watch items, then creates
  1187  // and subscribes a notification channel for each item.
  1188  func setupNotifyTest(state *StateStore, items ...watch.Item) notifyTest {
  1189  	var n notifyTest
  1190  	for _, item := range items {
  1191  		ch := make(chan struct{}, 1)
  1192  		state.Watch(watch.NewItems(item), ch)
  1193  		n = append(n, &notifyTestCase{item, ch})
  1194  	}
  1195  	return n
  1196  }
  1197  
  1198  // notifyTestCase is used to set up and verify watch triggers.
  1199  type notifyTestCase struct {
  1200  	item watch.Item
  1201  	ch   chan struct{}
  1202  }
  1203  
  1204  // notifyTest is a suite of notifyTestCases.
  1205  type notifyTest []*notifyTestCase
  1206  
  1207  // verify ensures that each channel received a notification.
  1208  func (n notifyTest) verify(t *testing.T) {
  1209  	for _, tcase := range n {
  1210  		if len(tcase.ch) != 1 {
  1211  			t.Fatalf("should notify %#v", tcase.item)
  1212  		}
  1213  	}
  1214  }
  1215  
  1216  // NodeIDSort is used to sort nodes by ID
  1217  type NodeIDSort []*structs.Node
  1218  
  1219  func (n NodeIDSort) Len() int {
  1220  	return len(n)
  1221  }
  1222  
  1223  func (n NodeIDSort) Less(i, j int) bool {
  1224  	return n[i].ID < n[j].ID
  1225  }
  1226  
  1227  func (n NodeIDSort) Swap(i, j int) {
  1228  	n[i], n[j] = n[j], n[i]
  1229  }
  1230  
  1231  // JobIDis used to sort jobs by id
  1232  type JobIDSort []*structs.Job
  1233  
  1234  func (n JobIDSort) Len() int {
  1235  	return len(n)
  1236  }
  1237  
  1238  func (n JobIDSort) Less(i, j int) bool {
  1239  	return n[i].ID < n[j].ID
  1240  }
  1241  
  1242  func (n JobIDSort) Swap(i, j int) {
  1243  	n[i], n[j] = n[j], n[i]
  1244  }
  1245  
  1246  // EvalIDis used to sort evals by id
  1247  type EvalIDSort []*structs.Evaluation
  1248  
  1249  func (n EvalIDSort) Len() int {
  1250  	return len(n)
  1251  }
  1252  
  1253  func (n EvalIDSort) Less(i, j int) bool {
  1254  	return n[i].ID < n[j].ID
  1255  }
  1256  
  1257  func (n EvalIDSort) Swap(i, j int) {
  1258  	n[i], n[j] = n[j], n[i]
  1259  }
  1260  
  1261  // AllocIDsort used to sort allocations by id
  1262  type AllocIDSort []*structs.Allocation
  1263  
  1264  func (n AllocIDSort) Len() int {
  1265  	return len(n)
  1266  }
  1267  
  1268  func (n AllocIDSort) Less(i, j int) bool {
  1269  	return n[i].ID < n[j].ID
  1270  }
  1271  
  1272  func (n AllocIDSort) Swap(i, j int) {
  1273  	n[i], n[j] = n[j], n[i]
  1274  }