...

Source file src/github.com/linkerd/linkerd2/test/integration/viz/edges/edges_test.go

Documentation: github.com/linkerd/linkerd2/test/integration/viz/edges

     1  package edges
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"os"
     8  	"regexp"
     9  	"strings"
    10  	"testing"
    11  	"text/template"
    12  	"time"
    13  
    14  	"github.com/linkerd/linkerd2/testutil"
    15  )
    16  
    17  var TestHelper *testutil.TestHelper
    18  
    19  func TestMain(m *testing.M) {
    20  	TestHelper = testutil.NewTestHelper()
    21  	// Block test execution until viz extension is running
    22  	TestHelper.WaitUntilDeployReady(testutil.LinkerdVizDeployReplicas)
    23  	os.Exit(m.Run())
    24  }
    25  
    26  // TestEdges requires that there has been traffic recently between linkerd-web
    27  // and linkerd-controller for edges to have been registered, which is the
    28  // case when running this test in the context of the other integration tests.
    29  
    30  func TestEdges(t *testing.T) {
    31  	ns := TestHelper.GetLinkerdNamespace()
    32  	promNs := TestHelper.GetVizNamespace()
    33  	vars := struct {
    34  		Ns     string
    35  		PromNs string
    36  	}{ns, promNs}
    37  
    38  	var b bytes.Buffer
    39  	tpl := template.Must(template.ParseFiles("testdata/linkerd_edges.golden"))
    40  	if err := tpl.Execute(&b, vars); err != nil {
    41  		t.Fatalf("failed to parse linkerd_edges.golden template: %s", err)
    42  	}
    43  
    44  	timeout := 50 * time.Second
    45  	cmd := []string{
    46  		"edges",
    47  		"-n", ns,
    48  		"deploy",
    49  		"-ojson",
    50  	}
    51  	r := regexp.MustCompile(b.String())
    52  	err := testutil.RetryFor(timeout, func() error {
    53  		out, err := TestHelper.LinkerdRun(cmd...)
    54  		if err != nil {
    55  			t.Fatal(err)
    56  		}
    57  		pods, err := TestHelper.Kubectl("", []string{"get", "pods", "-A"}...)
    58  		if err != nil {
    59  			return err
    60  		}
    61  		if !r.MatchString(out) {
    62  			t.Errorf("Expected output:\n%s\nactual:\n%s\nAll pods: %s", b.String(), out, pods)
    63  		}
    64  		return nil
    65  	})
    66  	if err != nil {
    67  		testutil.AnnotatedError(t, fmt.Sprintf("timed-out checking edges (%s)", timeout), err)
    68  	}
    69  }
    70  
    71  // TestDirectEdges deploys a terminus and then generates a load generator which
    72  // sends traffic directly to the pod ip of the terminus pod.
    73  func TestDirectEdges(t *testing.T) {
    74  
    75  	ctx := context.Background()
    76  	// setup
    77  	TestHelper.WithDataPlaneNamespace(ctx, "direct-edges-test", map[string]string{}, t, func(t *testing.T, testNamespace string) {
    78  
    79  		// inject terminus
    80  
    81  		out, err := TestHelper.LinkerdRun("inject", "--manual", "testdata/terminus.yaml")
    82  		if err != nil {
    83  			testutil.AnnotatedFatalf(t, "'linkerd inject' command failed", "'linkerd inject' command failed: %s", err)
    84  		}
    85  
    86  		// deploy terminus
    87  
    88  		out, err = TestHelper.KubectlApply(out, testNamespace)
    89  		if err != nil {
    90  			testutil.AnnotatedFatalf(t, "kubectl apply command failed", "kubectl apply command failed\n%s", out)
    91  		}
    92  
    93  		if err := TestHelper.CheckPods(ctx, testNamespace, "terminus", 1); err != nil {
    94  			//nolint:errorlint
    95  			if rce, ok := err.(*testutil.RestartCountError); ok {
    96  				testutil.AnnotatedWarn(t, "CheckPods timed-out", rce)
    97  			} else {
    98  				testutil.AnnotatedError(t, "CheckPods timed-out", err)
    99  			}
   100  		}
   101  
   102  		// get terminus pod ip
   103  
   104  		ip, err := TestHelper.Kubectl("", "-n", testNamespace, "get", "pod", "-ojsonpath=\"{.items[*].status.podIP}\"")
   105  		if err != nil {
   106  			testutil.AnnotatedError(t, "'kubectl get pod' command failed", err)
   107  		}
   108  		ip = strings.Trim(ip, "\"") // strip quotes
   109  
   110  		b, err := os.ReadFile("testdata/slow-cooker.yaml")
   111  		if err != nil {
   112  			testutil.AnnotatedError(t, "error reading file slow-cooker.yaml", err)
   113  		}
   114  
   115  		slowcooker := string(b)
   116  		slowcooker = strings.ReplaceAll(slowcooker, "___TERMINUS_POD_IP___", ip)
   117  
   118  		// inject slow cooker
   119  
   120  		out, stderr, err := TestHelper.PipeToLinkerdRun(slowcooker, "inject", "--manual", "-")
   121  		if err != nil {
   122  			testutil.AnnotatedFatalf(t, "'linkerd 'inject' command failed", "'linkerd %s' command failed with %s: %s\n", "inject", err.Error(), stderr)
   123  		}
   124  
   125  		// deploy slow cooker
   126  
   127  		out, err = TestHelper.KubectlApply(out, testNamespace)
   128  		if err != nil {
   129  			testutil.AnnotatedFatalf(t, "kubectl apply command failed", "kubectl apply command failed\n%s", out)
   130  		}
   131  
   132  		if err := TestHelper.CheckPods(ctx, testNamespace, "slow-cooker", 1); err != nil {
   133  			//nolint:errorlint
   134  			if rce, ok := err.(*testutil.RestartCountError); ok {
   135  				testutil.AnnotatedWarn(t, "CheckPods timed-out", rce)
   136  			} else {
   137  				testutil.AnnotatedError(t, "CheckPods timed-out", err)
   138  			}
   139  		}
   140  
   141  		// check edges
   142  		timeout := 50 * time.Second
   143  		testDataPath := "testdata"
   144  		err = testutil.RetryFor(timeout, func() error {
   145  			out, err = TestHelper.LinkerdRun("-n", testNamespace, "-o", "json", "viz", "edges", "deploy")
   146  			if err != nil {
   147  				return err
   148  			}
   149  
   150  			tpl := template.Must(template.ParseFiles(testDataPath + "/direct_edges.golden"))
   151  			vars := struct {
   152  				Ns    string
   153  				VizNs string
   154  			}{
   155  				testNamespace,
   156  				TestHelper.GetVizNamespace(),
   157  			}
   158  			var buf bytes.Buffer
   159  			if err := tpl.Execute(&buf, vars); err != nil {
   160  				return fmt.Errorf("failed to parse direct_edges.golden template: %w", err)
   161  			}
   162  
   163  			pods, err := TestHelper.Kubectl("", []string{"get", "pods", "-A"}...)
   164  			if err != nil {
   165  				return err
   166  			}
   167  
   168  			r := regexp.MustCompile(buf.String())
   169  			if !r.MatchString(out) {
   170  				return fmt.Errorf("Expected output:\n%s\nactual:\n%s\nAll pods: %s", buf.String(), out, pods)
   171  			}
   172  			return nil
   173  		})
   174  
   175  		if err != nil {
   176  			testutil.AnnotatedError(t, fmt.Sprintf("timed-out checking edges (%s)", timeout), err)
   177  		}
   178  	})
   179  
   180  }
   181  

View as plain text