Skip to content

Commit

Permalink
Fix hyperkube flag parsing
Browse files Browse the repository at this point in the history
hyperkube kubectl cobra subcommands now work as expected.

Add unit tests with hyperkube subcommands
  • Loading branch information
Colin Hom authored and colhom committed May 13, 2016
1 parent 24c46ac commit fd1771e
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 8 deletions.
2 changes: 1 addition & 1 deletion cmd/hyperkube/hyperkube.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ func (hk *HyperKube) Run(args []string) error {
command := args[0]
baseCommand := path.Base(command)
serverName := baseCommand
args = args[1:]
if serverName == hk.Name {
args = args[1:]

baseFlags := hk.Flags()
baseFlags.SetInterspersed(false) // Only parse flags up to the next real command
Expand Down
80 changes: 80 additions & 0 deletions cmd/hyperkube/hyperkube_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"strings"
"testing"

"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -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{
Expand All @@ -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)
Expand Down Expand Up @@ -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")
}
16 changes: 9 additions & 7 deletions cmd/hyperkube/kubectl.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
4 changes: 4 additions & 0 deletions cmd/kubectl/app/kubectl.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit fd1771e

Please sign in to comment.