github.com/criteo-forks/consul@v1.4.5-criteonogrpc/command/rtt/rtt_test.go (about)

     1  package rtt
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/consul/testrpc"
     9  
    10  	"github.com/hashicorp/consul/agent"
    11  	"github.com/hashicorp/consul/agent/structs"
    12  	"github.com/hashicorp/consul/testutil/retry"
    13  	"github.com/hashicorp/serf/coordinate"
    14  	"github.com/mitchellh/cli"
    15  )
    16  
    17  func TestRTTCommand_noTabs(t *testing.T) {
    18  	t.Parallel()
    19  	if strings.ContainsRune(New(cli.NewMockUi()).Help(), '\t') {
    20  		t.Fatal("help has tabs")
    21  	}
    22  }
    23  
    24  func TestRTTCommand_BadArgs(t *testing.T) {
    25  	t.Parallel()
    26  	tests := []struct {
    27  		args []string
    28  	}{
    29  		{args: []string{}},
    30  		{args: []string{"node1", "node2", "node3"}},
    31  		{args: []string{"-wan", "node1", "node2"}},
    32  		{args: []string{"-wan", "node1.dc1", "node2"}},
    33  		{args: []string{"-wan", "node1", "node2.dc1"}},
    34  	}
    35  
    36  	for _, tt := range tests {
    37  		t.Run(strings.Join(tt.args, " "), func(t *testing.T) {
    38  			ui := cli.NewMockUi()
    39  			c := New(ui)
    40  			if code := c.Run(tt.args); code != 1 {
    41  				t.Fatalf("expected return code 1, got %d", code)
    42  			}
    43  		})
    44  	}
    45  }
    46  
    47  func TestRTTCommand_LAN(t *testing.T) {
    48  	t.Parallel()
    49  	a := agent.NewTestAgent(t, t.Name(), `
    50  		consul = {
    51  			coordinate = {
    52  				update_period = "10ms"
    53  			}
    54  		}
    55  	`)
    56  	defer a.Shutdown()
    57  	testrpc.WaitForLeader(t, a.RPC, "dc1")
    58  
    59  	// Inject some known coordinates.
    60  	c1 := coordinate.NewCoordinate(coordinate.DefaultConfig())
    61  	c2 := c1.Clone()
    62  	c2.Vec[0] = 0.123
    63  	distStr := fmt.Sprintf("%.3f ms", c1.DistanceTo(c2).Seconds()*1000.0)
    64  	{
    65  		req := structs.CoordinateUpdateRequest{
    66  			Datacenter: a.Config.Datacenter,
    67  			Node:       a.Config.NodeName,
    68  			Coord:      c1,
    69  		}
    70  		var reply struct{}
    71  		if err := a.RPC("Coordinate.Update", &req, &reply); err != nil {
    72  			t.Fatalf("err: %s", err)
    73  		}
    74  	}
    75  	{
    76  		req := structs.RegisterRequest{
    77  			Datacenter: a.Config.Datacenter,
    78  			Node:       "dogs",
    79  			Address:    "127.0.0.2",
    80  		}
    81  		var reply struct{}
    82  		if err := a.RPC("Catalog.Register", &req, &reply); err != nil {
    83  			t.Fatalf("err: %s", err)
    84  		}
    85  	}
    86  	{
    87  		var reply struct{}
    88  		req := structs.CoordinateUpdateRequest{
    89  			Datacenter: a.Config.Datacenter,
    90  			Node:       "dogs",
    91  			Coord:      c2,
    92  		}
    93  		if err := a.RPC("Coordinate.Update", &req, &reply); err != nil {
    94  			t.Fatalf("err: %s", err)
    95  		}
    96  	}
    97  
    98  	// Ask for the RTT of two known nodes
    99  	ui := cli.NewMockUi()
   100  	c := New(ui)
   101  	args := []string{
   102  		"-http-addr=" + a.HTTPAddr(),
   103  		a.Config.NodeName,
   104  		"dogs",
   105  	}
   106  	// Wait for the updates to get flushed to the data store.
   107  	retry.Run(t, func(r *retry.R) {
   108  		code := c.Run(args)
   109  		if code != 0 {
   110  			r.Fatalf("bad: %d: %#v", code, ui.ErrorWriter.String())
   111  		}
   112  
   113  		// Make sure the proper RTT was reported in the output.
   114  		expected := fmt.Sprintf("rtt: %s", distStr)
   115  		if !strings.Contains(ui.OutputWriter.String(), expected) {
   116  			r.Fatalf("bad: %#v", ui.OutputWriter.String())
   117  		}
   118  	})
   119  
   120  	// Default to the agent's node.
   121  	{
   122  		ui := cli.NewMockUi()
   123  		c := New(ui)
   124  		args := []string{
   125  			"-http-addr=" + a.HTTPAddr(),
   126  			"dogs",
   127  		}
   128  		code := c.Run(args)
   129  		if code != 0 {
   130  			t.Fatalf("bad: %d: %#v", code, ui.ErrorWriter.String())
   131  		}
   132  
   133  		// Make sure the proper RTT was reported in the output.
   134  		expected := fmt.Sprintf("rtt: %s", distStr)
   135  		if !strings.Contains(ui.OutputWriter.String(), expected) {
   136  			t.Fatalf("bad: %#v", ui.OutputWriter.String())
   137  		}
   138  	}
   139  
   140  	// Try an unknown node.
   141  	{
   142  		ui := cli.NewMockUi()
   143  		c := New(ui)
   144  		args := []string{
   145  			"-http-addr=" + a.HTTPAddr(),
   146  			a.Config.NodeName,
   147  			"nope",
   148  		}
   149  		code := c.Run(args)
   150  		if code != 1 {
   151  			t.Fatalf("bad: %d: %#v", code, ui.ErrorWriter.String())
   152  		}
   153  	}
   154  }
   155  
   156  func TestRTTCommand_WAN(t *testing.T) {
   157  	t.Parallel()
   158  	a := agent.NewTestAgent(t, t.Name(), ``)
   159  	defer a.Shutdown()
   160  	testrpc.WaitForLeader(t, a.RPC, "dc1")
   161  
   162  	node := fmt.Sprintf("%s.%s", a.Config.NodeName, a.Config.Datacenter)
   163  
   164  	// We can't easily inject WAN coordinates, so we will just query the
   165  	// node with itself.
   166  	{
   167  		ui := cli.NewMockUi()
   168  		c := New(ui)
   169  		args := []string{
   170  			"-wan",
   171  			"-http-addr=" + a.HTTPAddr(),
   172  			node,
   173  			node,
   174  		}
   175  		code := c.Run(args)
   176  		if code != 0 {
   177  			t.Fatalf("bad: %d: %#v", code, ui.ErrorWriter.String())
   178  		}
   179  
   180  		// Make sure there was some kind of RTT reported in the output.
   181  		if !strings.Contains(ui.OutputWriter.String(), "rtt: ") {
   182  			t.Fatalf("bad: %#v", ui.OutputWriter.String())
   183  		}
   184  	}
   185  
   186  	// Default to the agent's node.
   187  	{
   188  		ui := cli.NewMockUi()
   189  		c := New(ui)
   190  		args := []string{
   191  			"-wan",
   192  			"-http-addr=" + a.HTTPAddr(),
   193  			node,
   194  		}
   195  		code := c.Run(args)
   196  		if code != 0 {
   197  			t.Fatalf("bad: %d: %#v", code, ui.ErrorWriter.String())
   198  		}
   199  
   200  		// Make sure there was some kind of RTT reported in the output.
   201  		if !strings.Contains(ui.OutputWriter.String(), "rtt: ") {
   202  			t.Fatalf("bad: %#v", ui.OutputWriter.String())
   203  		}
   204  	}
   205  
   206  	// Try an unknown node.
   207  	{
   208  		ui := cli.NewMockUi()
   209  		c := New(ui)
   210  		args := []string{
   211  			"-wan",
   212  			"-http-addr=" + a.HTTPAddr(),
   213  			node,
   214  			"dc1.nope",
   215  		}
   216  		code := c.Run(args)
   217  		if code != 1 {
   218  			t.Fatalf("bad: %d: %#v", code, ui.ErrorWriter.String())
   219  		}
   220  	}
   221  }