Repository: hashicorp/nomad
File: nomad/job_endpoint_test.go (Go)

Code before:
		NackTimer: time.NewTimer(time.Minute),
	}

	t.Log("marking remaining canary as healthy")
	updateFromClient(canaries[1], true, true) // now healthy

	t.Log("waiting for promotion")
	must.Wait(t, wait.InitialSuccess(
		wait.ErrorFunc(func() error {
			d, err := srv.State().DeploymentByID(nil, dID)
			if err != nil {
				return err
			}
			if !d.TaskGroups["web"].Promoted {
				return fmt.Errorf("deployment not promoted: %+v", d)
			}
			return nil
		}),
		wait.Timeout(2*time.Second),
		wait.Gap(time.Millisecond*10),
	))

	time.Sleep(time.Second)

	err = srv.workers[0].invokeScheduler(snap, eval, evalToken)
	if err != nil { // this is racy with the deplyoment watcher, so we won't always see it
		t.Log("scheduler had write skew with deployment")
		must.EqError(t, err,
			"failed to process evaluation: deployment promotion cannot be undone")
	} else {
		// note: this is the reconciler output, not the resulting plan
		eval, _ = srv.State().EvalByID(nil, eval.ID)
		must.Eq(t, 2, eval.PlanAnnotations.DesiredTGUpdates["web"].Ignore)
		must.Eq(t, 2, eval.PlanAnnotations.DesiredTGUpdates["web"].DestructiveUpdate)
	}

	// ensure dstate hasn't been mutated incorrectly
	d, _ := srv.State().DeploymentByID(nil, dID)
	dstate := d.TaskGroups["web"]
	must.Eq(t, 2, dstate.DesiredCanaries)
	must.Eq(t, 2, dstate.HealthyAllocs)
	gotCanaryIds := slices.Clone(dstate.PlacedCanaries)
	sort.Strings(gotCanaryIds)
	must.Eq(t, canaryIDs, gotCanaryIds)
	must.True(t, dstate.Promoted)

	srv.evalBroker.SetEnabled(true)
	t.Log("eval broker unpaused")

	t.Log("waiting for remaining allocs")
	must.Wait(t, wait.InitialSuccess(

Review comment (suggestion):
```suggestion
	if err != nil { // this is racy with the deployment watcher, so we won't always see it
```

Code after:
		NackTimer: time.NewTimer(time.Minute),
	}

	t.Log("marking remaining canary as healthy")
	updateFromClient(canaries[1], true, true) // now healthy

	t.Log("waiting for promotion")
	must.Wait(t, wait.InitialSuccess(
		wait.ErrorFunc(func() error {
			d, err := srv.State().DeploymentByID(nil, dID)
			if err != nil {
				return err
			}
			if !d.TaskGroups["web"].Promoted {
				return fmt.Errorf("deployment not promoted: %+v", d)
			}
			return nil
		}),
		wait.Timeout(2*time.Second),
		wait.Gap(time.Millisecond*10),
	))

	time.Sleep(time.Second)

	err = srv.workers[0].invokeScheduler(snap, eval, evalToken)
	if err != nil { // this is racy with the deployment watcher, so we won't always see it
		t.Log("scheduler had write skew with deployment")
		must.EqError(t, err,
			"failed to process evaluation: deployment promotion cannot be undone")
	} else {
		// note: this is the reconciler output, not the resulting plan
		eval, _ = srv.State().EvalByID(nil, eval.ID)
		must.Eq(t, 2, eval.PlanAnnotations.DesiredTGUpdates["web"].Ignore)
		must.Eq(t, 2, eval.PlanAnnotations.DesiredTGUpdates["web"].DestructiveUpdate)
	}

	// ensure dstate hasn't been mutated incorrectly
	d, _ := srv.State().DeploymentByID(nil, dID)
	dstate := d.TaskGroups["web"]
	must.Eq(t, 2, dstate.DesiredCanaries)
	must.Eq(t, 2, dstate.HealthyAllocs)
	gotCanaryIds := slices.Clone(dstate.PlacedCanaries)
	sort.Strings(gotCanaryIds)
	must.Eq(t, canaryIDs, gotCanaryIds)
	must.True(t, dstate.Promoted)

	srv.evalBroker.SetEnabled(true)
	t.Log("eval broker unpaused")

	t.Log("waiting for remaining allocs")
	must.Wait(t, wait.InitialSuccess(