1
2
3
4
5
6
7
8
9
10
11
12
13
14 package httpchaos
15
16 import (
17 "context"
18 "net/http"
19 "time"
20
21 . "github.com/onsi/ginkgo"
22 corev1 "k8s.io/api/core/v1"
23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24 "k8s.io/apimachinery/pkg/types"
25 "k8s.io/apimachinery/pkg/util/wait"
26 "k8s.io/kubernetes/test/e2e/framework"
27 "sigs.k8s.io/controller-runtime/pkg/client"
28
29 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
30 "github.com/chaos-mesh/chaos-mesh/e2e-test/e2e/util"
31 )
32
33 func TestcaseHttpAbortThenRecover(
34 ns string,
35 cli client.Client,
36 c http.Client,
37 port uint16,
38 ) {
39 ctx, cancel := context.WithCancel(context.Background())
40 defer cancel()
41
42 By("waiting on e2e helper ready")
43 err := util.WaitE2EHelperReady(c, port)
44 framework.ExpectNoError(err, "wait e2e helper ready error")
45 By("create http abort chaos CRD objects")
46
47 abort := true
48
49 httpChaos := &v1alpha1.HTTPChaos{
50 ObjectMeta: metav1.ObjectMeta{
51 Name: "http-chaos",
52 Namespace: ns,
53 },
54 Spec: v1alpha1.HTTPChaosSpec{
55 PodSelector: v1alpha1.PodSelector{
56 Selector: v1alpha1.PodSelectorSpec{
57 Namespaces: []string{ns},
58 LabelSelectors: map[string]string{"app": "http"},
59 },
60 Mode: v1alpha1.OnePodMode,
61 },
62 Port: 8080,
63 Target: "Request",
64 PodHttpChaosActions: v1alpha1.PodHttpChaosActions{
65 Abort: &abort,
66 },
67 },
68 }
69 err = cli.Create(ctx, httpChaos)
70 framework.ExpectNoError(err, "create http chaos error")
71
72 By("waiting for assertion HTTP abort")
73 err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
74 _, err := getPodHttpNoBody(c, port)
75
76
77 if err != nil {
78 return true, nil
79 }
80 return false, nil
81 })
82 framework.ExpectNoError(err, "http chaos doesn't work as expected")
83 By("apply http chaos successfully")
84
85 By("delete chaos CRD objects")
86
87 err = cli.Delete(ctx, httpChaos)
88 framework.ExpectNoError(err, "failed to delete http chaos")
89
90 By("waiting for assertion recovering")
91 err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
92 _, err := getPodHttpNoBody(c, port)
93
94
95 if err != nil {
96 return false, nil
97 }
98 return true, nil
99 })
100 framework.ExpectNoError(err, "fail to recover http chaos")
101 }
102
103 func TestcaseHttpAbortPauseAndUnPause(
104 ns string,
105 cli client.Client,
106 c http.Client,
107 port uint16,
108 ) {
109 ctx, cancel := context.WithCancel(context.Background())
110 defer cancel()
111
112 By("waiting on e2e helper ready")
113 err := util.WaitE2EHelperReady(c, port)
114 framework.ExpectNoError(err, "wait e2e helper ready error")
115 By("create http abort chaos CRD objects")
116
117 abort := true
118
119 httpChaos := &v1alpha1.HTTPChaos{
120 ObjectMeta: metav1.ObjectMeta{
121 Name: "http-chaos",
122 Namespace: ns,
123 },
124 Spec: v1alpha1.HTTPChaosSpec{
125 PodSelector: v1alpha1.PodSelector{
126 Selector: v1alpha1.PodSelectorSpec{
127 Namespaces: []string{ns},
128 LabelSelectors: map[string]string{"app": "http"},
129 },
130 Mode: v1alpha1.OnePodMode,
131 },
132 Port: 8080,
133 Target: "Request",
134 PodHttpChaosActions: v1alpha1.PodHttpChaosActions{
135 Abort: &abort,
136 },
137 },
138 }
139
140 err = cli.Create(ctx, httpChaos)
141 framework.ExpectNoError(err, "error occurs while applying http chaos")
142
143 chaosKey := types.NamespacedName{
144 Namespace: ns,
145 Name: "http-chaos",
146 }
147
148 By("waiting for assertion http chaos")
149 err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
150 chaos := &v1alpha1.HTTPChaos{}
151 err = cli.Get(ctx, chaosKey, chaos)
152 framework.ExpectNoError(err, "get http chaos error")
153
154 for _, c := range chaos.GetStatus().Conditions {
155 if c.Type == v1alpha1.ConditionAllInjected {
156 if c.Status != corev1.ConditionTrue {
157 return false, nil
158 }
159 } else if c.Type == v1alpha1.ConditionSelected {
160 if c.Status != corev1.ConditionTrue {
161 return false, nil
162 }
163 }
164 }
165
166 _, err := getPodHttpNoBody(c, port)
167
168
169 if err != nil {
170 return true, nil
171 }
172 return false, nil
173 })
174 framework.ExpectNoError(err, "http chaos doesn't work as expected")
175
176 By("pause http abort chaos experiment")
177
178 err = util.PauseChaos(ctx, cli, httpChaos)
179 framework.ExpectNoError(err, "pause chaos error")
180
181 By("waiting for assertion about pause")
182 err = wait.Poll(1*time.Second, 1*time.Minute, func() (done bool, err error) {
183 chaos := &v1alpha1.HTTPChaos{}
184 err = cli.Get(ctx, chaosKey, chaos)
185 framework.ExpectNoError(err, "get http chaos error")
186
187 for _, c := range chaos.GetStatus().Conditions {
188 if c.Type == v1alpha1.ConditionAllRecovered {
189 if c.Status != corev1.ConditionTrue {
190 return false, nil
191 }
192 } else if c.Type == v1alpha1.ConditionSelected {
193 if c.Status != corev1.ConditionTrue {
194 return false, nil
195 }
196 }
197 }
198
199 return true, err
200 })
201 framework.ExpectNoError(err, "check paused chaos failed")
202
203
204 err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
205 _, err := getPodHttpNoBody(c, port)
206
207
208 if err != nil {
209 return false, nil
210 }
211 return true, nil
212 })
213 framework.ExpectNoError(err, "fail to recover http chaos")
214
215 By("resume http abort chaos experiment")
216
217 err = util.UnPauseChaos(ctx, cli, httpChaos)
218 framework.ExpectNoError(err, "resume chaos error")
219
220 By("assert that http abort is effective again")
221 err = wait.Poll(1*time.Second, 1*time.Minute, func() (done bool, err error) {
222 chaos := &v1alpha1.HTTPChaos{}
223 err = cli.Get(ctx, chaosKey, chaos)
224 framework.ExpectNoError(err, "get http chaos error")
225
226 for _, c := range chaos.GetStatus().Conditions {
227 if c.Type == v1alpha1.ConditionAllInjected {
228 if c.Status != corev1.ConditionTrue {
229 return false, nil
230 }
231 } else if c.Type == v1alpha1.ConditionSelected {
232 if c.Status != corev1.ConditionTrue {
233 return false, nil
234 }
235 }
236 }
237
238 return true, err
239 })
240 framework.ExpectNoError(err, "check resumed chaos failed")
241
242 err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
243 _, err := getPodHttpNoBody(c, port)
244
245
246 if err != nil {
247 return true, nil
248 }
249 return false, nil
250 })
251 framework.ExpectNoError(err, "HTTP chaos doesn't work as expected")
252
253 By("cleanup")
254
255 cli.Delete(ctx, httpChaos)
256 }
257