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