Fix hyperkube flag parsing

hyperkube kubectl cobra subcommands now work as expected.

Add unit tests with hyperkube subcommands
pull/6/head
Colin Hom 2016-05-11 14:46:26 -07:00 committed by Colin Hom
parent 24c46acd16
commit fd1771e7ae
4 changed files with 94 additions and 8 deletions

View File

@ -123,8 +123,8 @@ func (hk *HyperKube) Run(args []string) error {
command := args[0]
baseCommand := path.Base(command)
serverName := baseCommand
if serverName == hk.Name {
args = args[1:]
if serverName == hk.Name {
baseFlags := hk.Flags()
baseFlags.SetInterspersed(false) // Only parse flags up to the next real command

View File

@ -25,6 +25,7 @@ import (
"strings"
"testing"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)
@ -54,6 +55,55 @@ func testServerError(n string) *Server {
}
}
const defaultCobraMessage = "default message from cobra command"
const defaultCobraSubMessage = "default sub-message from cobra command"
const cobraMessageDesc = "message to print"
const cobraSubMessageDesc = "sub-message to print"
func testCobraCommand(n string) *Server {
var cobraServer *Server
var msg string
cmd := &cobra.Command{
Use: n,
Long: n,
Short: n,
Run: func(cmd *cobra.Command, args []string) {
cobraServer.hk.Printf("msg: %s\n", msg)
},
}
cmd.PersistentFlags().StringVar(&msg, "msg", defaultCobraMessage, cobraMessageDesc)
var subMsg string
subCmdName := "subcommand"
subCmd := &cobra.Command{
Use: subCmdName,
Long: subCmdName,
Short: subCmdName,
Run: func(cmd *cobra.Command, args []string) {
cobraServer.hk.Printf("submsg: %s", subMsg)
},
}
subCmd.PersistentFlags().StringVar(&subMsg, "submsg", defaultCobraSubMessage, cobraSubMessageDesc)
cmd.AddCommand(subCmd)
localFlags := cmd.LocalFlags()
localFlags.SetInterspersed(false)
s := &Server{
SimpleUsage: n,
Long: fmt.Sprintf("A server named %s which uses a cobra command", n),
Run: func(s *Server, args []string) error {
cobraServer = s
cmd.SetOutput(s.hk.Out())
cmd.SetArgs(args)
return cmd.Execute()
},
flags: localFlags,
}
return s
}
func runFull(t *testing.T, args string) *result {
buf := new(bytes.Buffer)
hk := HyperKube{
@ -66,6 +116,7 @@ func runFull(t *testing.T, args string) *result {
hk.AddServer(testServer("test2"))
hk.AddServer(testServer("test3"))
hk.AddServer(testServerError("test-error"))
hk.AddServer(testCobraCommand("test-cobra-command"))
a := strings.Split(args, " ")
t.Logf("Running full with args: %q", a)
@ -143,3 +194,32 @@ func TestServerError(t *testing.T) {
assert.Contains(t, x.output, "test-error Run")
assert.EqualError(t, x.err, "Server returning error")
}
func TestCobraCommandHelp(t *testing.T) {
x := runFull(t, "hyperkube test-cobra-command --help")
assert.NoError(t, x.err)
assert.Contains(t, x.output, "A server named test-cobra-command which uses a cobra command")
assert.Contains(t, x.output, cobraMessageDesc)
}
func TestCobraCommandDefaultMessage(t *testing.T) {
x := runFull(t, "hyperkube test-cobra-command")
assert.Contains(t, x.output, fmt.Sprintf("msg: %s", defaultCobraMessage))
}
func TestCobraCommandMessage(t *testing.T) {
x := runFull(t, "hyperkube test-cobra-command --msg foobar")
assert.Contains(t, x.output, "msg: foobar")
}
func TestCobraSubCommandHelp(t *testing.T) {
x := runFull(t, "hyperkube test-cobra-command subcommand --help")
assert.NoError(t, x.err)
assert.Contains(t, x.output, cobraSubMessageDesc)
}
func TestCobraSubCommandDefaultMessage(t *testing.T) {
x := runFull(t, "hyperkube test-cobra-command subcommand")
assert.Contains(t, x.output, fmt.Sprintf("submsg: %s", defaultCobraSubMessage))
}
func TestCobraSubCommandMessage(t *testing.T) {
x := runFull(t, "hyperkube test-cobra-command subcommand --submsg foobar")
assert.Contains(t, x.output, "submsg: foobar")
}

View File

@ -19,21 +19,23 @@ package main
import (
"os"
"k8s.io/kubernetes/cmd/kubectl/app"
"k8s.io/kubernetes/pkg/kubectl/cmd"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
)
func NewKubectlServer() *Server {
cmd := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, os.Stdout, os.Stderr)
localFlags := cmd.LocalFlags()
localFlags.SetInterspersed(false)
return &Server{
name: "kubectl",
SimpleUsage: "Kubernetes command line client",
Long: "Kubernetes command line client",
Run: func(s *Server, args []string) error {
os.Args = os.Args[1:]
if err := app.Run(); err != nil {
os.Exit(1)
}
os.Exit(0)
return nil
cmd.SetArgs(args)
return cmd.Execute()
},
flags: localFlags,
}
}

View File

@ -23,6 +23,10 @@ import (
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
)
/*
WARNING: this logic is duplicated, with minor changes, in cmd/hyperkube/kubectl.go
Any salient changes here will need to be manually reflected in that file.
*/
func Run() error {
cmd := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, os.Stdout, os.Stderr)
return cmd.Execute()