1
2
3
4
5
6
7
8
9
10
11
12
13
14 package scheduler
15
16 import (
17 "context"
18 "errors"
19 "testing"
20
21 "github.com/golang/mock/gomock"
22 "github.com/stretchr/testify/assert"
23
24 workflowerrors "github.com/chaos-mesh/chaos-mesh/pkg/workflow/errors"
25 "github.com/chaos-mesh/chaos-mesh/pkg/workflow/mock/model/mock_node"
26 "github.com/chaos-mesh/chaos-mesh/pkg/workflow/mock/model/mock_template"
27 "github.com/chaos-mesh/chaos-mesh/pkg/workflow/mock/model/mock_workflow"
28 "github.com/chaos-mesh/chaos-mesh/pkg/workflow/model/template"
29 )
30
31 func TestScheduleWithSerial(t *testing.T) {
32
33 tests := []struct {
34 name string
35 childrenTemplates []string
36 succeedChildren int
37 expectedScheduledTemplates []string
38 expectedError error
39 }{
40 {
41 name: "no-schedule",
42 childrenTemplates: nil,
43 succeedChildren: 0,
44 expectedScheduledTemplates: nil,
45 expectedError: workflowerrors.ErrNoMoreTemplateInSerialTemplate,
46 }, {
47 name: "alternative-no-schedule",
48 childrenTemplates: []string{},
49 succeedChildren: 0,
50 expectedScheduledTemplates: nil,
51 expectedError: workflowerrors.ErrNoMoreTemplateInSerialTemplate,
52 }, {
53 name: "schedule-one-by-one-0",
54 childrenTemplates: []string{"child-0", "child-1", "child-2"},
55 succeedChildren: 0,
56 expectedScheduledTemplates: []string{"child-0"},
57 expectedError: nil,
58 }, {
59 name: "schedule-one-by-one-1",
60 childrenTemplates: []string{"child-0", "child-1", "child-2"},
61 succeedChildren: 1,
62 expectedScheduledTemplates: []string{"child-1"},
63 expectedError: nil,
64 }, {
65 name: "schedule-one-by-one-2",
66 childrenTemplates: []string{"child-0", "child-1", "child-2"},
67 succeedChildren: 2,
68 expectedScheduledTemplates: []string{"child-2"},
69 expectedError: nil,
70 }, {
71 name: "schedule-one-by-one-final",
72 childrenTemplates: []string{"child-0", "child-1", "child-2"},
73 succeedChildren: 3,
74 expectedScheduledTemplates: nil,
75 expectedError: workflowerrors.ErrNoMoreTemplateInSerialTemplate,
76 }, {
77 name: "schedule-duplicated-template-0",
78 childrenTemplates: []string{"child-0", "child-1", "child-0", "child-1"},
79 succeedChildren: 0,
80 expectedScheduledTemplates: []string{"child-0"},
81 expectedError: nil,
82 }, {
83 name: "schedule-duplicated-template-1",
84 childrenTemplates: []string{"child-0", "child-1", "child-0", "child-1"},
85 succeedChildren: 1,
86 expectedScheduledTemplates: []string{"child-1"},
87 expectedError: nil,
88 }, {
89 name: "schedule-duplicated-template-2",
90 childrenTemplates: []string{"child-0", "child-1", "child-0", "child-1"},
91 succeedChildren: 2,
92 expectedScheduledTemplates: []string{"child-0"},
93 expectedError: nil,
94 }, {
95 name: "schedule-duplicated-template-3",
96 childrenTemplates: []string{"child-0", "child-1", "child-0", "child-1"},
97 succeedChildren: 3,
98 expectedScheduledTemplates: []string{"child-1"},
99 expectedError: nil,
100 }, {
101 name: "schedule-duplicated-template-4",
102 childrenTemplates: []string{"child-0", "child-1", "child-0", "child-1"},
103 succeedChildren: 4,
104 expectedScheduledTemplates: nil,
105 expectedError: workflowerrors.ErrNoMoreTemplateInSerialTemplate,
106 },
107 }
108 for _, test := range tests {
109 t.Run(test.name, func(t *testing.T) {
110 mockctl := gomock.NewController(t)
111 const serialTemplateName = "mock-serial"
112 const serialNodeName = serialTemplateName + "-0000"
113 const workflowName = "mock-workflow"
114
115 mockSerialTemplate := mock_template.NewMockSerialTemplate(mockctl)
116 mockSerialTemplate.EXPECT().TemplateType().Return(template.Serial).AnyTimes()
117 mockSerialTemplate.EXPECT().SerialChildrenList().Return(test.childrenTemplates).AnyTimes()
118
119 mockWorkflowSpec := mock_workflow.NewMockWorkflowSpec(mockctl)
120 mockWorkflowSpec.EXPECT().Name().Return(workflowName).AnyTimes()
121
122 mockTreeNode := mock_node.NewMockNodeTreeNode(mockctl)
123 nodeTreeChildren := mock_node.NewMockNodeTreeChildren(mockctl)
124 mockTreeNode.EXPECT().Name().Return(serialNodeName).AnyTimes()
125 mockTreeNode.EXPECT().Children().Return(nodeTreeChildren).AnyTimes()
126 mockTreeNode.EXPECT().TemplateName().Return(serialTemplateName).AnyTimes()
127 nodeTreeChildren.EXPECT().Length().Return(test.succeedChildren).AnyTimes()
128
129 mockNode := mock_node.NewMockNode(mockctl)
130 mockNode.EXPECT().Name().Return(serialNodeName).AnyTimes()
131 mockNode.EXPECT().TemplateName().Return(serialTemplateName).AnyTimes()
132
133 mockWorkflowSpec.EXPECT().FetchTemplateByName(gomock.Eq(serialTemplateName)).Return(mockSerialTemplate, nil).AnyTimes()
134 for _, childTemplate := range test.childrenTemplates {
135 mockChildTemplate := mock_template.NewMockSerialTemplate(mockctl)
136 mockChildTemplate.EXPECT().Name().Return(childTemplate).AnyTimes()
137 mockWorkflowSpec.EXPECT().FetchTemplateByName(gomock.Eq(childTemplate)).Return(mockChildTemplate, nil).AnyTimes()
138 }
139
140 scheduler := NewSerialScheduler(mockWorkflowSpec, mockNode, mockTreeNode)
141 nextTemplates, parentNodeName, err := scheduler.ScheduleNext(context.TODO())
142 if test.expectedError != nil {
143 assert.Error(t, err)
144 assert.True(t, errors.Is(err, test.expectedError))
145 } else {
146 assert.NoError(t, err)
147 assert.Equal(t, serialNodeName, parentNodeName)
148 var names []string
149 for _, item := range nextTemplates {
150 names = append(names, item.Name())
151 }
152 assert.Equal(t, test.expectedScheduledTemplates, names)
153 }
154 })
155 }
156 }
157