Handle exact namespace match properly when also matched as prefix

This fixes an issue with the nomad namespace inspect and nomad namespace status commands failing to run for namespaces whose names are the start of another namespace's name: for example, foo and foobar. If the argument matches the first possibility returned by prefix exactly, that namespace will be targetted. If no exact match occurs, the behavior is unchanged.
This commit is contained in:
Charlie Voiselle
2017-11-29 19:40:08 -05:00
parent e369a9a971
commit 1592bf5b0c
3 changed files with 89 additions and 0 deletions

View File

@@ -92,3 +92,45 @@ func TestNamespaceInspectCommand_AutocompleteArgs(t *testing.T) {
assert.Equal(1, len(res))
assert.Equal(ns.Name, res[0])
}
// This test should demonstrate the behavior of a namespace
// and prefix collision. In that case, the Namespace status
// command should pull the matching namespace rather than
// displaying the multiple match error
func TestNamespaceInspectCommand_NamespaceMatchesPrefix(t *testing.T) {
t.Parallel()
// Create a server
srv, client, url := testServer(t, true, nil)
defer srv.Shutdown()
ui := new(cli.MockUi)
cmd := &NamespaceInspectCommand{Meta: Meta{Ui: ui}}
// Create a namespace that uses foo as a prefix
ns := &api.Namespace{Name: "fooBar"}
_, err := client.Namespaces().Register(ns, nil)
assert.Nil(t, err)
// Create a foo namespace
ns2 := &api.Namespace{Name: "foo"}
_, err = client.Namespaces().Register(ns2, nil)
assert.Nil(t, err)
// Adding a NS after to prevent sort from creating
// false successes
ns = &api.Namespace{Name: "fooBaz"}
_, err = client.Namespaces().Register(ns, nil)
assert.Nil(t, err)
// Check status on namespace
code := cmd.Run([]string{"-address=" + url, ns2.Name})
if code != 0 {
t.Fatalf("expected exit 0, got: %d; %v", code, ui.ErrorWriter.String())
}
// Check to ensure we got the proper foo
out := ui.OutputWriter.String()
if !strings.Contains(out, "= foo\n") {
t.Fatalf("expected namespace foo, got: %s", out)
}
}

View File

@@ -128,6 +128,11 @@ func getNamespace(client *api.Namespaces, ns string) (match *api.Namespace, poss
case l == 1:
return namespaces[0], nil, nil
default:
// search for an exact match in the returned namespaces
for _, namespace := range namespaces {
if namespace.Name == ns { return namespace, nil, nil }
}
// if not found, return the fuzzy matches.
return nil, namespaces, nil
}
}

View File

@@ -133,3 +133,45 @@ func TestNamespaceStatusCommand_AutocompleteArgs(t *testing.T) {
assert.Equal(1, len(res))
assert.Equal(ns.Name, res[0])
}
// This test should demonstrate the behavior of a namespace
// and prefix collision. In that case, the Namespace status
// command should pull the matching namespace rather than
// displaying the multiple match error
func TestNamespaceStatusCommand_NamespaceMatchesPrefix(t *testing.T) {
t.Parallel()
// Create a server
srv, client, url := testServer(t, true, nil)
defer srv.Shutdown()
ui := new(cli.MockUi)
cmd := &NamespaceStatusCommand{Meta: Meta{Ui: ui}}
// Create a namespace that uses foo as a prefix
ns := &api.Namespace{Name: "fooBar"}
_, err := client.Namespaces().Register(ns, nil)
assert.Nil(t, err)
// Create a foo namespace
ns2 := &api.Namespace{Name: "foo"}
_, err = client.Namespaces().Register(ns2, nil)
assert.Nil(t, err)
// Adding a NS after to prevent sort from creating
// false successes
ns = &api.Namespace{Name: "fooBaz"}
_, err = client.Namespaces().Register(ns, nil)
assert.Nil(t, err)
// Check status on namespace
code := cmd.Run([]string{"-address=" + url, ns2.Name})
if code != 0 {
t.Fatalf("expected exit 0, got: %d; %v", code, ui.ErrorWriter.String())
}
// Check to ensure we got the proper foo
out := ui.OutputWriter.String()
if !strings.Contains(out, "= foo\n") {
t.Fatalf("expected namespace foo, got: %s", out)
}
}