...

Source file src/github.com/chaos-mesh/chaos-mesh/e2e-test/e2e/chaos/dnschaos/dns.go

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

     1  // Copyright 2020 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 networkchaos
    15  
    16  import (
    17  	"context"
    18  	"fmt"
    19  	"io/ioutil"
    20  	"net/http"
    21  	"strings"
    22  	"time"
    23  
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/util/wait"
    26  	"k8s.io/klog"
    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 TestcaseDNSRandom(
    35  	ns string,
    36  	cli client.Client,
    37  	port uint16,
    38  	c http.Client,
    39  ) {
    40  	ctx, cancel := context.WithCancel(context.Background())
    41  
    42  	err := util.WaitE2EHelperReady(c, port)
    43  
    44  	effectDomainNames := []string{"not-exist-host.abc", "not_exist_host.abc", "not-exist-host.def"}
    45  
    46  	framework.ExpectNoError(err, "wait e2e helper ready error")
    47  
    48  	// get IP of a non exists host, and will get error
    49  	for _, domainName := range effectDomainNames {
    50  		_, err = testDNSServer(c, port, domainName)
    51  		framework.ExpectError(err, "test DNS server failed")
    52  	}
    53  
    54  	dnsChaos := &v1alpha1.DNSChaos{
    55  		ObjectMeta: metav1.ObjectMeta{
    56  			Name:      "dns-chaos-random",
    57  			Namespace: ns,
    58  		},
    59  		Spec: v1alpha1.DNSChaosSpec{
    60  			Action:             v1alpha1.RandomAction,
    61  			DomainNamePatterns: []string{"not-exist-?ost.*", "not_exist?host.abc", "not-exist-host.def"},
    62  			ContainerSelector: v1alpha1.ContainerSelector{
    63  				PodSelector: v1alpha1.PodSelector{
    64  					Mode: v1alpha1.AllPodMode,
    65  					Selector: v1alpha1.PodSelectorSpec{
    66  						Namespaces:     []string{ns},
    67  						LabelSelectors: map[string]string{"app": "network-peer"},
    68  					},
    69  				},
    70  			},
    71  		},
    72  	}
    73  
    74  	err = cli.Create(ctx, dnsChaos.DeepCopy())
    75  	framework.ExpectNoError(err, "create dns chaos error")
    76  
    77  	for _, domainName := range effectDomainNames {
    78  		err = wait.Poll(time.Second, 5*time.Second, func() (done bool, err error) {
    79  			// get IP of a non exists host, because chaos DNS server will return a random IP,
    80  			// so err should be nil
    81  			_, dnsErr := testDNSServer(c, port, domainName)
    82  			if dnsErr != nil {
    83  				return false, nil
    84  			}
    85  			return true, nil
    86  		})
    87  		framework.ExpectNoError(err, "test DNS server failed")
    88  	}
    89  
    90  	err = cli.Delete(ctx, dnsChaos.DeepCopy())
    91  	framework.ExpectNoError(err, "failed to delete dns chaos")
    92  
    93  	cancel()
    94  }
    95  
    96  func TestcaseDNSError(
    97  	ns string,
    98  	cli client.Client,
    99  	port uint16,
   100  	c http.Client,
   101  ) {
   102  	ctx, cancel := context.WithCancel(context.Background())
   103  
   104  	err := util.WaitE2EHelperReady(c, port)
   105  
   106  	framework.ExpectNoError(err, "wait e2e helper ready error")
   107  
   108  	effectDomainNames := []string{"chaos-mesh.org", "github.com", "163.com"}
   109  
   110  	// get IP of chaos-mesh.org, and will get no error
   111  	for _, domainName := range effectDomainNames {
   112  		_, err = testDNSServer(c, port, domainName)
   113  		framework.ExpectNoError(err, "test DNS server failed")
   114  	}
   115  
   116  	dnsChaos := &v1alpha1.DNSChaos{
   117  		ObjectMeta: metav1.ObjectMeta{
   118  			Name:      "dns-chaos-error",
   119  			Namespace: ns,
   120  		},
   121  		Spec: v1alpha1.DNSChaosSpec{
   122  			Action:             v1alpha1.ErrorAction,
   123  			DomainNamePatterns: []string{"chaos-mes?.org", "github.com", "16?.co*"},
   124  			ContainerSelector: v1alpha1.ContainerSelector{
   125  				PodSelector: v1alpha1.PodSelector{
   126  					Mode: v1alpha1.AllPodMode,
   127  					Selector: v1alpha1.PodSelectorSpec{
   128  						Namespaces:     []string{ns},
   129  						LabelSelectors: map[string]string{"app": "network-peer"},
   130  					},
   131  				},
   132  			},
   133  		},
   134  	}
   135  
   136  	err = cli.Create(ctx, dnsChaos.DeepCopy())
   137  	framework.ExpectNoError(err, "create dns chaos error")
   138  
   139  	for _, domainName := range effectDomainNames {
   140  		err = wait.Poll(time.Second, 5*time.Second, func() (done bool, err error) {
   141  			// get IP of a chaos-mesh.org, because chaos DNS server will return error,
   142  			// so err should not be nil
   143  			_, dnsErr := testDNSServer(c, port, domainName)
   144  			if dnsErr == nil {
   145  				return false, nil
   146  			}
   147  			return true, nil
   148  		})
   149  		framework.ExpectNoError(err, "test DNS server failed")
   150  	}
   151  
   152  	err = cli.Delete(ctx, dnsChaos.DeepCopy())
   153  	framework.ExpectNoError(err, "failed to delete dns chaos")
   154  
   155  	cancel()
   156  }
   157  
   158  func testDNSServer(c http.Client, port uint16, url string) (string, error) {
   159  	klog.Infof("sending request to http://localhost:%d/dns?url=%s", port, url)
   160  
   161  	resp, err := c.Get(fmt.Sprintf("http://localhost:%d/dns?url=%s", port, url))
   162  	if err != nil {
   163  		return "", err
   164  	}
   165  
   166  	out, err := ioutil.ReadAll(resp.Body)
   167  	defer resp.Body.Close()
   168  	if err != nil {
   169  		return "", err
   170  	}
   171  
   172  	result := string(out)
   173  	klog.Infof("testDNSServer result: %s", result)
   174  	if strings.Contains(result, "failed") {
   175  		return "", fmt.Errorf("test DNS server failed")
   176  	}
   177  
   178  	return result, nil
   179  }
   180