github.com/DerekStrickland/consul@v1.4.5/command/agent/agent_test.go (about)

     1  package agent
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/exec"
     7  	"path/filepath"
     8  	"strings"
     9  	"sync"
    10  	"testing"
    11  
    12  	"github.com/hashicorp/consul/testrpc"
    13  
    14  	"github.com/hashicorp/consul/agent"
    15  	"github.com/hashicorp/consul/testutil"
    16  	"github.com/hashicorp/consul/testutil/retry"
    17  	"github.com/hashicorp/consul/version"
    18  	"github.com/mitchellh/cli"
    19  )
    20  
    21  // TestConfigFail should test command line flags that lead to an immediate error.
    22  func TestConfigFail(t *testing.T) {
    23  	t.Parallel()
    24  
    25  	dataDir := testutil.TempDir(t, "consul")
    26  	defer os.RemoveAll(dataDir)
    27  
    28  	tests := []struct {
    29  		args []string
    30  		out  string
    31  	}{
    32  		{
    33  			args: []string{"agent", "-server", "-bind=10.0.0.1", "-datacenter="},
    34  			out:  "==> datacenter cannot be empty\n",
    35  		},
    36  		{
    37  			args: []string{"agent", "-server", "-bind=10.0.0.1", "-datacenter=foo", "some-other-arg"},
    38  			out:  "==> config: Unknown extra arguments: [some-other-arg]\n",
    39  		},
    40  		{
    41  			args: []string{"agent", "-server", "-bind=10.0.0.1"},
    42  			out:  "==> data_dir cannot be empty\n",
    43  		},
    44  		{
    45  			args: []string{"agent", "-server", "-data-dir", dataDir, "-advertise", "0.0.0.0", "-bind", "10.0.0.1"},
    46  			out:  "==> Advertise address cannot be 0.0.0.0, :: or [::]\n",
    47  		},
    48  		{
    49  			args: []string{"agent", "-server", "-data-dir", dataDir, "-advertise", "::", "-bind", "10.0.0.1"},
    50  			out:  "==> Advertise address cannot be 0.0.0.0, :: or [::]\n",
    51  		},
    52  		{
    53  			args: []string{"agent", "-server", "-data-dir", dataDir, "-advertise", "[::]", "-bind", "10.0.0.1"},
    54  			out:  "==> Advertise address cannot be 0.0.0.0, :: or [::]\n",
    55  		},
    56  		{
    57  			args: []string{"agent", "-server", "-data-dir", dataDir, "-advertise-wan", "0.0.0.0", "-bind", "10.0.0.1"},
    58  			out:  "==> Advertise WAN address cannot be 0.0.0.0, :: or [::]\n",
    59  		},
    60  		{
    61  			args: []string{"agent", "-server", "-data-dir", dataDir, "-advertise-wan", "::", "-bind", "10.0.0.1"},
    62  			out:  "==> Advertise WAN address cannot be 0.0.0.0, :: or [::]\n",
    63  		},
    64  		{
    65  			args: []string{"agent", "-server", "-data-dir", dataDir, "-advertise-wan", "[::]", "-bind", "10.0.0.1"},
    66  			out:  "==> Advertise WAN address cannot be 0.0.0.0, :: or [::]\n",
    67  		},
    68  	}
    69  
    70  	for _, tt := range tests {
    71  		t.Run(strings.Join(tt.args, " "), func(t *testing.T) {
    72  			cmd := exec.Command("consul", tt.args...)
    73  			b, err := cmd.CombinedOutput()
    74  			if got, want := err, "exit status 1"; got == nil || got.Error() != want {
    75  				t.Fatalf("got err %q want %q", got, want)
    76  			}
    77  			if got, want := string(b), tt.out; got != want {
    78  				t.Fatalf("got %q want %q", got, want)
    79  			}
    80  		})
    81  	}
    82  }
    83  
    84  func TestRetryJoin(t *testing.T) {
    85  	t.Parallel()
    86  	a := agent.NewTestAgent(t, t.Name(), "")
    87  	defer a.Shutdown()
    88  	testrpc.WaitForLeader(t, a.RPC, "dc1")
    89  
    90  	shutdownCh := make(chan struct{})
    91  
    92  	var wg sync.WaitGroup
    93  	wg.Add(1)
    94  	go func() {
    95  		defer wg.Done()
    96  
    97  		tmpDir := testutil.TempDir(t, "consul")
    98  		defer os.RemoveAll(tmpDir)
    99  
   100  		args := []string{
   101  			"-server",
   102  			"-bind", a.Config.BindAddr.String(),
   103  			"-data-dir", tmpDir,
   104  			"-node", "Node 11111111-1111-1111-1111-111111111111",
   105  			"-node-id", "11111111-1111-1111-1111-111111111111",
   106  			"-advertise", a.Config.BindAddr.String(),
   107  			"-retry-join", a.Config.SerfBindAddrLAN.String(),
   108  			"-retry-interval", "1s",
   109  			"-retry-join-wan", a.Config.SerfBindAddrWAN.String(),
   110  			"-retry-interval-wan", "1s",
   111  		}
   112  
   113  		ui := cli.NewMockUi()
   114  		cmd := New(ui, "", version.Version, "", "", shutdownCh)
   115  		// closing shutdownCh triggers a SIGINT which triggers shutdown without leave
   116  		// which will return 1
   117  		if code := cmd.Run(args); code != 1 {
   118  			t.Log(ui.ErrorWriter.String())
   119  			t.Fatalf("bad: %d", code)
   120  		}
   121  	}()
   122  
   123  	retry.Run(t, func(r *retry.R) {
   124  		if got, want := len(a.LANMembers()), 2; got != want {
   125  			r.Fatalf("got %d LAN members want %d", got, want)
   126  		}
   127  		if got, want := len(a.WANMembers()), 2; got != want {
   128  			r.Fatalf("got %d WAN members want %d", got, want)
   129  		}
   130  	})
   131  
   132  	close(shutdownCh)
   133  	wg.Wait()
   134  }
   135  
   136  func TestRetryJoinFail(t *testing.T) {
   137  	t.Parallel()
   138  	tmpDir := testutil.TempDir(t, "consul")
   139  	defer os.RemoveAll(tmpDir)
   140  
   141  	ui := cli.NewMockUi()
   142  	cmd := New(ui, "", "", "", "", nil)
   143  
   144  	args := []string{
   145  		"-bind", "127.0.0.1",
   146  		"-data-dir", tmpDir,
   147  		"-retry-join", "127.0.0.1:99",
   148  		"-retry-max", "1",
   149  		"-retry-interval", "10ms",
   150  	}
   151  
   152  	if code := cmd.Run(args); code == 0 {
   153  		t.Fatalf("bad: %d", code)
   154  	}
   155  }
   156  
   157  func TestRetryJoinWanFail(t *testing.T) {
   158  	t.Parallel()
   159  	tmpDir := testutil.TempDir(t, "consul")
   160  	defer os.RemoveAll(tmpDir)
   161  
   162  	ui := cli.NewMockUi()
   163  	cmd := New(ui, "", "", "", "", nil)
   164  
   165  	args := []string{
   166  		"-server",
   167  		"-bind", "127.0.0.1",
   168  		"-data-dir", tmpDir,
   169  		"-retry-join-wan", "127.0.0.1:99",
   170  		"-retry-max-wan", "1",
   171  		"-retry-interval-wan", "10ms",
   172  	}
   173  
   174  	if code := cmd.Run(args); code == 0 {
   175  		t.Fatalf("bad: %d", code)
   176  	}
   177  }
   178  
   179  func TestProtectDataDir(t *testing.T) {
   180  	t.Parallel()
   181  	dir := testutil.TempDir(t, "consul")
   182  	defer os.RemoveAll(dir)
   183  
   184  	if err := os.MkdirAll(filepath.Join(dir, "mdb"), 0700); err != nil {
   185  		t.Fatalf("err: %v", err)
   186  	}
   187  
   188  	cfgDir := testutil.TempDir(t, "consul-config")
   189  	defer os.RemoveAll(cfgDir)
   190  
   191  	cfgFilePath := filepath.Join(cfgDir, "consul.json")
   192  	cfgFile, err := os.Create(cfgFilePath)
   193  	if err != nil {
   194  		t.Fatalf("Unable to create file %v, got error:%v", cfgFilePath, err)
   195  	}
   196  
   197  	content := fmt.Sprintf(`{"server": true, "bind_addr" : "10.0.0.1", "data_dir": "%s"}`, dir)
   198  	_, err = cfgFile.Write([]byte(content))
   199  	if err != nil {
   200  		t.Fatalf("err: %v", err)
   201  	}
   202  
   203  	ui := cli.NewMockUi()
   204  	cmd := New(ui, "", "", "", "", nil)
   205  	args := []string{"-config-file=" + cfgFile.Name()}
   206  	if code := cmd.Run(args); code == 0 {
   207  		t.Fatalf("should fail")
   208  	}
   209  	if out := ui.ErrorWriter.String(); !strings.Contains(out, dir) {
   210  		t.Fatalf("expected mdb dir error, got: %s", out)
   211  	}
   212  }
   213  
   214  func TestBadDataDirPermissions(t *testing.T) {
   215  	t.Parallel()
   216  	dir := testutil.TempDir(t, "consul")
   217  	defer os.RemoveAll(dir)
   218  
   219  	dataDir := filepath.Join(dir, "mdb")
   220  	if err := os.MkdirAll(dataDir, 0400); err != nil {
   221  		t.Fatalf("err: %v", err)
   222  	}
   223  	defer os.RemoveAll(dataDir)
   224  
   225  	ui := cli.NewMockUi()
   226  	cmd := New(ui, "", "", "", "", nil)
   227  	args := []string{"-data-dir=" + dataDir, "-server=true", "-bind=10.0.0.1"}
   228  	if code := cmd.Run(args); code == 0 {
   229  		t.Fatalf("Should fail with bad data directory permissions")
   230  	}
   231  	if out := ui.ErrorWriter.String(); !strings.Contains(out, "Permission denied") {
   232  		t.Fatalf("expected permission denied error, got: %s", out)
   233  	}
   234  }