From cc4fea99fc9b5f0feff17f2e4f18fe5d531a4109 Mon Sep 17 00:00:00 2001 From: Ivo Verberk Date: Thu, 21 Jan 2016 22:21:35 +0100 Subject: [PATCH] Provide a consistent user experience with prefix based lookups. * Require at least two characters for identifier * Automatically strip off the last character in case of uneven length --- command/alloc_status.go | 10 ++++++++-- command/alloc_status_test.go | 19 +++++++++++++++---- command/monitor.go | 9 +++++++-- command/monitor_test.go | 20 ++++++++++++++------ command/node_drain.go | 9 +++++++-- command/node_drain_test.go | 17 +++++++++++++---- command/node_status.go | 9 +++++++-- command/node_status_test.go | 16 ++++++++++++---- 8 files changed, 83 insertions(+), 26 deletions(-) diff --git a/command/alloc_status.go b/command/alloc_status.go index 77ce75827..2b51c2984 100644 --- a/command/alloc_status.go +++ b/command/alloc_status.go @@ -77,10 +77,16 @@ func (c *AllocStatusCommand) Run(args []string) int { // Query the allocation info alloc, _, err := client.Allocations().Info(allocID, nil) if err != nil { - if len(allocID)%2 != 0 { - c.Ui.Error(fmt.Sprintf("Identifier (without hyphens) must be of even length.")) + if len(allocID) == 1 { + c.Ui.Error(fmt.Sprintf("Identifier must contain at least two characters.")) return 1 } + if len(allocID)%2 == 1 { + // Identifiers must be of even length, so we strip off the last byte + // to provide a consistent user experience. + allocID = allocID[:len(allocID)-1] + } + allocs, _, err := client.Allocations().PrefixList(allocID) if err != nil { c.Ui.Error(fmt.Sprintf("Error querying allocation: %v", err)) diff --git a/command/alloc_status_test.go b/command/alloc_status_test.go index 44a665e46..e8405ae46 100644 --- a/command/alloc_status_test.go +++ b/command/alloc_status_test.go @@ -43,12 +43,23 @@ func TestAllocStatusCommand_Fails(t *testing.T) { if out := ui.ErrorWriter.String(); !strings.Contains(out, "No allocation(s) with prefix or id") { t.Fatalf("expected not found error, got: %s", out) } + ui.ErrorWriter.Reset() - // Fail on uneven identifier length - if code := cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705"}); code != 1 { + // Fail on identifier with too few characters + if code := cmd.Run([]string{"-address=" + url, "2"}); code != 1 { t.Fatalf("expected exit 1, got: %d", code) } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "must be of even length.") { - t.Fatalf("expected even length error, got: %s", out) + if out := ui.ErrorWriter.String(); !strings.Contains(out, "must contain at least two characters.") { + t.Fatalf("expected too few characters error, got: %s", out) } + ui.ErrorWriter.Reset() + + // Identifiers with uneven length should produce a query result + if code := cmd.Run([]string{"-address=" + url, "123"}); code != 1 { + t.Fatalf("expected exit 1, got: %d", code) + } + if out := ui.ErrorWriter.String(); !strings.Contains(out, "No allocation(s) with prefix or id") { + t.Fatalf("expected not found error, got: %s", out) + } + } diff --git a/command/monitor.go b/command/monitor.go index 9e0b579e9..27a01b06a 100644 --- a/command/monitor.go +++ b/command/monitor.go @@ -196,10 +196,15 @@ func (m *monitor) monitor(evalID string, allowPrefix bool) int { m.ui.Error(fmt.Sprintf("No evaluation with id %q found", evalID)) return 1 } - if len(evalID)%2 != 0 { - m.ui.Error(fmt.Sprintf("Identifier (without hyphens) must be of even length.")) + if len(evalID) == 1 { + m.ui.Error(fmt.Sprintf("Identifier must contain at least two characters.")) return 1 } + if len(evalID)%2 == 1 { + // Identifiers must be of even length, so we strip off the last byte + // to provide a consistent user experience. + evalID = evalID[:len(evalID)-1] + } evals, _, err := m.client.Evaluations().PrefixList(evalID) if err != nil { diff --git a/command/monitor_test.go b/command/monitor_test.go index 68b41dc77..f200eedcb 100644 --- a/command/monitor_test.go +++ b/command/monitor_test.go @@ -324,16 +324,24 @@ func TestMonitor_MonitorWithPrefix(t *testing.T) { t.Fatalf("missing final status\n\n%s", out) } - // Test identifiers of uneven length - code = mon.monitor(evalID[:7], true) + // Fail on identifier with too few characters + code = mon.monitor(evalID[:1], true) if code != 1 { t.Fatalf("expect exit 1, got: %d", code) } - out = ui.ErrorWriter.String() - t.Logf("dus: %s", out) - if !strings.Contains(out, "must be of even length.") { - t.Fatalf("expect even length error, got %s", out) + if out := ui.ErrorWriter.String(); !strings.Contains(out, "must contain at least two characters.") { + t.Fatalf("expected too few characters error, got: %s", out) } + ui.ErrorWriter.Reset() + + code = mon.monitor(evalID[:3], true) + if code != 2 { + t.Fatalf("expect exit 2, got: %d", code) + } + if out := ui.OutputWriter.String(); !strings.Contains(out, "Monitoring evaluation") { + t.Fatalf("expected evaluation monitoring output, got: %s", out) + } + } func TestMonitor_DumpAllocStatus(t *testing.T) { diff --git a/command/node_drain.go b/command/node_drain.go index 20809022a..ec4eb95ae 100644 --- a/command/node_drain.go +++ b/command/node_drain.go @@ -71,10 +71,15 @@ func (c *NodeDrainCommand) Run(args []string) int { // Check if node exists node, _, err := client.Nodes().Info(nodeID, nil) if err != nil { - if len(nodeID)%2 != 0 { - c.Ui.Error(fmt.Sprintf("Identifier (without hyphens) must be of even length.")) + if len(nodeID) == 1 { + c.Ui.Error(fmt.Sprintf("Identifier must contain at least two characters.")) return 1 } + if len(nodeID)%2 == 1 { + // Identifiers must be of even length, so we strip off the last byte + // to provide a consistent user experience. + nodeID = nodeID[:len(nodeID)-1] + } // Exact lookup failed, try with prefix based search nodes, _, err := client.Nodes().PrefixList(nodeID) diff --git a/command/node_drain_test.go b/command/node_drain_test.go index 659b59912..30ce9a0cb 100644 --- a/command/node_drain_test.go +++ b/command/node_drain_test.go @@ -63,11 +63,20 @@ func TestNodeDrainCommand_Fails(t *testing.T) { } ui.ErrorWriter.Reset() - // Fail on uneven identifier length - if code := cmd.Run([]string{"-address=" + url, "-enable", "1234567-abcd-efab-cdef-123456789abc"}); code != 1 { + // Fail on identifier with too few characters + if code := cmd.Run([]string{"-address=" + url, "-enable", "1"}); code != 1 { t.Fatalf("expected exit 1, got: %d", code) } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "must be of even length.") { - t.Fatalf("expected even length error, got: %s", out) + if out := ui.ErrorWriter.String(); !strings.Contains(out, "must contain at least two characters.") { + t.Fatalf("expected too few characters error, got: %s", out) + } + ui.ErrorWriter.Reset() + + // Identifiers with uneven length should produce a query result + if code := cmd.Run([]string{"-address=" + url, "-enable", "123"}); code != 1 { + t.Fatalf("expected exit 1, got: %d", code) + } + if out := ui.ErrorWriter.String(); !strings.Contains(out, "No node(s) with prefix or id") { + t.Fatalf("expected not exist error, got: %s", out) } } diff --git a/command/node_status.go b/command/node_status.go index d8424ce24..042c4f307 100644 --- a/command/node_status.go +++ b/command/node_status.go @@ -110,10 +110,15 @@ func (c *NodeStatusCommand) Run(args []string) int { nodeID := args[0] node, _, err := client.Nodes().Info(nodeID, nil) if err != nil { - if len(nodeID)%2 != 0 { - c.Ui.Error(fmt.Sprintf("Identifier (without hyphens) must be of even length.")) + if len(nodeID) == 1 { + c.Ui.Error(fmt.Sprintf("Identifier must contain at least two characters.")) return 1 } + if len(nodeID)%2 == 1 { + // Identifiers must be of even length, so we strip off the last byte + // to provide a consistent user experience. + nodeID = nodeID[:len(nodeID)-1] + } // Exact lookup failed, try with prefix based search nodes, _, err := client.Nodes().PrefixList(nodeID) diff --git a/command/node_status_test.go b/command/node_status_test.go index 353005679..14324bca4 100644 --- a/command/node_status_test.go +++ b/command/node_status_test.go @@ -104,6 +104,14 @@ func TestNodeStatusCommand_Run(t *testing.T) { } ui.OutputWriter.Reset() + // Identifiers with uneven length should produce a query result + if code := cmd.Run([]string{"-address=" + url, nodeID[:3]}); code != 0 { + t.Fatalf("expected exit 0, got: %d", code) + } + out = ui.OutputWriter.String() + if !strings.Contains(out, "mynode") { + t.Fatalf("expect to find mynode, got: %s", out) + } } func TestNodeStatusCommand_Fails(t *testing.T) { @@ -140,11 +148,11 @@ func TestNodeStatusCommand_Fails(t *testing.T) { } ui.ErrorWriter.Reset() - // Fail on uneven identifier length - if code := cmd.Run([]string{"-address=" + url, "1234567-abcd-efab-cdef-123456789abc"}); code != 1 { + // Fail on identifier with too few characters + if code := cmd.Run([]string{"-address=" + url, "1"}); code != 1 { t.Fatalf("expected exit 1, got: %d", code) } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "must be of even length.") { - t.Fatalf("expected even length error, got: %s", out) + if out := ui.ErrorWriter.String(); !strings.Contains(out, "must contain at least two characters.") { + t.Fatalf("expected too few characters error, got: %s", out) } }