...

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