From 771d7ad93ffbc1cdbd1bf635e99cd04e1bab9df3 Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Mon, 7 Sep 2015 14:21:38 -0700 Subject: [PATCH] nomad: guard eval creation based on parent eval --- nomad/eval_endpoint.go | 9 +++++++++ nomad/eval_endpoint_test.go | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/nomad/eval_endpoint.go b/nomad/eval_endpoint.go index d007a1d17..97fb160ea 100644 --- a/nomad/eval_endpoint.go +++ b/nomad/eval_endpoint.go @@ -167,6 +167,15 @@ func (e *Eval) Create(args *structs.EvalUpdateRequest, } eval := args.Evals[0] + // Verify the parent evaluation is outstanding, and that the tokens match. + token, ok := e.srv.evalBroker.Outstanding(eval.PreviousEval) + if !ok { + return fmt.Errorf("previous evaluation is not outstanding") + } + if args.EvalToken != token { + return fmt.Errorf("previous evaluation token does not match") + } + // Look for the eval snap, err := e.srv.fsm.State().Snapshot() if err != nil { diff --git a/nomad/eval_endpoint_test.go b/nomad/eval_endpoint_test.go index 144f8d4a6..d6777a422 100644 --- a/nomad/eval_endpoint_test.go +++ b/nomad/eval_endpoint_test.go @@ -224,10 +224,29 @@ func TestEvalEndpoint_Create(t *testing.T) { defer s1.Shutdown() codec := rpcClient(t, s1) + testutil.WaitForResult(func() (bool, error) { + return s1.evalBroker.Enabled(), nil + }, func(err error) { + t.Fatalf("should enable eval broker") + }) + + // Create the register request + prev := mock.Eval() + s1.evalBroker.Enqueue(prev) + out, token, err := s1.evalBroker.Dequeue(defaultSched, time.Second) + if err != nil { + t.Fatalf("err: %v", err) + } + if out == nil { + t.Fatalf("missing eval") + } + // Create the register request eval1 := mock.Eval() + eval1.PreviousEval = prev.ID get := &structs.EvalUpdateRequest{ Evals: []*structs.Evaluation{eval1}, + EvalToken: token, WriteRequest: structs.WriteRequest{Region: "region1"}, } var resp structs.GenericResponse