github.com/hhrutter/nomad@v0.6.0-rc2.0.20170723054333-80c4b03f0705/command/node_status_test.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/nomad/command/agent"
     9  	"github.com/hashicorp/nomad/testutil"
    10  	"github.com/mitchellh/cli"
    11  )
    12  
    13  func TestNodeStatusCommand_Implements(t *testing.T) {
    14  	t.Parallel()
    15  	var _ cli.Command = &NodeStatusCommand{}
    16  }
    17  
    18  func TestNodeStatusCommand_Self(t *testing.T) {
    19  	t.Parallel()
    20  	// Start in dev mode so we get a node registration
    21  	srv, client, url := testServer(t, true, func(c *agent.Config) {
    22  		c.NodeName = "mynode"
    23  	})
    24  	defer srv.Shutdown()
    25  
    26  	ui := new(cli.MockUi)
    27  	cmd := &NodeStatusCommand{Meta: Meta{Ui: ui}}
    28  
    29  	// Wait for a node to appear
    30  	var nodeID string
    31  	testutil.WaitForResult(func() (bool, error) {
    32  		nodes, _, err := client.Nodes().List(nil)
    33  		if err != nil {
    34  			return false, err
    35  		}
    36  		if len(nodes) == 0 {
    37  			return false, fmt.Errorf("missing node")
    38  		}
    39  		nodeID = nodes[0].ID
    40  		return true, nil
    41  	}, func(err error) {
    42  		t.Fatalf("err: %s", err)
    43  	})
    44  
    45  	// Query self node
    46  	if code := cmd.Run([]string{"-address=" + url, "-self"}); code != 0 {
    47  		t.Fatalf("expected exit 0, got: %d", code)
    48  	}
    49  	out := ui.OutputWriter.String()
    50  	if !strings.Contains(out, "mynode") {
    51  		t.Fatalf("expect to find mynode, got: %s", out)
    52  	}
    53  	if !strings.Contains(out, "No allocations placed") {
    54  		t.Fatalf("should not dump allocations")
    55  	}
    56  	ui.OutputWriter.Reset()
    57  
    58  	// Request full id output
    59  	if code := cmd.Run([]string{"-address=" + url, "-self", "-verbose"}); code != 0 {
    60  		t.Fatalf("expected exit 0, got: %d", code)
    61  	}
    62  	out = ui.OutputWriter.String()
    63  	if !strings.Contains(out, nodeID) {
    64  		t.Fatalf("expected full node id %q, got: %s", nodeID, out)
    65  	}
    66  	ui.OutputWriter.Reset()
    67  }
    68  
    69  func TestNodeStatusCommand_Run(t *testing.T) {
    70  	t.Parallel()
    71  	// Start in dev mode so we get a node registration
    72  	srv, client, url := testServer(t, true, func(c *agent.Config) {
    73  		c.NodeName = "mynode"
    74  	})
    75  	defer srv.Shutdown()
    76  
    77  	ui := new(cli.MockUi)
    78  	cmd := &NodeStatusCommand{Meta: Meta{Ui: ui}}
    79  
    80  	// Wait for a node to appear
    81  	var nodeID string
    82  	testutil.WaitForResult(func() (bool, error) {
    83  		nodes, _, err := client.Nodes().List(nil)
    84  		if err != nil {
    85  			return false, err
    86  		}
    87  		if len(nodes) == 0 {
    88  			return false, fmt.Errorf("missing node")
    89  		}
    90  		nodeID = nodes[0].ID
    91  		return true, nil
    92  	}, func(err error) {
    93  		t.Fatalf("err: %s", err)
    94  	})
    95  
    96  	// Query all node statuses
    97  	if code := cmd.Run([]string{"-address=" + url}); code != 0 {
    98  		t.Fatalf("expected exit 0, got: %d", code)
    99  	}
   100  	out := ui.OutputWriter.String()
   101  	if !strings.Contains(out, "mynode") {
   102  		t.Fatalf("expect to find mynode, got: %s", out)
   103  	}
   104  	ui.OutputWriter.Reset()
   105  
   106  	// Query a single node
   107  	if code := cmd.Run([]string{"-address=" + url, nodeID}); code != 0 {
   108  		t.Fatalf("expected exit 0, got: %d", code)
   109  	}
   110  	out = ui.OutputWriter.String()
   111  	if !strings.Contains(out, "mynode") {
   112  		t.Fatalf("expect to find mynode, got: %s", out)
   113  	}
   114  	ui.OutputWriter.Reset()
   115  
   116  	// Query single node in short view
   117  	if code := cmd.Run([]string{"-address=" + url, "-short", nodeID}); code != 0 {
   118  		t.Fatalf("expected exit 0, got: %d", code)
   119  	}
   120  	out = ui.OutputWriter.String()
   121  	if !strings.Contains(out, "mynode") {
   122  		t.Fatalf("expect to find mynode, got: %s", out)
   123  	}
   124  	if !strings.Contains(out, "No allocations placed") {
   125  		t.Fatalf("should not dump allocations")
   126  	}
   127  
   128  	// Query a single node based on prefix
   129  	if code := cmd.Run([]string{"-address=" + url, nodeID[:4]}); code != 0 {
   130  		t.Fatalf("expected exit 0, got: %d", code)
   131  	}
   132  	out = ui.OutputWriter.String()
   133  	if !strings.Contains(out, "mynode") {
   134  		t.Fatalf("expect to find mynode, got: %s", out)
   135  	}
   136  	if strings.Contains(out, nodeID) {
   137  		t.Fatalf("expected truncated node id, got: %s", out)
   138  	}
   139  	if !strings.Contains(out, nodeID[:8]) {
   140  		t.Fatalf("expected node id %q, got: %s", nodeID[:8], out)
   141  	}
   142  	ui.OutputWriter.Reset()
   143  
   144  	// Request full id output
   145  	if code := cmd.Run([]string{"-address=" + url, "-verbose", nodeID[:4]}); code != 0 {
   146  		t.Fatalf("expected exit 0, got: %d", code)
   147  	}
   148  	out = ui.OutputWriter.String()
   149  	if !strings.Contains(out, nodeID) {
   150  		t.Fatalf("expected full node id %q, got: %s", nodeID, out)
   151  	}
   152  	ui.OutputWriter.Reset()
   153  
   154  	// Identifiers with uneven length should produce a query result
   155  	if code := cmd.Run([]string{"-address=" + url, nodeID[:3]}); code != 0 {
   156  		t.Fatalf("expected exit 0, got: %d", code)
   157  	}
   158  	out = ui.OutputWriter.String()
   159  	if !strings.Contains(out, "mynode") {
   160  		t.Fatalf("expect to find mynode, got: %s", out)
   161  	}
   162  }
   163  
   164  func TestNodeStatusCommand_Fails(t *testing.T) {
   165  	t.Parallel()
   166  	srv, _, url := testServer(t, false, nil)
   167  	defer srv.Shutdown()
   168  
   169  	ui := new(cli.MockUi)
   170  	cmd := &NodeStatusCommand{Meta: Meta{Ui: ui}}
   171  
   172  	// Fails on misuse
   173  	if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 {
   174  		t.Fatalf("expected exit code 1, got: %d", code)
   175  	}
   176  	if out := ui.ErrorWriter.String(); !strings.Contains(out, cmd.Help()) {
   177  		t.Fatalf("expected help output, got: %s", out)
   178  	}
   179  	ui.ErrorWriter.Reset()
   180  
   181  	// Fails on connection failure
   182  	if code := cmd.Run([]string{"-address=nope"}); code != 1 {
   183  		t.Fatalf("expected exit code 1, got: %d", code)
   184  	}
   185  	if out := ui.ErrorWriter.String(); !strings.Contains(out, "Error querying node status") {
   186  		t.Fatalf("expected failed query error, got: %s", out)
   187  	}
   188  	ui.ErrorWriter.Reset()
   189  
   190  	// Fails on non-existent node
   191  	if code := cmd.Run([]string{"-address=" + url, "12345678-abcd-efab-cdef-123456789abc"}); code != 1 {
   192  		t.Fatalf("expected exit 1, got: %d", code)
   193  	}
   194  	if out := ui.ErrorWriter.String(); !strings.Contains(out, "No node(s) with prefix") {
   195  		t.Fatalf("expected not found error, got: %s", out)
   196  	}
   197  	ui.ErrorWriter.Reset()
   198  
   199  	// Fail on identifier with too few characters
   200  	if code := cmd.Run([]string{"-address=" + url, "1"}); code != 1 {
   201  		t.Fatalf("expected exit 1, got: %d", code)
   202  	}
   203  	if out := ui.ErrorWriter.String(); !strings.Contains(out, "must contain at least two characters.") {
   204  		t.Fatalf("expected too few characters error, got: %s", out)
   205  	}
   206  	ui.ErrorWriter.Reset()
   207  
   208  	// Failed on both -json and -t options are specified
   209  	if code := cmd.Run([]string{"-address=" + url, "-json", "-t", "{{.ID}}"}); code != 1 {
   210  		t.Fatalf("expected exit 1, got: %d", code)
   211  	}
   212  	if out := ui.ErrorWriter.String(); !strings.Contains(out, "Both json and template formatting are not allowed") {
   213  		t.Fatalf("expected getting formatter error, got: %s", out)
   214  	}
   215  }