...

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