...

Source file src/github.com/chaos-mesh/chaos-mesh/e2e-test/e2e/chaos/httpchaos/http_delay.go

Documentation: github.com/chaos-mesh/chaos-mesh/e2e-test/e2e/chaos/httpchaos

     1  // Copyright 2021 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  // http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    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/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 TestcaseHttpDelayDurationForATimeThenRecover(
    36  	ns string,
    37  	cli client.Client,
    38  	c HTTPE2EClient,
    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.WaitHTTPE2EHelperReady(*c.C, c.IP, port)
    46  	framework.ExpectNoError(err, "wait e2e helper ready error")
    47  	By("create http delay chaos CRD objects")
    48  
    49  	delay := "1s"
    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  				Delay: &delay,
    70  			},
    71  		},
    72  	}
    73  	err = cli.Create(ctx, httpChaos)
    74  	framework.ExpectNoError(err, "create http chaos error")
    75  
    76  	By("waiting for assertion HTTP delay")
    77  	err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
    78  		resp, dur, err := getPodHttpDelay(c, port)
    79  		if err != nil {
    80  			return false, err
    81  		}
    82  		second := dur.Seconds()
    83  		klog.Infof("Status(%d): get http delay %fs", resp.StatusCode, second)
    84  		// IO Delay >= 1s
    85  		if second >= 1 {
    86  			return true, nil
    87  		}
    88  		return false, nil
    89  	})
    90  	framework.ExpectNoError(err, "http chaos doesn't work as expected")
    91  	By("apply http chaos successfully")
    92  
    93  	By("delete chaos CRD objects")
    94  	// delete chaos CRD
    95  	err = cli.Delete(ctx, httpChaos)
    96  	framework.ExpectNoError(err, "failed to delete http chaos")
    97  
    98  	time.Sleep(time.Second * 5)
    99  
   100  	By("waiting for assertion recovering")
   101  	err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
   102  		resp, dur, err := getPodHttpDelay(c, port)
   103  		if err != nil {
   104  			return false, err
   105  		}
   106  		second := dur.Seconds()
   107  		klog.Infof("Status(%d): get http delay %fs", resp.StatusCode, second)
   108  		// IO Delay shouldn't longer than 1s
   109  		if second >= 1 {
   110  			return false, nil
   111  		}
   112  		return true, nil
   113  	})
   114  	framework.ExpectNoError(err, "fail to recover http chaos")
   115  }
   116  
   117  func TestcaseHttpDelayDurationForATimePauseAndUnPause(
   118  	ns string,
   119  	cli client.Client,
   120  	c HTTPE2EClient,
   121  	port uint16,
   122  ) {
   123  	ctx, cancel := context.WithCancel(context.Background())
   124  	defer cancel()
   125  
   126  	By("waiting on e2e helper ready")
   127  	err := util.WaitHTTPE2EHelperReady(*c.C, c.IP, port)
   128  	framework.ExpectNoError(err, "wait e2e helper ready error")
   129  	By("create http delay chaos CRD objects")
   130  
   131  	delay := "1s"
   132  
   133  	httpChaos := &v1alpha1.HTTPChaos{
   134  		ObjectMeta: metav1.ObjectMeta{
   135  			Name:      "http-chaos",
   136  			Namespace: ns,
   137  		},
   138  		Spec: v1alpha1.HTTPChaosSpec{
   139  			PodSelector: v1alpha1.PodSelector{
   140  				Selector: v1alpha1.PodSelectorSpec{
   141  					GenericSelectorSpec: v1alpha1.GenericSelectorSpec{
   142  						Namespaces:     []string{ns},
   143  						LabelSelectors: map[string]string{"app": "http"},
   144  					},
   145  				},
   146  				Mode: v1alpha1.OneMode,
   147  			},
   148  			Port:   8080,
   149  			Target: "Request",
   150  			PodHttpChaosActions: v1alpha1.PodHttpChaosActions{
   151  				Delay: &delay,
   152  			},
   153  		},
   154  	}
   155  
   156  	err = cli.Create(ctx, httpChaos)
   157  	framework.ExpectNoError(err, "error occurs while applying http chaos")
   158  
   159  	chaosKey := types.NamespacedName{
   160  		Namespace: ns,
   161  		Name:      "http-chaos",
   162  	}
   163  
   164  	By("waiting for assertion http chaos")
   165  	err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
   166  		chaos := &v1alpha1.HTTPChaos{}
   167  		err = cli.Get(ctx, chaosKey, chaos)
   168  		framework.ExpectNoError(err, "get http chaos error")
   169  
   170  		for _, c := range chaos.GetStatus().Conditions {
   171  			if c.Type == v1alpha1.ConditionAllInjected {
   172  				if c.Status != corev1.ConditionTrue {
   173  					return false, nil
   174  				}
   175  			} else if c.Type == v1alpha1.ConditionSelected {
   176  				if c.Status != corev1.ConditionTrue {
   177  					return false, nil
   178  				}
   179  			}
   180  		}
   181  
   182  		_, dur, _ := getPodHttpDelay(c, port)
   183  
   184  		s := dur.Seconds()
   185  		klog.Infof("get http delay %fs", s)
   186  		// HTTP Delay >= 1s
   187  		if s >= 1 {
   188  			return true, nil
   189  		}
   190  		return false, nil
   191  	})
   192  	framework.ExpectNoError(err, "http chaos doesn't work as expected")
   193  
   194  	By("pause http delay chaos experiment")
   195  	// pause experiment
   196  	err = util.PauseChaos(ctx, cli, httpChaos)
   197  	framework.ExpectNoError(err, "pause chaos error")
   198  
   199  	By("waiting for assertion about pause")
   200  	err = wait.Poll(1*time.Second, 1*time.Minute, func() (done bool, err error) {
   201  		chaos := &v1alpha1.HTTPChaos{}
   202  		err = cli.Get(ctx, chaosKey, chaos)
   203  		framework.ExpectNoError(err, "get http chaos error")
   204  
   205  		for _, c := range chaos.GetStatus().Conditions {
   206  			if c.Type == v1alpha1.ConditionAllRecovered {
   207  				if c.Status != corev1.ConditionTrue {
   208  					return false, nil
   209  				}
   210  			} else if c.Type == v1alpha1.ConditionSelected {
   211  				if c.Status != corev1.ConditionTrue {
   212  					return false, nil
   213  				}
   214  			}
   215  		}
   216  
   217  		return true, err
   218  	})
   219  	framework.ExpectNoError(err, "check paused chaos failed")
   220  
   221  	// wait 1 min to check whether io delay still exists
   222  	err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
   223  		_, dur, _ := getPodHttpDelay(c, port)
   224  
   225  		s := dur.Seconds()
   226  		klog.Infof("get http delay %fs", s)
   227  		// HTTP Delay >= 1s
   228  		if s >= 1 {
   229  			return false, nil
   230  		}
   231  		return true, nil
   232  	})
   233  	framework.ExpectNoError(err, "fail to recover http chaos")
   234  
   235  	By("resume http delay chaos experiment")
   236  	// resume experiment
   237  	err = util.UnPauseChaos(ctx, cli, httpChaos)
   238  	framework.ExpectNoError(err, "resume chaos error")
   239  
   240  	By("assert that http delay is effective again")
   241  	err = wait.Poll(1*time.Second, 1*time.Minute, func() (done bool, err error) {
   242  		chaos := &v1alpha1.HTTPChaos{}
   243  		err = cli.Get(ctx, chaosKey, chaos)
   244  		framework.ExpectNoError(err, "get http chaos error")
   245  
   246  		for _, c := range chaos.GetStatus().Conditions {
   247  			if c.Type == v1alpha1.ConditionAllInjected {
   248  				if c.Status != corev1.ConditionTrue {
   249  					return false, nil
   250  				}
   251  			} else if c.Type == v1alpha1.ConditionSelected {
   252  				if c.Status != corev1.ConditionTrue {
   253  					return false, nil
   254  				}
   255  			}
   256  		}
   257  
   258  		return true, err
   259  	})
   260  	framework.ExpectNoError(err, "check resumed chaos failed")
   261  
   262  	err = wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
   263  		_, dur, _ := getPodHttpDelay(c, port)
   264  
   265  		s := dur.Seconds()
   266  		klog.Infof("get http delay %fs", s)
   267  		// HTTP Delay >= 1s
   268  		if s >= 1 {
   269  			return true, nil
   270  		}
   271  		return false, nil
   272  	})
   273  	framework.ExpectNoError(err, "HTTP chaos doesn't work as expected")
   274  
   275  	By("cleanup")
   276  	// cleanup
   277  	cli.Delete(ctx, httpChaos)
   278  }
   279