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