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