1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package controllers
17
18 import (
19 "context"
20 "fmt"
21 "reflect"
22 "sort"
23 "strings"
24 "testing"
25 "time"
26
27 . "github.com/onsi/ginkgo/v2"
28 . "github.com/onsi/gomega"
29 corev1 "k8s.io/api/core/v1"
30 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31 "k8s.io/apimachinery/pkg/types"
32 "sigs.k8s.io/controller-runtime/pkg/client"
33
34 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
35 )
36
37
38 func Test_getTaskNameFromGeneratedName(t *testing.T) {
39 type args struct {
40 generatedNodeName string
41 }
42 tests := []struct {
43 name string
44 args args
45 want string
46 }{
47 {
48 "common case",
49 args{"name-1"},
50 "name",
51 }, {
52 "common case",
53 args{"name-1-2"},
54 "name-1",
55 }, {
56 "common case",
57 args{"name"},
58 "name",
59 }, {
60 "common case",
61 args{"name-"},
62 "name",
63 },
64 {
65 "common case",
66 args{"-name"},
67 "",
68 },
69 }
70 for _, tt := range tests {
71 t.Run(tt.name, func(t *testing.T) {
72 if got := getTaskNameFromGeneratedName(tt.args.generatedNodeName); got != tt.want {
73 t.Errorf("getTaskNameFromGeneratedName() = %v, want %v", got, tt.want)
74 }
75 })
76 }
77 }
78
79 func Test_relativeComplementSet(t *testing.T) {
80 type args struct {
81 former []string
82 latter []string
83 }
84 tests := []struct {
85 name string
86 args args
87 want []string
88 }{
89 {
90 name: "common_case",
91 args: args{
92 former: []string{"a", "b", "c"},
93 latter: []string{},
94 },
95 want: []string{"a", "b", "c"},
96 }, {
97 name: "common_case",
98 args: args{
99 former: []string{"a", "b", "c"},
100 latter: []string{"b", "c"},
101 },
102 want: []string{"a"},
103 }, {
104 name: "common_case",
105 args: args{
106 former: []string{"a", "b", "c"},
107 latter: []string{"c", "a"},
108 },
109 want: []string{"b"},
110 }, {
111 name: "common_case",
112 args: args{
113 former: []string{"a", "b", "c"},
114 latter: []string{"c", "b", "d"},
115 },
116 want: []string{"a"},
117 },
118 }
119 for _, test := range tests {
120 t.Run(test.name, func(t *testing.T) {
121 got := setDifference(test.args.former, test.args.latter)
122 sort.Strings(got)
123 sort.Strings(test.want)
124 if !reflect.DeepEqual(got, test.want) {
125 t.Errorf("getTaskNameFromGeneratedName() = %v, want %v", got, test.want)
126 }
127 })
128 }
129 }
130
131
132 var _ = Describe("Workflow", func() {
133 var ns string
134 BeforeEach(func() {
135 ctx := context.TODO()
136 newNs := corev1.Namespace{
137 ObjectMeta: metav1.ObjectMeta{
138 GenerateName: "chaos-mesh-",
139 },
140 Spec: corev1.NamespaceSpec{},
141 }
142 Expect(kubeClient.Create(ctx, &newNs)).To(Succeed())
143 ns = newNs.Name
144 By(fmt.Sprintf("create new namespace %s", ns))
145 })
146
147 AfterEach(func() {
148 ctx := context.TODO()
149 nsToDelete := corev1.Namespace{}
150 Expect(kubeClient.Get(ctx, types.NamespacedName{Name: ns}, &nsToDelete)).To(Succeed())
151 Expect(kubeClient.Delete(ctx, &nsToDelete)).To(Succeed())
152 By(fmt.Sprintf("cleanup namespace %s", ns))
153 })
154
155 Context("with one parallel node", func() {
156 Context("with one simple parallel node", func() {
157
158 It("should spawn all the children at the same time", func() {
159 By("create simple workflow")
160 ctx := context.TODO()
161 simpleParallelWorkflow := v1alpha1.Workflow{
162 ObjectMeta: metav1.ObjectMeta{
163 Name: "simple-parallel",
164 Namespace: ns,
165 },
166 Spec: v1alpha1.WorkflowSpec{
167 Entry: "parallel",
168 Templates: []v1alpha1.Template{
169 {
170 Name: "parallel",
171 Type: v1alpha1.TypeParallel,
172 Children: []string{
173 "network-chaos",
174 "pod-chaos",
175 "stress-chaos",
176 },
177 }, {
178 Name: "network-chaos",
179 Type: v1alpha1.TypeNetworkChaos,
180 EmbedChaos: &v1alpha1.EmbedChaos{
181 NetworkChaos: &v1alpha1.NetworkChaosSpec{
182 PodSelector: v1alpha1.PodSelector{
183 Selector: v1alpha1.PodSelectorSpec{
184 GenericSelectorSpec: v1alpha1.GenericSelectorSpec{
185 Namespaces: []string{ns},
186 LabelSelectors: map[string]string{
187 "app": "not-exist",
188 },
189 },
190 },
191 Mode: v1alpha1.AllMode,
192 },
193 Action: v1alpha1.PartitionAction,
194 },
195 },
196 }, {
197 Name: "pod-chaos",
198 Type: v1alpha1.TypePodChaos,
199 EmbedChaos: &v1alpha1.EmbedChaos{
200 PodChaos: &v1alpha1.PodChaosSpec{
201 ContainerSelector: v1alpha1.ContainerSelector{
202 PodSelector: v1alpha1.PodSelector{
203 Selector: v1alpha1.PodSelectorSpec{
204 GenericSelectorSpec: v1alpha1.GenericSelectorSpec{
205 Namespaces: []string{ns},
206 LabelSelectors: map[string]string{
207 "app": "not-exist",
208 },
209 },
210 },
211 Mode: v1alpha1.AllMode,
212 },
213 },
214 Action: v1alpha1.PodKillAction,
215 },
216 },
217 },
218 {
219 Name: "stress-chaos",
220 Type: v1alpha1.TypeStressChaos,
221 EmbedChaos: &v1alpha1.EmbedChaos{
222 StressChaos: &v1alpha1.StressChaosSpec{
223 ContainerSelector: v1alpha1.ContainerSelector{
224 PodSelector: v1alpha1.PodSelector{
225 Selector: v1alpha1.PodSelectorSpec{
226 GenericSelectorSpec: v1alpha1.GenericSelectorSpec{
227 Namespaces: []string{ns},
228 LabelSelectors: map[string]string{
229 "app": "not-exist",
230 },
231 },
232 },
233 Mode: v1alpha1.AllMode,
234 },
235 },
236 Stressors: &v1alpha1.Stressors{
237 CPUStressor: &v1alpha1.CPUStressor{
238 Stressor: v1alpha1.Stressor{
239 Workers: 2,
240 },
241 }},
242 },
243 },
244 },
245 },
246 }}
247 Expect(kubeClient.Create(ctx, &simpleParallelWorkflow)).To(Succeed())
248
249 By("assert that all resource has been created")
250
251 By("assert that 1 entry node and 3 chaos nodes created")
252 Eventually(func() int {
253 workflowNodeList := v1alpha1.WorkflowNodeList{}
254 Expect(kubeClient.List(ctx, &workflowNodeList, &client.ListOptions{Namespace: ns})).To(Succeed())
255 return len(workflowNodeList.Items)
256 }, 10*time.Second, time.Second).Should(Equal(4))
257
258 By("assert that network chaos has been created")
259 Eventually(func() bool {
260 chaosList := v1alpha1.NetworkChaosList{}
261 Expect(kubeClient.List(ctx, &chaosList, &client.ListOptions{Namespace: ns})).To(Succeed())
262 if len(chaosList.Items) != 1 {
263 return false
264 }
265 return strings.HasPrefix(chaosList.Items[0].Name, "network-chaos")
266 }, 10*time.Second, time.Second).Should(BeTrue())
267
268 By("assert that pod chaos has been created")
269 Eventually(func() bool {
270 chaosList := v1alpha1.PodChaosList{}
271 Expect(kubeClient.List(ctx, &chaosList, &client.ListOptions{Namespace: ns})).To(Succeed())
272 if len(chaosList.Items) != 1 {
273 return false
274 }
275 return strings.HasPrefix(chaosList.Items[0].Name, "pod-chaos")
276 }, 10*time.Second, time.Second).Should(BeTrue())
277
278 By("assert that stress chaos has been created")
279 Eventually(func() bool {
280 chaosList := v1alpha1.StressChaosList{}
281 Expect(kubeClient.List(ctx, &chaosList, &client.ListOptions{Namespace: ns})).To(Succeed())
282 if len(chaosList.Items) != 1 {
283 return false
284 }
285 return strings.HasPrefix(chaosList.Items[0].Name, "stress-chaos")
286 }, 10*time.Second, time.Second).Should(BeTrue())
287 })
288 })
289 })
290 })
291