1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package archive
17
18 import (
19 "context"
20 "encoding/json"
21 "fmt"
22 "net/http"
23 "net/http/httptest"
24 "testing"
25 "time"
26
27 "github.com/gin-gonic/gin"
28 "github.com/jinzhu/gorm"
29 . "github.com/onsi/ginkgo/v2"
30 . "github.com/onsi/gomega"
31 "github.com/pkg/errors"
32 "github.com/stretchr/testify/mock"
33 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
34
35 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
36 config "github.com/chaos-mesh/chaos-mesh/pkg/config"
37 "github.com/chaos-mesh/chaos-mesh/pkg/dashboard/apiserver/types"
38 "github.com/chaos-mesh/chaos-mesh/pkg/dashboard/core"
39 pkgmock "github.com/chaos-mesh/chaos-mesh/pkg/mock"
40 )
41
42
43 type MockExperimentStore struct {
44 mock.Mock
45 }
46
47
48 type MockScheduleStore struct {
49 mock.Mock
50 }
51
52 func TestEvent(t *testing.T) {
53 RegisterFailHandler(Fail)
54 RunSpecs(t, "types.Archive Suite")
55 }
56
57 func (m *MockExperimentStore) ListMeta(ctx context.Context, kind, namespace, name string, archived bool) ([]*core.ExperimentMeta, error) {
58 var res []*core.ExperimentMeta
59 var err error
60 if kind == "testKind" {
61 expMeta := &core.ExperimentMeta{
62 UID: "testUID",
63 Kind: "testKind",
64 Name: "testName",
65 Namespace: "testNamespace",
66 Action: "testAction",
67 StartTime: time.Time{},
68 FinishTime: &time.Time{},
69 Archived: true,
70 }
71 res = append(res, expMeta)
72 } else {
73 err = errors.New("test err")
74 }
75 return res, err
76 }
77
78 func (m *MockExperimentStore) FindByUID(ctx context.Context, UID string) (*core.Experiment, error) {
79 var res *core.Experiment
80 var err error
81 switch UID {
82 case "testPodChaos":
83 chaos := v1alpha1.PodChaos{}
84 jsonStr, _ := json.Marshal(chaos)
85 res = &core.Experiment{
86 ExperimentMeta: core.ExperimentMeta{
87 UID: UID,
88 Kind: v1alpha1.KindPodChaos,
89 Name: "testName",
90 Namespace: "testNamespace",
91 Action: "testAction",
92 StartTime: time.Time{},
93 FinishTime: &time.Time{},
94 Archived: true,
95 },
96 Experiment: string(jsonStr),
97 }
98 case "testIOChaos":
99 chaos := v1alpha1.IOChaos{}
100 jsonStr, _ := json.Marshal(chaos)
101 res = &core.Experiment{
102 ExperimentMeta: core.ExperimentMeta{
103 UID: UID,
104 Kind: v1alpha1.KindIOChaos,
105 Name: "testName",
106 Namespace: "testNamespace",
107 Action: "testAction",
108 StartTime: time.Time{},
109 FinishTime: &time.Time{},
110 Archived: true,
111 },
112 Experiment: string(jsonStr),
113 }
114 case "testNetworkChaos":
115 chaos := v1alpha1.NetworkChaos{}
116 jsonStr, _ := json.Marshal(chaos)
117 res = &core.Experiment{
118 ExperimentMeta: core.ExperimentMeta{
119 UID: UID,
120 Kind: v1alpha1.KindNetworkChaos,
121 Name: "testName",
122 Namespace: "testNamespace",
123 Action: "testAction",
124 StartTime: time.Time{},
125 FinishTime: &time.Time{},
126 Archived: true,
127 },
128 Experiment: string(jsonStr),
129 }
130 case "testTimeChaos":
131 chaos := v1alpha1.TimeChaos{}
132 jsonStr, _ := json.Marshal(chaos)
133 res = &core.Experiment{
134 ExperimentMeta: core.ExperimentMeta{
135 UID: UID,
136 Kind: v1alpha1.KindTimeChaos,
137 Name: "testName",
138 Namespace: "testNamespace",
139 Action: "testAction",
140 StartTime: time.Time{},
141 FinishTime: &time.Time{},
142 Archived: true,
143 },
144 Experiment: string(jsonStr),
145 }
146 case "testKernelChaos":
147 chaos := v1alpha1.KernelChaos{}
148 jsonStr, _ := json.Marshal(chaos)
149 res = &core.Experiment{
150 ExperimentMeta: core.ExperimentMeta{
151 UID: UID,
152 Kind: v1alpha1.KindKernelChaos,
153 Name: "testName",
154 Namespace: "testNamespace",
155 Action: "testAction",
156 StartTime: time.Time{},
157 FinishTime: &time.Time{},
158 Archived: true,
159 },
160 Experiment: string(jsonStr),
161 }
162 case "testStressChaos":
163 chaos := v1alpha1.StressChaos{}
164 jsonStr, _ := json.Marshal(chaos)
165 res = &core.Experiment{
166 ExperimentMeta: core.ExperimentMeta{
167 UID: UID,
168 Kind: v1alpha1.KindStressChaos,
169 Name: "testName",
170 Namespace: "testNamespace",
171 Action: "testAction",
172 StartTime: time.Time{},
173 FinishTime: &time.Time{},
174 Archived: true,
175 },
176 Experiment: string(jsonStr),
177 }
178 case "testOtherChaos":
179 res = &core.Experiment{
180 ExperimentMeta: core.ExperimentMeta{
181 UID: UID,
182 Kind: "OtherChaos",
183 Name: "testName",
184 Namespace: "testNamespace",
185 Action: "testAction",
186 StartTime: time.Time{},
187 FinishTime: &time.Time{},
188 Archived: true,
189 },
190 Experiment: "",
191 }
192 case "testErrRecordNotFound":
193 err = gorm.ErrRecordNotFound
194 default:
195 err = errors.New("test err")
196 }
197 return res, err
198 }
199
200 func (m *MockExperimentStore) FindMetaByUID(ctx context.Context, UID string) (*core.ExperimentMeta, error) {
201 var res *core.ExperimentMeta
202 var err error
203 switch UID {
204 case "tsetUID":
205 res = &core.ExperimentMeta{
206 UID: "testUID",
207 Kind: "testKind",
208 Name: "testName",
209 Namespace: "testNamespace",
210 Action: "testAction",
211 StartTime: time.Time{},
212 FinishTime: &time.Time{},
213 Archived: true,
214 }
215 case "testErrRecordNotFound":
216 err = gorm.ErrRecordNotFound
217 default:
218 err = errors.New("test err")
219 }
220 return res, err
221 }
222
223 func (m *MockExperimentStore) FindManagedByNamespaceName(ctx context.Context, namespace, name string) ([]*core.Experiment, error) {
224 panic("implement me")
225 }
226
227 func (m *MockExperimentStore) Set(context.Context, *core.Experiment) error {
228 panic("implement me")
229 }
230
231 func (m *MockExperimentStore) Archive(ctx context.Context, namespace, name string) error {
232 panic("implement me")
233 }
234
235 func (m *MockExperimentStore) Delete(context.Context, *core.Experiment) error {
236 panic("implement me")
237 }
238
239 func (m *MockExperimentStore) DeleteByFinishTime(context.Context, time.Duration) error {
240 panic("implement me")
241 }
242
243 func (m *MockExperimentStore) DeleteIncompleteExperiments(context.Context) error {
244 panic("implement me")
245 }
246
247 func (m *MockExperimentStore) DeleteByUIDs(context.Context, []string) error {
248 panic("implement me")
249 }
250
251 func (m *MockScheduleStore) ListMeta(ctx context.Context, namespace, name string, archived bool) ([]*core.ScheduleMeta, error) {
252 var res []*core.ScheduleMeta
253 var err error
254 if name == "testScheduleName" {
255 schMeta := &core.ScheduleMeta{
256 UID: "testUID",
257 Kind: "testKind",
258 Name: "testScheduleName",
259 Namespace: "testNamespace",
260 Action: "testAction",
261 StartTime: time.Time{},
262 FinishTime: &time.Time{},
263 Archived: true,
264 }
265 res = append(res, schMeta)
266 } else {
267 err = errors.New("test err")
268 }
269 return res, err
270 }
271
272 func (m *MockScheduleStore) FindByUID(ctx context.Context, UID string) (*core.Schedule, error) {
273 var res *core.Schedule
274 var err error
275 switch UID {
276 case "testPodChaos":
277 sch := v1alpha1.Schedule{}
278 jsonStr, _ := json.Marshal(sch)
279 res = &core.Schedule{
280 ScheduleMeta: core.ScheduleMeta{
281 UID: UID,
282 Kind: v1alpha1.KindPodChaos,
283 Name: "testName",
284 Namespace: "testNamespace",
285 Action: "testAction",
286 StartTime: time.Time{},
287 FinishTime: &time.Time{},
288 Archived: true,
289 },
290 Schedule: string(jsonStr),
291 }
292 case "testErrRecordNotFound":
293 err = gorm.ErrRecordNotFound
294 default:
295 err = errors.New("test err")
296 }
297 return res, err
298 }
299
300 func (m *MockScheduleStore) FindMetaByUID(context.Context, string) (*core.ScheduleMeta, error) {
301 panic("implement me")
302 }
303
304 func (m *MockScheduleStore) Set(context.Context, *core.Schedule) error {
305 panic("implement me")
306 }
307
308 func (m *MockScheduleStore) Archive(ctx context.Context, namespace, name string) error {
309 panic("implement me")
310 }
311
312 func (m *MockScheduleStore) Delete(context.Context, *core.Schedule) error {
313 panic("implement me")
314 }
315
316 func (m *MockScheduleStore) DeleteByFinishTime(context.Context, time.Duration) error {
317 panic("implement me")
318 }
319
320 func (m *MockScheduleStore) DeleteByUIDs(context.Context, []string) error {
321 panic("implement me")
322 }
323
324 func (m *MockScheduleStore) DeleteIncompleteSchedules(context.Context) error {
325 panic("implement me")
326 }
327
328 var _ = Describe("event", func() {
329 var router *gin.Engine
330 BeforeEach(func() {
331 pkgmock.With("AuthMiddleware", true)
332
333 mockExpStore := new(MockExperimentStore)
334 mockSchStore := new(MockScheduleStore)
335
336 s := Service{
337 archive: mockExpStore,
338 archiveSchedule: mockSchStore,
339 event: nil,
340 conf: &config.ChaosDashboardConfig{
341 ClusterScoped: true,
342 },
343 }
344 router = gin.Default()
345 r := router.Group("/api")
346 endpoint := r.Group("/archives")
347
348 endpoint.GET("", s.list)
349 endpoint.GET("/:uid", s.get)
350
351 endpoint.GET("/schedules", s.listSchedule)
352 endpoint.GET("/schedules/:uid", s.detailSchedule)
353 })
354
355 AfterEach(func() {
356
357 pkgmock.Reset("AuthMiddleware")
358 })
359
360 Context("List", func() {
361 It("success", func() {
362 response := []types.Archive{
363 {
364 UID: "testUID",
365 Kind: "testKind",
366 Namespace: "testNamespace",
367 Name: "testName",
368 Created: time.Time{}.Format(time.RFC3339),
369 },
370 }
371 rr := httptest.NewRecorder()
372 request, _ := http.NewRequest(http.MethodGet, "/api/archives?kind=testKind", nil)
373 router.ServeHTTP(rr, request)
374 Expect(rr.Code).Should(Equal(http.StatusOK))
375 responseBody, err := json.Marshal(response)
376 Expect(err).ShouldNot(HaveOccurred())
377 Expect(rr.Body.Bytes()).Should(Equal(responseBody))
378 })
379
380 It("test err", func() {
381 rr := httptest.NewRecorder()
382 request, _ := http.NewRequest(http.MethodGet, "/api/archives", nil)
383 router.ServeHTTP(rr, request)
384 Expect(rr.Code).Should(Equal(http.StatusInternalServerError))
385 })
386 })
387
388 Context("Detail", func() {
389 It("testPodChaos", func() {
390 chaos := &v1alpha1.PodChaos{}
391 response := types.ArchiveDetail{
392 Archive: types.Archive{
393 UID: "testPodChaos",
394 Kind: v1alpha1.KindPodChaos,
395 Namespace: "testNamespace",
396 Name: "testName",
397 Created: time.Time{}.Format(time.RFC3339),
398 },
399 KubeObject: core.KubeObjectDesc{
400 TypeMeta: metav1.TypeMeta{
401 APIVersion: "",
402 Kind: "",
403 },
404 Meta: core.KubeObjectMeta{
405 Name: "",
406 Namespace: "",
407 Labels: nil,
408 Annotations: nil,
409 },
410 Spec: chaos.Spec,
411 },
412 }
413 rr := httptest.NewRecorder()
414 request, _ := http.NewRequest(http.MethodGet, "/api/archives/testPodChaos", nil)
415 router.ServeHTTP(rr, request)
416 Expect(rr.Code).Should(Equal(http.StatusOK))
417 responseBody, err := json.Marshal(response)
418 Expect(err).ShouldNot(HaveOccurred())
419 Expect(rr.Body.Bytes()).Should(Equal(responseBody))
420 })
421
422 It("testIOChaos", func() {
423 chaos := &v1alpha1.IOChaos{}
424 response := types.ArchiveDetail{
425 Archive: types.Archive{
426 UID: "testIOChaos",
427 Kind: v1alpha1.KindIOChaos,
428 Namespace: "testNamespace",
429 Name: "testName",
430 Created: time.Time{}.Format(time.RFC3339),
431 },
432 KubeObject: core.KubeObjectDesc{
433 TypeMeta: metav1.TypeMeta{
434 APIVersion: "",
435 Kind: "",
436 },
437 Meta: core.KubeObjectMeta{
438 Name: "",
439 Namespace: "",
440 Labels: nil,
441 Annotations: nil,
442 },
443 Spec: chaos.Spec,
444 },
445 }
446 rr := httptest.NewRecorder()
447 request, _ := http.NewRequest(http.MethodGet, "/api/archives/testIOChaos", nil)
448 router.ServeHTTP(rr, request)
449 Expect(rr.Code).Should(Equal(http.StatusOK))
450 responseBody, err := json.Marshal(response)
451 Expect(err).ShouldNot(HaveOccurred())
452 Expect(rr.Body.Bytes()).Should(Equal(responseBody))
453 })
454
455 It("testNetworkChaos", func() {
456 chaos := &v1alpha1.NetworkChaos{}
457 response := types.ArchiveDetail{
458 Archive: types.Archive{
459 UID: "testNetworkChaos",
460 Kind: v1alpha1.KindNetworkChaos,
461 Namespace: "testNamespace",
462 Name: "testName",
463 Created: time.Time{}.Format(time.RFC3339),
464 },
465 KubeObject: core.KubeObjectDesc{
466 TypeMeta: metav1.TypeMeta{
467 APIVersion: "",
468 Kind: "",
469 },
470 Meta: core.KubeObjectMeta{
471 Name: "",
472 Namespace: "",
473 Labels: nil,
474 Annotations: nil,
475 },
476 Spec: chaos.Spec,
477 },
478 }
479 rr := httptest.NewRecorder()
480 request, _ := http.NewRequest(http.MethodGet, "/api/archives/testNetworkChaos", nil)
481 router.ServeHTTP(rr, request)
482 Expect(rr.Code).Should(Equal(http.StatusOK))
483 responseBody, err := json.Marshal(response)
484 Expect(err).ShouldNot(HaveOccurred())
485 Expect(rr.Body.Bytes()).Should(Equal(responseBody))
486 })
487
488 It("testTimeChaos", func() {
489 chaos := &v1alpha1.TimeChaos{}
490 response := types.ArchiveDetail{
491 Archive: types.Archive{
492 UID: "testTimeChaos",
493 Kind: v1alpha1.KindTimeChaos,
494 Namespace: "testNamespace",
495 Name: "testName",
496 Created: time.Time{}.Format(time.RFC3339),
497 },
498 KubeObject: core.KubeObjectDesc{
499 TypeMeta: metav1.TypeMeta{
500 APIVersion: "",
501 Kind: "",
502 },
503 Meta: core.KubeObjectMeta{
504 Name: "",
505 Namespace: "",
506 Labels: nil,
507 Annotations: nil,
508 },
509 Spec: chaos.Spec,
510 },
511 }
512 rr := httptest.NewRecorder()
513 request, _ := http.NewRequest(http.MethodGet, "/api/archives/testTimeChaos", nil)
514 router.ServeHTTP(rr, request)
515 Expect(rr.Code).Should(Equal(http.StatusOK))
516 responseBody, err := json.Marshal(response)
517 Expect(err).ShouldNot(HaveOccurred())
518 Expect(rr.Body.Bytes()).Should(Equal(responseBody))
519 })
520
521 It("testKernelChaos", func() {
522 chaos := &v1alpha1.KernelChaos{}
523 response := types.ArchiveDetail{
524 Archive: types.Archive{
525 UID: "testKernelChaos",
526 Kind: v1alpha1.KindKernelChaos,
527 Namespace: "testNamespace",
528 Name: "testName",
529 Created: time.Time{}.Format(time.RFC3339),
530 },
531 KubeObject: core.KubeObjectDesc{
532 TypeMeta: metav1.TypeMeta{
533 APIVersion: "",
534 Kind: "",
535 },
536 Meta: core.KubeObjectMeta{
537 Name: "",
538 Namespace: "",
539 Labels: nil,
540 Annotations: nil,
541 },
542 Spec: chaos.Spec,
543 },
544 }
545 rr := httptest.NewRecorder()
546 request, _ := http.NewRequest(http.MethodGet, "/api/archives/testKernelChaos", nil)
547 router.ServeHTTP(rr, request)
548 Expect(rr.Code).Should(Equal(http.StatusOK))
549 responseBody, err := json.Marshal(response)
550 Expect(err).ShouldNot(HaveOccurred())
551 Expect(rr.Body.Bytes()).Should(Equal(responseBody))
552 })
553
554 It("testStressChaos", func() {
555 chaos := &v1alpha1.StressChaos{}
556 response := types.ArchiveDetail{
557 Archive: types.Archive{
558 UID: "testStressChaos",
559 Kind: v1alpha1.KindStressChaos,
560 Namespace: "testNamespace",
561 Name: "testName",
562 Created: time.Time{}.Format(time.RFC3339),
563 },
564 KubeObject: core.KubeObjectDesc{
565 TypeMeta: metav1.TypeMeta{
566 APIVersion: "",
567 Kind: "",
568 },
569 Meta: core.KubeObjectMeta{
570 Name: "",
571 Namespace: "",
572 Labels: nil,
573 Annotations: nil,
574 },
575 Spec: chaos.Spec,
576 },
577 }
578 rr := httptest.NewRecorder()
579 request, _ := http.NewRequest(http.MethodGet, "/api/archives/testStressChaos", nil)
580 router.ServeHTTP(rr, request)
581 Expect(rr.Code).Should(Equal(http.StatusOK))
582 responseBody, err := json.Marshal(response)
583 Expect(err).ShouldNot(HaveOccurred())
584 Expect(rr.Body.Bytes()).Should(Equal(responseBody))
585 })
586
587 It("testOtherChaos", func() {
588 rr := httptest.NewRecorder()
589 request, _ := http.NewRequest(http.MethodGet, "/api/archives/testOtherChaos", nil)
590 router.ServeHTTP(rr, request)
591 Expect(rr.Code).Should(Equal(http.StatusInternalServerError))
592 })
593
594 It("testErrRecordNotFound", func() {
595 rr := httptest.NewRecorder()
596 request, _ := http.NewRequest(http.MethodGet, "/api/archives/testErrRecordNotFound", nil)
597 router.ServeHTTP(rr, request)
598 Expect(rr.Code).Should(Equal(http.StatusNotFound))
599 })
600
601 It("test err", func() {
602 rr := httptest.NewRecorder()
603 request, _ := http.NewRequest(http.MethodGet, "/api/archives/testErr", nil)
604 router.ServeHTTP(rr, request)
605 fmt.Println(rr.Code)
606 Expect(rr.Code).Should(Equal(http.StatusInternalServerError))
607 })
608 })
609
610 Context("ListSchedule", func() {
611 It("success", func() {
612 response := []types.Archive{
613 {
614 UID: "testUID",
615 Kind: "testKind",
616 Namespace: "testNamespace",
617 Name: "testScheduleName",
618 Created: time.Time{}.Format(time.RFC3339),
619 },
620 }
621 rr := httptest.NewRecorder()
622 request, _ := http.NewRequest(http.MethodGet, "/api/archives/schedules?name=testScheduleName", nil)
623 router.ServeHTTP(rr, request)
624 Expect(rr.Code).Should(Equal(http.StatusOK))
625 responseBody, err := json.Marshal(response)
626 Expect(err).ShouldNot(HaveOccurred())
627 Expect(rr.Body.Bytes()).Should(Equal(responseBody))
628 })
629
630 It("test err", func() {
631 rr := httptest.NewRecorder()
632 request, _ := http.NewRequest(http.MethodGet, "/api/archives/schedules", nil)
633 router.ServeHTTP(rr, request)
634 Expect(rr.Code).Should(Equal(http.StatusInternalServerError))
635 })
636 })
637
638 Context("DetailSchedule", func() {
639 It("testPodChaos", func() {
640 sch := &v1alpha1.Schedule{}
641 response := types.ArchiveDetail{
642 Archive: types.Archive{
643 UID: "testPodChaos",
644 Kind: v1alpha1.KindPodChaos,
645 Namespace: "testNamespace",
646 Name: "testName",
647 Created: time.Time{}.Format(time.RFC3339),
648 },
649 KubeObject: core.KubeObjectDesc{
650 TypeMeta: metav1.TypeMeta{
651 APIVersion: "",
652 Kind: "",
653 },
654 Meta: core.KubeObjectMeta{
655 Name: "",
656 Namespace: "",
657 Labels: nil,
658 Annotations: nil,
659 },
660 Spec: sch.Spec,
661 },
662 }
663 rr := httptest.NewRecorder()
664 request, _ := http.NewRequest(http.MethodGet, "/api/archives/schedules/testPodChaos", nil)
665 router.ServeHTTP(rr, request)
666 Expect(rr.Code).Should(Equal(http.StatusOK))
667 responseBody, err := json.Marshal(response)
668 Expect(err).ShouldNot(HaveOccurred())
669 Expect(rr.Body.Bytes()).Should(Equal(responseBody))
670 })
671
672 It("testErrRecordNotFound", func() {
673 rr := httptest.NewRecorder()
674 request, _ := http.NewRequest(http.MethodGet, "/api/archives/schedules/testErrRecordNotFound", nil)
675 router.ServeHTTP(rr, request)
676 Expect(rr.Code).Should(Equal(http.StatusNotFound))
677 })
678
679 It("test err", func() {
680 rr := httptest.NewRecorder()
681 request, _ := http.NewRequest(http.MethodGet, "/api/archives/schedules/testErr", nil)
682 router.ServeHTTP(rr, request)
683 Expect(rr.Code).Should(Equal(http.StatusInternalServerError))
684 })
685 })
686 })
687