func TestReconciler_PausedOrFailedDeployment_NoMoreCanaries(t *testing.T) {
	job := mock.Job()
	job.TaskGroups[0].Update = canaryUpdate

	cases := []struct {
		name             string
		deploymentStatus string
		stop             uint64
	}{
		{
			name:             "paused deployment",
			deploymentStatus: structs.DeploymentStatusPaused,
			stop:             0,
		},
		{
			name:             "failed deployment",
			deploymentStatus: structs.DeploymentStatusFailed,
			stop:             1,
		},
	}

	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			// Create a deployment that is paused/failed and has placed some canaries
			d := structs.NewDeployment(job)
			d.Status = c.deploymentStatus
			d.TaskGroups[job.TaskGroups[0].Name] = &structs.DeploymentState{
				Promoted:        false,
				DesiredCanaries: 2,
				DesiredTotal:    10,
				PlacedAllocs:    1,
			}

			// Create 10 allocations for the original job
			var allocs []*structs.Allocation
			for i := 0; i < 10; i++ {
				alloc := mock.Alloc()
				alloc.Job = job
				alloc.JobID = job.ID
				alloc.NodeID = structs.GenerateUUID()
				alloc.Name = structs.AllocName(job.ID, job.TaskGroups[0].Name, uint(i))
				alloc.TaskGroup = job.TaskGroups[0].Name
				allocs = append(allocs, alloc)
			}

			// Create one canary
			canary := mock.Alloc()
			canary.Job = job
			canary.JobID = job.ID
			canary.NodeID = structs.GenerateUUID()
			canary.Name = structs.AllocName(job.ID, job.TaskGroups[0].Name, 0)
			canary.TaskGroup = job.TaskGroups[0].Name
			canary.DeploymentID = d.ID
			allocs = append(allocs, canary)
			d.TaskGroups[canary.TaskGroup].PlacedCanaries = []string{canary.ID}

			mockUpdateFn := allocUpdateFnMock(map[string]allocUpdateType{canary.ID: allocUpdateFnIgnore}, allocUpdateFnDestructive)
			reconciler := NewAllocReconciler(testLogger(), mockUpdateFn, false, job.ID, job, d, allocs, nil)
			r := reconciler.Compute()

			// Assert the correct results
			assertResults(t, r, &resultExpectation{
				createDeployment:  nil,
				deploymentUpdates: nil,
				place:             0,
				inplace:           0,
				stop:              int(c.stop),
				desiredTGUpdates: map[string]*structs.DesiredUpdates{
					job.TaskGroups[0].Name: {
						Ignore: 11 - c.stop,
						Stop:   c.stop,
					},
				},
			})
		})
	}
}
// Tests the reconciler doesn't place any more canaries when the deployment is
// paused or failed
Tests the reconciler doesn't place any more canaries when the deployment is
paused or failed
// Tests the reconciler doesn ' t place any more canaries when the deployment is // paused or failed
func TestReconciler_PausedOrFailedDeployment_NoMoreCanaries(t *testing.T) {
	job := mock.Job()
	job.TaskGroups[0].Update = canaryUpdate
	cases := []struct {
		name             string
		deploymentStatus string
		stop             uint64
	}{
		{
			name:             "paused deployment",
			deploymentStatus: structs.DeploymentStatusPaused,
			stop:             0,
		},
		{
			name:             "failed deployment",
			deploymentStatus: structs.DeploymentStatusFailed,
			stop:             1,
		},
	}
	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			d := structs.NewDeployment(job)
			d.Status = c.deploymentStatus
			d.TaskGroups[job.TaskGroups[0].Name] = &structs.DeploymentState{
				Promoted:        false,
				DesiredCanaries: 2,
				DesiredTotal:    10,
				PlacedAllocs:    1,
			}
			var allocs []*structs.Allocation
			for i := 0; i < 10; i++ {
				alloc := mock.Alloc()
				alloc.Job = job
				alloc.JobID = job.ID
				alloc.NodeID = structs.GenerateUUID()
				alloc.Name = structs.AllocName(job.ID, job.TaskGroups[0].Name, uint(i))
				alloc.TaskGroup = job.TaskGroups[0].Name
				allocs = append(allocs, alloc)
			}
			canary := mock.Alloc()
			canary.Job = job
			canary.JobID = job.ID
			canary.NodeID = structs.GenerateUUID()
			canary.Name = structs.AllocName(job.ID, job.TaskGroups[0].Name, 0)
			canary.TaskGroup = job.TaskGroups[0].Name
			canary.DeploymentID = d.ID
			allocs = append(allocs, canary)
			d.TaskGroups[canary.TaskGroup].PlacedCanaries = []string{canary.ID}
			mockUpdateFn := allocUpdateFnMock(map[string]allocUpdateType{canary.ID: allocUpdateFnIgnore}, allocUpdateFnDestructive)
			reconciler := NewAllocReconciler(testLogger(), mockUpdateFn, false, job.ID, job, d, allocs, nil)
			r := reconciler.Compute()
			assertResults(t, r, &resultExpectation{
				createDeployment:  nil,
				deploymentUpdates: nil,
				place:             0,
				inplace:           0,
				stop:              int(c.stop),
				desiredTGUpdates: map[string]*structs.DesiredUpdates{
					job.TaskGroups[0].Name: {
						Ignore: 11 - c.stop,
						Stop:   c.stop,
					},
				},
			})
		})
	}
}
func TestReconciler_PausedOrFailedDeployment_NoMoreCanaries ( t * testing . T ) { job := mock . Job ( ) job . TaskGroups [ 0 ] . Update = canaryUpdate cases := [ ] struct { name string deploymentStatus string stop uint64 } { { name : " " , deploymentStatus : structs . DeploymentStatusPaused , stop : 0 , } , { name : " " , deploymentStatus : structs . DeploymentStatusFailed , stop : 1 , } , } for _ , c := range cases { t . Run ( c . name , func ( t * testing . T ) { d := structs . NewDeployment ( job ) d . Status = c . deploymentStatus d . TaskGroups [ job . TaskGroups [ 0 ] . Name ] = & structs . DeploymentState { Promoted : false , DesiredCanaries : 2 , DesiredTotal : 10 , PlacedAllocs : 1 , } var allocs [ ] * structs . Allocation for i := 0 ; i < 10 ; i ++ { alloc := mock . Alloc ( ) alloc . Job = job alloc . JobID = job . ID alloc . NodeID = structs . GenerateUUID ( ) alloc . Name = structs . AllocName ( job . ID , job . TaskGroups [ 0 ] . Name , uint ( i ) ) alloc . TaskGroup = job . TaskGroups [ 0 ] . Name allocs = append ( allocs , alloc ) } canary := mock . Alloc ( ) canary . Job = job canary . JobID = job . ID canary . NodeID = structs . GenerateUUID ( ) canary . Name = structs . AllocName ( job . ID , job . TaskGroups [ 0 ] . Name , 0 ) canary . TaskGroup = job . TaskGroups [ 0 ] . Name canary . DeploymentID = d . ID allocs = append ( allocs , canary ) d . TaskGroups [ canary . TaskGroup ] . PlacedCanaries = [ ] string { canary . ID } mockUpdateFn := allocUpdateFnMock ( map [ string ] allocUpdateType { canary . ID : allocUpdateFnIgnore } , allocUpdateFnDestructive ) reconciler := NewAllocReconciler ( testLogger ( ) , mockUpdateFn , false , job . ID , job , d , allocs , nil ) r := reconciler . Compute ( ) assertResults ( t , r , & resultExpectation { createDeployment : nil , deploymentUpdates : nil , place : 0 , inplace : 0 , stop : int ( c . stop ) , desiredTGUpdates : map [ string ] * structs . DesiredUpdates { job . TaskGroups [ 0 ] . Name : { Ignore : 11 - c . stop , Stop : c . stop , } , } , } ) } ) } }
Tests the reconciler doesn't place any more canaries when the deployment is
paused or failed
Tests the reconciler doesn ' t place any more canaries when the deployment is paused or failed
// Create a deployment that is paused/failed and has placed some canaries // Create 10 allocations for the original job // Create one canary // Assert the correct results