github.com/ryanslade/nomad@v0.2.4-0.20160128061903-fc95782f2089/api/jobs_test.go (about)

     1  package api
     2  
     3  import (
     4  	"reflect"
     5  	"sort"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/hashicorp/nomad/testutil"
    10  )
    11  
    12  func TestJobs_Register(t *testing.T) {
    13  	c, s := makeClient(t, nil, nil)
    14  	defer s.Stop()
    15  	jobs := c.Jobs()
    16  
    17  	// Listing jobs before registering returns nothing
    18  	resp, qm, err := jobs.List(nil)
    19  	if err != nil {
    20  		t.Fatalf("err: %s", err)
    21  	}
    22  	if qm.LastIndex != 0 {
    23  		t.Fatalf("bad index: %d", qm.LastIndex)
    24  	}
    25  	if n := len(resp); n != 0 {
    26  		t.Fatalf("expected 0 jobs, got: %d", n)
    27  	}
    28  
    29  	// Create a job and attempt to register it
    30  	job := testJob()
    31  	eval, wm, err := jobs.Register(job, nil)
    32  	if err != nil {
    33  		t.Fatalf("err: %s", err)
    34  	}
    35  	if eval == "" {
    36  		t.Fatalf("missing eval id")
    37  	}
    38  	assertWriteMeta(t, wm)
    39  
    40  	// Query the jobs back out again
    41  	resp, qm, err = jobs.List(nil)
    42  	if err != nil {
    43  		t.Fatalf("err: %s", err)
    44  	}
    45  	assertQueryMeta(t, qm)
    46  
    47  	// Check that we got the expected response
    48  	if len(resp) != 1 || resp[0].ID != job.ID {
    49  		t.Fatalf("bad: %#v", resp[0])
    50  	}
    51  }
    52  
    53  func TestJobs_Info(t *testing.T) {
    54  	c, s := makeClient(t, nil, nil)
    55  	defer s.Stop()
    56  	jobs := c.Jobs()
    57  
    58  	// Trying to retrieve a job by ID before it exists
    59  	// returns an error
    60  	_, _, err := jobs.Info("job1", nil)
    61  	if err == nil || !strings.Contains(err.Error(), "not found") {
    62  		t.Fatalf("expected not found error, got: %#v", err)
    63  	}
    64  
    65  	// Register the job
    66  	job := testJob()
    67  	_, wm, err := jobs.Register(job, nil)
    68  	if err != nil {
    69  		t.Fatalf("err: %s", err)
    70  	}
    71  	assertWriteMeta(t, wm)
    72  
    73  	// Query the job again and ensure it exists
    74  	result, qm, err := jobs.Info("job1", nil)
    75  	if err != nil {
    76  		t.Fatalf("err: %s", err)
    77  	}
    78  	assertQueryMeta(t, qm)
    79  
    80  	// Check that the result is what we expect
    81  	if result == nil || result.ID != job.ID {
    82  		t.Fatalf("expect: %#v, got: %#v", job, result)
    83  	}
    84  }
    85  
    86  func TestJobs_PrefixList(t *testing.T) {
    87  	c, s := makeClient(t, nil, nil)
    88  	defer s.Stop()
    89  	jobs := c.Jobs()
    90  
    91  	// Listing when nothing exists returns empty
    92  	results, qm, err := jobs.PrefixList("dummy")
    93  	if err != nil {
    94  		t.Fatalf("err: %s", err)
    95  	}
    96  	if qm.LastIndex != 0 {
    97  		t.Fatalf("bad index: %d", qm.LastIndex)
    98  	}
    99  	if n := len(results); n != 0 {
   100  		t.Fatalf("expected 0 jobs, got: %d", n)
   101  	}
   102  
   103  	// Register the job
   104  	job := testJob()
   105  	_, wm, err := jobs.Register(job, nil)
   106  	if err != nil {
   107  		t.Fatalf("err: %s", err)
   108  	}
   109  	assertWriteMeta(t, wm)
   110  
   111  	// Query the job again and ensure it exists
   112  	// Listing when nothing exists returns empty
   113  	results, qm, err = jobs.PrefixList(job.ID[:1])
   114  	if err != nil {
   115  		t.Fatalf("err: %s", err)
   116  	}
   117  
   118  	// Check if we have the right list
   119  	if len(results) != 1 || results[0].ID != job.ID {
   120  		t.Fatalf("bad: %#v", results)
   121  	}
   122  }
   123  
   124  func TestJobs_List(t *testing.T) {
   125  	c, s := makeClient(t, nil, nil)
   126  	defer s.Stop()
   127  	jobs := c.Jobs()
   128  
   129  	// Listing when nothing exists returns empty
   130  	results, qm, err := jobs.List(nil)
   131  	if err != nil {
   132  		t.Fatalf("err: %s", err)
   133  	}
   134  	if qm.LastIndex != 0 {
   135  		t.Fatalf("bad index: %d", qm.LastIndex)
   136  	}
   137  	if n := len(results); n != 0 {
   138  		t.Fatalf("expected 0 jobs, got: %d", n)
   139  	}
   140  
   141  	// Register the job
   142  	job := testJob()
   143  	_, wm, err := jobs.Register(job, nil)
   144  	if err != nil {
   145  		t.Fatalf("err: %s", err)
   146  	}
   147  	assertWriteMeta(t, wm)
   148  
   149  	// Query the job again and ensure it exists
   150  	// Listing when nothing exists returns empty
   151  	results, qm, err = jobs.List(nil)
   152  	if err != nil {
   153  		t.Fatalf("err: %s", err)
   154  	}
   155  
   156  	// Check if we have the right list
   157  	if len(results) != 1 || results[0].ID != job.ID {
   158  		t.Fatalf("bad: %#v", results)
   159  	}
   160  }
   161  
   162  func TestJobs_Allocations(t *testing.T) {
   163  	c, s := makeClient(t, nil, nil)
   164  	defer s.Stop()
   165  	jobs := c.Jobs()
   166  
   167  	// Looking up by a non-existent job returns nothing
   168  	allocs, qm, err := jobs.Allocations("job1", nil)
   169  	if err != nil {
   170  		t.Fatalf("err: %s", err)
   171  	}
   172  	if qm.LastIndex != 0 {
   173  		t.Fatalf("bad index: %d", qm.LastIndex)
   174  	}
   175  	if n := len(allocs); n != 0 {
   176  		t.Fatalf("expected 0 allocs, got: %d", n)
   177  	}
   178  
   179  	// TODO: do something here to create some allocations for
   180  	// an existing job, lookup again.
   181  }
   182  
   183  func TestJobs_Evaluations(t *testing.T) {
   184  	c, s := makeClient(t, nil, nil)
   185  	defer s.Stop()
   186  	jobs := c.Jobs()
   187  
   188  	// Looking up by a non-existent job ID returns nothing
   189  	evals, qm, err := jobs.Evaluations("job1", nil)
   190  	if err != nil {
   191  		t.Fatalf("err: %s", err)
   192  	}
   193  	if qm.LastIndex != 0 {
   194  		t.Fatalf("bad index: %d", qm.LastIndex)
   195  	}
   196  	if n := len(evals); n != 0 {
   197  		t.Fatalf("expected 0 evals, got: %d", n)
   198  	}
   199  
   200  	// Insert a job. This also creates an evaluation so we should
   201  	// be able to query that out after.
   202  	job := testJob()
   203  	evalID, wm, err := jobs.Register(job, nil)
   204  	if err != nil {
   205  		t.Fatalf("err: %s", err)
   206  	}
   207  	assertWriteMeta(t, wm)
   208  
   209  	// Look up the evaluations again.
   210  	evals, qm, err = jobs.Evaluations("job1", nil)
   211  	if err != nil {
   212  		t.Fatalf("err: %s", err)
   213  	}
   214  	assertQueryMeta(t, qm)
   215  
   216  	// Check that we got the evals back
   217  	if n := len(evals); n == 0 || evals[0].ID != evalID {
   218  		t.Fatalf("expected 1 eval (%s), got: %#v", evalID, evals)
   219  	}
   220  }
   221  
   222  func TestJobs_Deregister(t *testing.T) {
   223  	c, s := makeClient(t, nil, nil)
   224  	defer s.Stop()
   225  	jobs := c.Jobs()
   226  
   227  	// Register a new job
   228  	job := testJob()
   229  	_, wm, err := jobs.Register(job, nil)
   230  	if err != nil {
   231  		t.Fatalf("err: %s", err)
   232  	}
   233  	assertWriteMeta(t, wm)
   234  
   235  	// Attempting delete on non-existing job returns an error
   236  	if _, _, err = jobs.Deregister("nope", nil); err == nil {
   237  		t.Fatalf("expected error deregistering job")
   238  	}
   239  
   240  	// Deleting an existing job works
   241  	evalID, wm3, err := jobs.Deregister("job1", nil)
   242  	if err != nil {
   243  		t.Fatalf("err: %s", err)
   244  	}
   245  	assertWriteMeta(t, wm3)
   246  	if evalID == "" {
   247  		t.Fatalf("missing eval ID")
   248  	}
   249  
   250  	// Check that the job is really gone
   251  	result, qm, err := jobs.List(nil)
   252  	if err != nil {
   253  		t.Fatalf("err: %s", err)
   254  	}
   255  	assertQueryMeta(t, qm)
   256  	if n := len(result); n != 0 {
   257  		t.Fatalf("expected 0 jobs, got: %d", n)
   258  	}
   259  }
   260  
   261  func TestJobs_ForceEvaluate(t *testing.T) {
   262  	c, s := makeClient(t, nil, nil)
   263  	defer s.Stop()
   264  	jobs := c.Jobs()
   265  
   266  	// Force-eval on a non-existent job fails
   267  	_, _, err := jobs.ForceEvaluate("job1", nil)
   268  	if err == nil || !strings.Contains(err.Error(), "not found") {
   269  		t.Fatalf("expected not found error, got: %#v", err)
   270  	}
   271  
   272  	// Create a new job
   273  	_, wm, err := jobs.Register(testJob(), nil)
   274  	if err != nil {
   275  		t.Fatalf("err: %s", err)
   276  	}
   277  	assertWriteMeta(t, wm)
   278  
   279  	// Try force-eval again
   280  	evalID, wm, err := jobs.ForceEvaluate("job1", nil)
   281  	if err != nil {
   282  		t.Fatalf("err: %s", err)
   283  	}
   284  	assertWriteMeta(t, wm)
   285  
   286  	// Retrieve the evals and see if we get a matching one
   287  	evals, qm, err := jobs.Evaluations("job1", nil)
   288  	if err != nil {
   289  		t.Fatalf("err: %s", err)
   290  	}
   291  	assertQueryMeta(t, qm)
   292  	for _, eval := range evals {
   293  		if eval.ID == evalID {
   294  			return
   295  		}
   296  	}
   297  	t.Fatalf("evaluation %q missing", evalID)
   298  }
   299  
   300  func TestJobs_PeriodicForce(t *testing.T) {
   301  	c, s := makeClient(t, nil, nil)
   302  	defer s.Stop()
   303  	jobs := c.Jobs()
   304  
   305  	// Force-eval on a non-existent job fails
   306  	_, _, err := jobs.PeriodicForce("job1", nil)
   307  	if err == nil || !strings.Contains(err.Error(), "not found") {
   308  		t.Fatalf("expected not found error, got: %#v", err)
   309  	}
   310  
   311  	// Create a new job
   312  	job := testPeriodicJob()
   313  	_, _, err = jobs.Register(job, nil)
   314  	if err != nil {
   315  		t.Fatalf("err: %s", err)
   316  	}
   317  
   318  	testutil.WaitForResult(func() (bool, error) {
   319  		out, _, err := jobs.Info(job.ID, nil)
   320  		if err != nil || out == nil || out.ID != job.ID {
   321  			return false, err
   322  		}
   323  		return true, nil
   324  	}, func(err error) {
   325  		t.Fatalf("err: %s", err)
   326  	})
   327  
   328  	// Try force again
   329  	evalID, wm, err := jobs.PeriodicForce(job.ID, nil)
   330  	if err != nil {
   331  		t.Fatalf("err: %s", err)
   332  	}
   333  	assertWriteMeta(t, wm)
   334  
   335  	if evalID == "" {
   336  		t.Fatalf("empty evalID")
   337  	}
   338  
   339  	// Retrieve the eval
   340  	evals := c.Evaluations()
   341  	eval, qm, err := evals.Info(evalID, nil)
   342  	if err != nil {
   343  		t.Fatalf("err: %s", err)
   344  	}
   345  	assertQueryMeta(t, qm)
   346  	if eval.ID == evalID {
   347  		return
   348  	}
   349  	t.Fatalf("evaluation %q missing", evalID)
   350  }
   351  
   352  func TestJobs_NewBatchJob(t *testing.T) {
   353  	job := NewBatchJob("job1", "myjob", "region1", 5)
   354  	expect := &Job{
   355  		Region:   "region1",
   356  		ID:       "job1",
   357  		Name:     "myjob",
   358  		Type:     JobTypeBatch,
   359  		Priority: 5,
   360  	}
   361  	if !reflect.DeepEqual(job, expect) {
   362  		t.Fatalf("expect: %#v, got: %#v", expect, job)
   363  	}
   364  }
   365  
   366  func TestJobs_NewServiceJob(t *testing.T) {
   367  	job := NewServiceJob("job1", "myjob", "region1", 5)
   368  	expect := &Job{
   369  		Region:   "region1",
   370  		ID:       "job1",
   371  		Name:     "myjob",
   372  		Type:     JobTypeService,
   373  		Priority: 5,
   374  	}
   375  	if !reflect.DeepEqual(job, expect) {
   376  		t.Fatalf("expect: %#v, got: %#v", expect, job)
   377  	}
   378  }
   379  
   380  func TestJobs_SetMeta(t *testing.T) {
   381  	job := &Job{Meta: nil}
   382  
   383  	// Initializes a nil map
   384  	out := job.SetMeta("foo", "bar")
   385  	if job.Meta == nil {
   386  		t.Fatalf("should initialize metadata")
   387  	}
   388  
   389  	// Check that the job was returned
   390  	if job != out {
   391  		t.Fatalf("expect: %#v, got: %#v", job, out)
   392  	}
   393  
   394  	// Setting another pair is additive
   395  	job.SetMeta("baz", "zip")
   396  	expect := map[string]string{"foo": "bar", "baz": "zip"}
   397  	if !reflect.DeepEqual(job.Meta, expect) {
   398  		t.Fatalf("expect: %#v, got: %#v", expect, job.Meta)
   399  	}
   400  }
   401  
   402  func TestJobs_Constrain(t *testing.T) {
   403  	job := &Job{Constraints: nil}
   404  
   405  	// Create and add a constraint
   406  	out := job.Constrain(NewConstraint("kernel.name", "=", "darwin"))
   407  	if n := len(job.Constraints); n != 1 {
   408  		t.Fatalf("expected 1 constraint, got: %d", n)
   409  	}
   410  
   411  	// Check that the job was returned
   412  	if job != out {
   413  		t.Fatalf("expect: %#v, got: %#v", job, out)
   414  	}
   415  
   416  	// Adding another constraint preserves the original
   417  	job.Constrain(NewConstraint("memory.totalbytes", ">=", "128000000"))
   418  	expect := []*Constraint{
   419  		&Constraint{
   420  			LTarget: "kernel.name",
   421  			RTarget: "darwin",
   422  			Operand: "=",
   423  		},
   424  		&Constraint{
   425  			LTarget: "memory.totalbytes",
   426  			RTarget: "128000000",
   427  			Operand: ">=",
   428  		},
   429  	}
   430  	if !reflect.DeepEqual(job.Constraints, expect) {
   431  		t.Fatalf("expect: %#v, got: %#v", expect, job.Constraints)
   432  	}
   433  }
   434  
   435  func TestJobs_Sort(t *testing.T) {
   436  	jobs := []*JobListStub{
   437  		&JobListStub{ID: "job2"},
   438  		&JobListStub{ID: "job0"},
   439  		&JobListStub{ID: "job1"},
   440  	}
   441  	sort.Sort(JobIDSort(jobs))
   442  
   443  	expect := []*JobListStub{
   444  		&JobListStub{ID: "job0"},
   445  		&JobListStub{ID: "job1"},
   446  		&JobListStub{ID: "job2"},
   447  	}
   448  	if !reflect.DeepEqual(jobs, expect) {
   449  		t.Fatalf("\n\n%#v\n\n%#v", jobs, expect)
   450  	}
   451  }