diff --git a/nomad/job_endpoint.go b/nomad/job_endpoint.go index eb6205e06..e02c5a812 100644 --- a/nomad/job_endpoint.go +++ b/nomad/job_endpoint.go @@ -120,7 +120,7 @@ func (j *Job) Evaluate(args *structs.JobEvaluateRequest, reply *structs.JobRegis if err != nil { return err } - if job == nil { + if job != nil && job.IsPeriodic() { return fmt.Errorf("job not found") } @@ -179,9 +179,6 @@ func (j *Job) Deregister(args *structs.JobDeregisterRequest, reply *structs.JobD if err != nil { return err } - if job == nil { - return fmt.Errorf("job not found") - } // Commit this update via Raft _, index, err := j.srv.raftApply(structs.JobDeregisterRequestType, args) @@ -194,7 +191,7 @@ func (j *Job) Deregister(args *structs.JobDeregisterRequest, reply *structs.JobD reply.JobModifyIndex = index // If the job is periodic, we don't create an eval. - if job.IsPeriodic() { + if job != nil && job.IsPeriodic() { return nil } diff --git a/nomad/job_endpoint_test.go b/nomad/job_endpoint_test.go index 7c313e8d0..16131414c 100644 --- a/nomad/job_endpoint_test.go +++ b/nomad/job_endpoint_test.go @@ -463,6 +463,61 @@ func TestJobEndpoint_Deregister(t *testing.T) { } } +func TestJobEndpoint_Deregister_NonExistent(t *testing.T) { + s1 := testServer(t, func(c *Config) { + c.NumSchedulers = 0 // Prevent automatic dequeue + }) + defer s1.Shutdown() + codec := rpcClient(t, s1) + testutil.WaitForLeader(t, s1.RPC) + + // Deregister + jobID := "foo" + dereg := &structs.JobDeregisterRequest{ + JobID: jobID, + WriteRequest: structs.WriteRequest{Region: "global"}, + } + var resp2 structs.JobDeregisterResponse + if err := msgpackrpc.CallWithCodec(codec, "Job.Deregister", dereg, &resp2); err != nil { + t.Fatalf("err: %v", err) + } + if resp2.JobModifyIndex == 0 { + t.Fatalf("bad index: %d", resp2.Index) + } + + // Lookup the evaluation + state := s1.fsm.State() + eval, err := state.EvalByID(resp2.EvalID) + if err != nil { + t.Fatalf("err: %v", err) + } + if eval == nil { + t.Fatalf("expected eval") + } + if eval.CreateIndex != resp2.EvalCreateIndex { + t.Fatalf("index mis-match") + } + + if eval.Priority != structs.JobDefaultPriority { + t.Fatalf("bad: %#v", eval) + } + if eval.Type != structs.JobTypeService { + t.Fatalf("bad: %#v", eval) + } + if eval.TriggeredBy != structs.EvalTriggerJobDeregister { + t.Fatalf("bad: %#v", eval) + } + if eval.JobID != jobID { + t.Fatalf("bad: %#v", eval) + } + if eval.JobModifyIndex != resp2.JobModifyIndex { + t.Fatalf("bad: %#v", eval) + } + if eval.Status != structs.EvalStatusPending { + t.Fatalf("bad: %#v", eval) + } +} + func TestJobEndpoint_Deregister_Periodic(t *testing.T) { s1 := testServer(t, func(c *Config) { c.NumSchedulers = 0 // Prevent automatic dequeue