659 lines
9.8 KiB
Go
659 lines
9.8 KiB
Go
// SPDX-License-Identifier: Apache-2.0
|
|
// Copyright Authors of K9s
|
|
|
|
package cmd_test
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/derailed/k9s/internal/view/cmd"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestRbacCmd(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ok bool
|
|
args []string
|
|
}{
|
|
"empty": {},
|
|
"user": {
|
|
cmd: "can u:fernand",
|
|
ok: true,
|
|
args: []string{"u", "fernand"},
|
|
},
|
|
"user_spacing": {
|
|
cmd: "can u: fernand ",
|
|
ok: true,
|
|
args: []string{"u", "fernand"},
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
assert.Equal(t, u.ok, p.IsRBACCmd())
|
|
|
|
c, s, ok := p.RBACArgs()
|
|
assert.Equal(t, u.ok, ok)
|
|
if u.ok {
|
|
assert.Equal(t, u.args[0], c)
|
|
assert.Equal(t, u.args[1], s)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNsCmd(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ok bool
|
|
ns string
|
|
}{
|
|
"empty": {},
|
|
"happy": {
|
|
cmd: "pod fred",
|
|
ok: true,
|
|
ns: "fred",
|
|
},
|
|
"ns-arg-spaced": {
|
|
cmd: "pod fred ",
|
|
ok: true,
|
|
ns: "fred",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
ns, ok := p.NSArg()
|
|
assert.Equal(t, u.ok, ok)
|
|
if u.ok {
|
|
assert.Equal(t, u.ns, ns)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSwitchNS(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ns string
|
|
e string
|
|
}{
|
|
"empty": {},
|
|
|
|
"blank": {
|
|
cmd: "pod fred",
|
|
e: "pod",
|
|
},
|
|
|
|
"no-op": {
|
|
cmd: "pod fred",
|
|
ns: "fred",
|
|
e: "pod fred",
|
|
},
|
|
|
|
"no-ns": {
|
|
cmd: "pod",
|
|
ns: "blee",
|
|
e: "pod blee",
|
|
},
|
|
|
|
"full-ns": {
|
|
cmd: "pod app=blee fred @zorg",
|
|
ns: "blee",
|
|
e: "pod app=blee blee @zorg",
|
|
},
|
|
|
|
"full--repeat-ns": {
|
|
cmd: "pod app=zorg zorg @zorg",
|
|
ns: "blee",
|
|
e: "pod app=zorg blee @zorg",
|
|
},
|
|
|
|
"full-no-ns": {
|
|
cmd: "pod app=blee @zorg",
|
|
ns: "blee",
|
|
e: "pod app=blee @zorg blee",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
p.SwitchNS(u.ns)
|
|
assert.Equal(t, u.e, p.GetLine())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestClearNS(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
e string
|
|
}{
|
|
"empty": {},
|
|
|
|
"has-ns": {
|
|
cmd: "pod fred",
|
|
e: "pod",
|
|
},
|
|
|
|
"no-ns": {
|
|
cmd: "pod",
|
|
e: "pod",
|
|
},
|
|
|
|
"full-repeat-ns": {
|
|
cmd: "pod app=blee @zorg zorg",
|
|
e: "pod app=blee @zorg",
|
|
},
|
|
|
|
"full-no-ns": {
|
|
cmd: "pod app=blee @zorg",
|
|
e: "pod app=blee @zorg",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
p.ClearNS()
|
|
assert.Equal(t, u.e, p.GetLine())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFilterCmd(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ok bool
|
|
filter string
|
|
}{
|
|
"empty": {},
|
|
"normal": {
|
|
cmd: "pod /fred",
|
|
ok: true,
|
|
filter: "fred",
|
|
},
|
|
"caps": {
|
|
cmd: "POD /FRED",
|
|
ok: true,
|
|
filter: "fred",
|
|
},
|
|
"filter+ns": {
|
|
cmd: "pod /fred ns1",
|
|
ok: true,
|
|
filter: "fred",
|
|
},
|
|
"ns+filter": {
|
|
cmd: "pod ns1 /fred",
|
|
ok: true,
|
|
filter: "fred",
|
|
},
|
|
"ns+filter+labels": {
|
|
cmd: "pod ns1 /fred app=blee,fred=zorg",
|
|
ok: true,
|
|
filter: "fred",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
f, ok := p.FilterArg()
|
|
assert.Equal(t, u.ok, ok)
|
|
if u.ok {
|
|
assert.Equal(t, u.filter, f)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLabelCmd(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
err error
|
|
labels string
|
|
}{
|
|
"empty": {},
|
|
|
|
"plain": {
|
|
cmd: "pod fred=blee",
|
|
labels: "fred=blee",
|
|
},
|
|
|
|
"multi": {
|
|
cmd: "pod fred=blee,zorg=duh",
|
|
labels: "fred=blee,zorg=duh",
|
|
},
|
|
|
|
"complex-lbls": {
|
|
cmd: "pod 'fred in (blee,zorg),blee notin (zorg)'",
|
|
labels: "blee notin (zorg),fred in (blee,zorg)",
|
|
},
|
|
|
|
"no-lbls": {
|
|
cmd: "pod ns-1",
|
|
},
|
|
|
|
"multi-ns": {
|
|
cmd: "pod fred=blee,zorg=duh ns1",
|
|
labels: "fred=blee,zorg=duh",
|
|
},
|
|
|
|
"l-arg-spaced": {
|
|
cmd: "pod fred=blee ",
|
|
labels: "fred=blee",
|
|
},
|
|
|
|
"l-arg-caps": {
|
|
cmd: "POD FRED=BLEE ",
|
|
labels: "fred=blee",
|
|
},
|
|
|
|
"toast-labels": {
|
|
cmd: "pod =blee",
|
|
err: errors.New("found '=', expected: !, identifier, or 'end of string'"),
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
ll, err := p.LabelsSelector()
|
|
assert.Equal(t, u.err, err)
|
|
if err == nil {
|
|
assert.Equal(t, u.labels, ll.String())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestXRayCmd(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ok bool
|
|
res, ns string
|
|
}{
|
|
"empty": {},
|
|
|
|
"happy": {
|
|
cmd: "xray po",
|
|
ok: true,
|
|
res: "po",
|
|
},
|
|
|
|
"happy+ns": {
|
|
cmd: "xray po ns1",
|
|
ok: true,
|
|
res: "po",
|
|
ns: "ns1",
|
|
},
|
|
|
|
"toast": {
|
|
cmd: "xrayzor po",
|
|
},
|
|
|
|
"toast-1": {
|
|
cmd: "xray",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
res, ns, ok := p.XrayArgs()
|
|
assert.Equal(t, u.ok, ok)
|
|
if u.ok {
|
|
assert.Equal(t, u.res, res)
|
|
assert.Equal(t, u.ns, ns)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDirCmd(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ok bool
|
|
dir string
|
|
}{
|
|
"empty": {},
|
|
|
|
"happy": {
|
|
cmd: "dir dir1",
|
|
ok: true,
|
|
dir: "dir1",
|
|
},
|
|
|
|
"extra-ns": {
|
|
cmd: "dir dir1 ns1",
|
|
ok: true,
|
|
dir: "dir1",
|
|
},
|
|
|
|
"toast": {
|
|
cmd: "dirdel dir1",
|
|
},
|
|
|
|
"toast-nodir": {
|
|
cmd: "dir",
|
|
},
|
|
|
|
"caps": {
|
|
cmd: "dir DirName",
|
|
ok: true,
|
|
dir: "DirName",
|
|
},
|
|
|
|
"abs": {
|
|
cmd: "dir /tmp",
|
|
ok: true,
|
|
dir: "/tmp",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
dir, ok := p.DirArg()
|
|
assert.Equal(t, u.ok, ok)
|
|
assert.Equal(t, u.dir, dir)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRBACCmd(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ok bool
|
|
cat, sub string
|
|
}{
|
|
"empty": {},
|
|
"toast": {
|
|
cmd: "canopy u:bozo",
|
|
},
|
|
"toast-1": {
|
|
cmd: "can u:",
|
|
},
|
|
"toast-2": {
|
|
cmd: "can bozo",
|
|
},
|
|
"user": {
|
|
cmd: "can u:bozo",
|
|
ok: true,
|
|
cat: "u",
|
|
sub: "bozo",
|
|
},
|
|
"group": {
|
|
cmd: "can g:bozo",
|
|
ok: true,
|
|
cat: "g",
|
|
sub: "bozo",
|
|
},
|
|
"sa": {
|
|
cmd: "can s:bozo",
|
|
ok: true,
|
|
cat: "s",
|
|
sub: "bozo",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
cat, sub, ok := p.RBACArgs()
|
|
assert.Equal(t, u.ok, ok)
|
|
if u.ok {
|
|
assert.Equal(t, u.cat, cat)
|
|
assert.Equal(t, u.sub, sub)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestContextCmd(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ok bool
|
|
ctx string
|
|
}{
|
|
"empty": {},
|
|
"happy-full": {
|
|
cmd: "context ctx1",
|
|
ok: true,
|
|
ctx: "ctx1",
|
|
},
|
|
"happy-alias": {
|
|
cmd: "ctx ctx1",
|
|
ok: true,
|
|
ctx: "ctx1",
|
|
},
|
|
"toast": {
|
|
cmd: "ctxto ctx1",
|
|
},
|
|
"caps": {
|
|
cmd: "ctx Dev",
|
|
ok: true,
|
|
ctx: "Dev",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
assert.Equal(t, u.ok, p.IsContextCmd())
|
|
if u.ok {
|
|
ctx, ok := p.ContextArg()
|
|
assert.Equal(t, u.ok, ok)
|
|
assert.Equal(t, u.ctx, ctx)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHelpCmd(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ok bool
|
|
}{
|
|
"empty": {},
|
|
"plain": {
|
|
cmd: "help",
|
|
ok: true,
|
|
},
|
|
"toast": {
|
|
cmd: "helpme",
|
|
},
|
|
"toast1": {
|
|
cmd: "hozer",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
assert.Equal(t, u.ok, p.IsHelpCmd())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBailCmd(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ok bool
|
|
}{
|
|
"empty": {},
|
|
"plain": {
|
|
cmd: "quit",
|
|
ok: true,
|
|
},
|
|
"q": {
|
|
cmd: "q",
|
|
ok: true,
|
|
},
|
|
"q!": {
|
|
cmd: "q!",
|
|
ok: true,
|
|
},
|
|
"toast": {
|
|
cmd: "zorg",
|
|
},
|
|
"toast1": {
|
|
cmd: "quitter",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
assert.Equal(t, u.ok, p.IsBailCmd())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAliasCmd(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ok bool
|
|
}{
|
|
"empty": {},
|
|
"plain": {
|
|
cmd: "alias",
|
|
ok: true,
|
|
},
|
|
"a": {
|
|
cmd: "a",
|
|
ok: true,
|
|
},
|
|
"toast": {
|
|
cmd: "abba",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
assert.Equal(t, u.ok, p.IsAliasCmd())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCowCmd(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ok bool
|
|
}{
|
|
"empty": {},
|
|
"plain": {
|
|
cmd: "cow",
|
|
ok: true,
|
|
},
|
|
"msg": {
|
|
cmd: "cow bumblebeetuna",
|
|
ok: true,
|
|
},
|
|
"toast": {
|
|
cmd: "cowdy",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
assert.Equal(t, u.ok, p.IsCowCmd())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestArgs(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
ok bool
|
|
ctx string
|
|
}{
|
|
"empty": {},
|
|
|
|
"with-plain-context": {
|
|
cmd: "po @fred",
|
|
ok: true,
|
|
ctx: "fred",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
ctx, ok := p.ContextArg()
|
|
assert.Equal(t, u.ok, ok)
|
|
if u.ok {
|
|
assert.Equal(t, u.ctx, ctx)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_grokLabels(t *testing.T) {
|
|
uu := map[string]struct {
|
|
cmd string
|
|
err error
|
|
lbls string
|
|
}{
|
|
"empty": {},
|
|
|
|
"no-labels": {
|
|
cmd: "po @fred",
|
|
},
|
|
|
|
"plain-label": {
|
|
cmd: "po a=b,b=c @fred",
|
|
lbls: "a=b,b=c",
|
|
},
|
|
|
|
"label-quotes": {
|
|
cmd: "po 'a=b,b=c' @fred",
|
|
lbls: "a=b,b=c",
|
|
},
|
|
|
|
"partial-quotes-label": {
|
|
cmd: "po 'a=b @fred",
|
|
lbls: "",
|
|
},
|
|
|
|
"complex": {
|
|
cmd: "po 'a in (b,c),b notin (c,z)' fred'",
|
|
lbls: "a in (b,c),b notin (c,z)",
|
|
},
|
|
}
|
|
|
|
for k := range uu {
|
|
u := uu[k]
|
|
t.Run(k, func(t *testing.T) {
|
|
p := cmd.NewInterpreter(u.cmd)
|
|
sel, err := p.LabelsSelector()
|
|
assert.Equal(t, u.err, err)
|
|
if err == nil {
|
|
assert.Equal(t, u.lbls, sel.String())
|
|
}
|
|
})
|
|
}
|
|
}
|