...

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