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