...

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