...

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