1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package iochaos
17
18 import (
19 "context"
20 "net/http"
21 "strings"
22 "time"
23
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 TestcaseIOErrorDurationForATimeThenRecover(
36 ns string,
37 cli client.Client,
38 c http.Client,
39 port uint16,
40 ) {
41 ctx, cancel := context.WithCancel(context.Background())
42 err := util.WaitE2EHelperReady(c, port)
43 framework.ExpectNoError(err, "wait e2e helper ready error")
44
45 ioChaos := &v1alpha1.IOChaos{
46 ObjectMeta: metav1.ObjectMeta{
47 Name: "io-chaos",
48 Namespace: ns,
49 },
50 Spec: v1alpha1.IOChaosSpec{
51 Action: v1alpha1.IoFaults,
52 VolumePath: "/var/run/data",
53 Path: "/var/run/data/*",
54 Percent: 100,
55
56 Errno: 5,
57
58 Methods: []v1alpha1.IoMethod{v1alpha1.Write},
59 ContainerSelector: v1alpha1.ContainerSelector{
60 PodSelector: v1alpha1.PodSelector{
61 Selector: v1alpha1.PodSelectorSpec{
62 GenericSelectorSpec: v1alpha1.GenericSelectorSpec{
63 Namespaces: []string{ns},
64 LabelSelectors: map[string]string{"app": "io"},
65 },
66 },
67 Mode: v1alpha1.OneMode,
68 },
69 },
70 },
71 }
72 err = cli.Create(ctx, ioChaos)
73 framework.ExpectNoError(err, "create io chaos")
74
75 err = wait.PollImmediate(5*time.Second, 1*time.Minute, func() (bool, error) {
76 _, err = getPodIODelay(c, port)
77
78 if err != nil && strings.Contains(err.Error(), "input/output error") {
79 return true, nil
80 }
81 return false, nil
82 })
83 framework.ExpectNoError(err, "io chaos doesn't work as expected")
84
85 err = cli.Delete(ctx, ioChaos)
86 framework.ExpectNoError(err, "failed to delete io chaos")
87
88 klog.Infof("success to perform io chaos")
89 err = wait.PollImmediate(5*time.Second, 1*time.Minute, func() (bool, error) {
90 _, err = getPodIODelay(c, port)
91
92 if err == nil {
93 return true, nil
94 }
95 return false, nil
96 })
97 framework.ExpectNoError(err, "fail to recover io chaos")
98
99 cancel()
100 }
101
102 func TestcaseIOErrorDurationForATimePauseAndUnPause(
103 ns string,
104 cli client.Client,
105 c http.Client,
106 port uint16,
107 ) {
108 ctx, cancel := context.WithCancel(context.Background())
109 err := util.WaitE2EHelperReady(c, port)
110 framework.ExpectNoError(err, "wait e2e helper ready error")
111
112 ioChaos := &v1alpha1.IOChaos{
113 ObjectMeta: metav1.ObjectMeta{
114 Name: "io-chaos",
115 Namespace: ns,
116 },
117 Spec: v1alpha1.IOChaosSpec{
118 Action: v1alpha1.IoFaults,
119 VolumePath: "/var/run/data",
120 Path: "/var/run/data/*",
121 Percent: 100,
122
123 Errno: 5,
124
125 Methods: []v1alpha1.IoMethod{v1alpha1.Write},
126 ContainerSelector: v1alpha1.ContainerSelector{
127 PodSelector: v1alpha1.PodSelector{
128 Selector: v1alpha1.PodSelectorSpec{
129 GenericSelectorSpec: v1alpha1.GenericSelectorSpec{
130 Namespaces: []string{ns},
131 LabelSelectors: map[string]string{"app": "io"},
132 },
133 },
134 Mode: v1alpha1.OneMode,
135 },
136 },
137 },
138 }
139 err = cli.Create(ctx, ioChaos)
140 framework.ExpectNoError(err, "create io chaos error")
141
142 klog.Info("create iochaos successfully")
143
144 err = wait.PollImmediate(5*time.Second, 1*time.Minute, func() (bool, error) {
145 _, err = getPodIODelay(c, port)
146
147 if err != nil && strings.Contains(err.Error(), "input/output error") {
148 return true, nil
149 }
150 return false, nil
151 })
152 framework.ExpectNoError(err, "io chaos doesn't work as expected")
153
154 chaosKey := types.NamespacedName{
155 Namespace: ns,
156 Name: "io-chaos",
157 }
158
159
160 err = util.PauseChaos(ctx, cli, ioChaos)
161 framework.ExpectNoError(err, "pause chaos error")
162
163 klog.Info("pause iochaos")
164
165 err = wait.Poll(5*time.Second, 5*time.Minute, func() (done bool, err error) {
166 chaos := &v1alpha1.IOChaos{}
167 err = cli.Get(ctx, chaosKey, chaos)
168 framework.ExpectNoError(err, "get io chaos error")
169 if chaos.Status.Experiment.DesiredPhase == v1alpha1.StoppedPhase {
170 return true, nil
171 }
172 return false, err
173 })
174 framework.ExpectNoError(err, "check paused chaos failed")
175
176
177 err = wait.PollImmediate(5*time.Second, 1*time.Minute, func() (bool, error) {
178 _, err = getPodIODelay(c, port)
179
180 if err == nil {
181 return true, nil
182 }
183 return false, nil
184 })
185 framework.ExpectNoError(err, "fail to recover io chaos")
186
187
188 err = util.UnPauseChaos(ctx, cli, ioChaos)
189 framework.ExpectNoError(err, "resume chaos error")
190
191 err = wait.Poll(5*time.Second, 1*time.Minute, func() (done bool, err error) {
192 chaos := &v1alpha1.IOChaos{}
193 err = cli.Get(ctx, chaosKey, chaos)
194 framework.ExpectNoError(err, "get io chaos error")
195 if chaos.Status.Experiment.DesiredPhase == v1alpha1.RunningPhase {
196 return true, nil
197 }
198 return false, err
199 })
200 framework.ExpectNoError(err, "check resumed chaos failed")
201
202 err = wait.PollImmediate(5*time.Second, 1*time.Minute, func() (bool, error) {
203 _, err = getPodIODelay(c, port)
204
205 if err != nil && strings.Contains(err.Error(), "input/output error") {
206 return true, nil
207 }
208 return false, nil
209 })
210 framework.ExpectNoError(err, "io chaos doesn't work as expected")
211
212
213 cli.Delete(ctx, ioChaos)
214 cancel()
215 }
216
217 func TestcaseIOErrorWithSpecifiedContainer(
218 ns string,
219 cli client.Client,
220 c http.Client,
221 port uint16) {
222 ctx, cancel := context.WithCancel(context.Background())
223 defer cancel()
224 err := util.WaitE2EHelperReady(c, port)
225 framework.ExpectNoError(err, "wait e2e helper ready error")
226
227 containerName := "io"
228 ioChaos := &v1alpha1.IOChaos{
229 ObjectMeta: metav1.ObjectMeta{
230 Name: "io-chaos",
231 Namespace: ns,
232 },
233 Spec: v1alpha1.IOChaosSpec{
234 Action: v1alpha1.IoFaults,
235 VolumePath: "/var/run/data",
236 Path: "/var/run/data/*",
237 Percent: 100,
238
239 Errno: 5,
240
241 Methods: []v1alpha1.IoMethod{v1alpha1.Write},
242 ContainerSelector: v1alpha1.ContainerSelector{
243 PodSelector: v1alpha1.PodSelector{
244 Selector: v1alpha1.PodSelectorSpec{
245 GenericSelectorSpec: v1alpha1.GenericSelectorSpec{
246 Namespaces: []string{ns},
247 LabelSelectors: map[string]string{"app": "io"},
248 },
249 },
250 Mode: v1alpha1.OneMode,
251 },
252 ContainerNames: []string{containerName},
253 },
254 },
255 }
256 err = cli.Create(ctx, ioChaos)
257 framework.ExpectNoError(err, "create io chaos")
258
259 err = wait.PollImmediate(5*time.Second, 1*time.Minute, func() (bool, error) {
260 _, err = getPodIODelay(c, port)
261
262 if err != nil && strings.Contains(err.Error(), "input/output error") {
263 return true, nil
264 }
265 return false, nil
266 })
267 framework.ExpectNoError(err, "io chaos doesn't work as expected")
268
269 err = cli.Delete(ctx, ioChaos)
270 framework.ExpectNoError(err, "failed to delete io chaos")
271
272 klog.Infof("success to perform io chaos")
273 err = wait.PollImmediate(5*time.Second, 1*time.Minute, func() (bool, error) {
274 _, err = getPodIODelay(c, port)
275
276 if err == nil {
277 return true, nil
278 }
279 return false, nil
280 })
281 framework.ExpectNoError(err, "fail to recover io chaos")
282 }
283