...

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