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