test(cmd): add helm client mocking

pull/921/head
Adam Reese 8 years ago
parent b990428111
commit 73f1bef3c9

@ -90,7 +90,11 @@ func newRootCmd() *cobra.Command {
var RootCommand = newRootCmd() var RootCommand = newRootCmd()
func main() { func main() {
out := os.Stdout
client := helm.NewClient(helm.HelmHost(helm.Config.ServAddr))
cmd := RootCommand cmd := RootCommand
cmd.AddCommand(newListCmd(client, out))
if err := cmd.Execute(); err != nil { if err := cmd.Execute(); err != nil {
os.Exit(1) os.Exit(1)
} }

@ -19,7 +19,6 @@ package main
import ( import (
"fmt" "fmt"
"io" "io"
"os"
"strings" "strings"
"github.com/gosuri/uitable" "github.com/gosuri/uitable"
@ -55,17 +54,20 @@ flag with the '--offset' flag allows you to page through results.
` `
type lister struct { type lister struct {
filter string
long bool long bool
max int limit int
offset string offset string
byDate bool byDate bool
sortDesc bool sortDesc bool
out io.Writer out io.Writer
client helm.Interface
} }
func newListCmd(out io.Writer) *cobra.Command { func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
list := &lister{ list := &lister{
out: out, client: client,
out: out,
} }
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "list [flags] [FILTER]", Use: "list [flags] [FILTER]",
@ -74,28 +76,22 @@ func newListCmd(out io.Writer) *cobra.Command {
Aliases: []string{"ls"}, Aliases: []string{"ls"},
PersistentPreRunE: setupConnection, PersistentPreRunE: setupConnection,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
return list.run(args) if len(args) > 0 {
list.filter = strings.Join(args, " ")
}
return list.run()
}, },
} }
f := cmd.Flags() f := cmd.Flags()
f.BoolVarP(&list.long, "long", "l", false, "output long listing format") f.BoolVarP(&list.long, "long", "l", false, "output long listing format")
f.BoolVarP(&list.byDate, "date", "d", false, "sort by release date") f.BoolVarP(&list.byDate, "date", "d", false, "sort by release date")
f.BoolVarP(&list.sortDesc, "reverse", "r", false, "reverse the sort order") f.BoolVarP(&list.sortDesc, "reverse", "r", false, "reverse the sort order")
f.IntVarP(&list.max, "max", "m", 256, "maximum number of releases to fetch") f.IntVarP(&list.limit, "max", "m", 256, "maximum number of releases to fetch")
f.StringVarP(&list.offset, "offset", "o", "", "the next release name in the list, used to offset from start value") f.StringVarP(&list.offset, "offset", "o", "", "the next release name in the list, used to offset from start value")
return cmd return cmd
} }
func init() { func (l *lister) run() error {
RootCommand.AddCommand(newListCmd(os.Stdout))
}
func (l *lister) run(args []string) error {
var filter string
if len(args) > 0 {
filter = strings.Join(args, " ")
}
sortBy := services.ListSort_NAME sortBy := services.ListSort_NAME
if l.byDate { if l.byDate {
sortBy = services.ListSort_LAST_RELEASED sortBy = services.ListSort_LAST_RELEASED
@ -106,7 +102,14 @@ func (l *lister) run(args []string) error {
sortOrder = services.ListSort_DESC sortOrder = services.ListSort_DESC
} }
res, err := helm.ListReleases(l.max, l.offset, sortBy, sortOrder, filter) res, err := l.client.ListReleases(
helm.ReleaseListLimit(l.limit),
helm.ReleaseListOffset(l.offset),
helm.ReleaseListFilter(l.filter),
helm.ReleaseListSort(int32(sortBy)),
helm.ReleaseListOrder(int32(sortOrder)),
)
if err != nil { if err != nil {
return prettyError(err) return prettyError(err)
} }

@ -4,18 +4,51 @@ import (
"bytes" "bytes"
"testing" "testing"
"github.com/golang/protobuf/ptypes/timestamp"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/proto/hapi/chart"
"k8s.io/helm/pkg/proto/hapi/release"
rls "k8s.io/helm/pkg/proto/hapi/services"
) )
// Stubbed out tests at two diffent layers func releaseMock(name string) *release.Release {
// TestList() is testing the command action date := timestamp.Timestamp{Seconds: 242085845, Nanos: 0}
// TestListCmd() is testing command line interface return &release.Release{
Name: name,
Info: &release.Info{
FirstDeployed: &date,
LastDeployed: &date,
Status: &release.Status{Code: release.Status_DEPLOYED},
},
Chart: &chart.Chart{
Metadata: &chart.Metadata{
Name: "foo",
Version: "0.1.0-beta.1",
},
Templates: []*chart.Template{
{Name: "foo.tpl", Data: []byte("Hello")},
},
},
Config: &chart.Config{Raw: `name = "value"`},
}
}
// TODO mock tiller responses type fakeReleaseLister struct {
helm.Interface
rels []*release.Release
err error
}
func TestList(t *testing.T) { func (fl *fakeReleaseLister) ListReleases(opts ...helm.ReleaseListOption) (*rls.ListReleasesResponse, error) {
helm.Config.ServAddr = ":44134" resp := &rls.ListReleasesResponse{
Count: int64(len(fl.rels)),
Releases: fl.rels,
}
return resp, fl.err
}
func TestListRun(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
lister *lister lister *lister
@ -23,21 +56,34 @@ func TestList(t *testing.T) {
err bool err bool
}{ }{
{ {
name: "with a release", name: "with a release",
lister: &lister{}, lister: &lister{
expected: "understood-coral", client: &fakeReleaseLister{
rels: []*release.Release{
releaseMock("thomas-guide"),
},
},
},
expected: "thomas-guide",
}, },
{ {
name: "list --long", name: "list --long",
lister: &lister{long: true}, lister: &lister{
expected: "NAME \tUPDATED \tSTATUS \tCHART \nunderstood-coral\tTue Jun 28 12:29:54 2016\tDEPLOYED\tnginx-0.1.0", client: &fakeReleaseLister{
rels: []*release.Release{
releaseMock("atlas"),
},
},
long: true,
},
expected: "NAME \tUPDATED \tSTATUS \tCHART \natlas\tFri Sep 2 15:04:05 1977\tDEPLOYED\tfoo-0.1.0-beta.1",
}, },
} }
var buf bytes.Buffer var buf bytes.Buffer
for _, tt := range tests { for _, tt := range tests {
tt.lister.out = &buf tt.lister.out = &buf
err := tt.lister.run([]string{}) err := tt.lister.run()
if (err != nil) != tt.err { if (err != nil) != tt.err {
t.Errorf("%q. expected error: %v, got %v", tt.name, tt.err, err) t.Errorf("%q. expected error: %v, got %v", tt.name, tt.err, err)
} }
@ -50,29 +96,38 @@ func TestList(t *testing.T) {
} }
func TestListCmd(t *testing.T) { func TestListCmd(t *testing.T) {
helm.Config.ServAddr = ":44134"
tests := []struct { tests := []struct {
name string name string
args []string args []string
flags map[string]string flags map[string]string
client helm.Interface
expected string expected string
err bool err bool
}{ }{
{ {
name: "with a release", name: "with a release",
expected: "understood-coral", client: &fakeReleaseLister{
rels: []*release.Release{
releaseMock("thomas-guide"),
},
},
expected: "thomas-guide",
}, },
{ {
name: "list --long", name: "list --long",
flags: map[string]string{"long": "1"}, flags: map[string]string{"long": "1"},
expected: "NAME \tUPDATED \tSTATUS \tCHART \nunderstood-coral\tTue Jun 28 12:29:54 2016\tDEPLOYED\tnginx-0.1.0", client: &fakeReleaseLister{
rels: []*release.Release{
releaseMock("atlas"),
},
},
expected: "NAME \tUPDATED \tSTATUS \tCHART \natlas\tFri Sep 2 15:04:05 1977\tDEPLOYED\tfoo-0.1.0-beta.1",
}, },
} }
var buf bytes.Buffer var buf bytes.Buffer
for _, tt := range tests { for _, tt := range tests {
cmd := newListCmd(&buf) cmd := newListCmd(tt.client, &buf)
for flag, value := range tt.flags { for flag, value := range tt.flags {
cmd.Flags().Set(flag, value) cmd.Flags().Set(flag, value)
} }

@ -0,0 +1,30 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package helm
import (
rls "k8s.io/helm/pkg/proto/hapi/services"
)
// Interface for helm client for mocking in tests
type Interface interface {
ListReleases(opts ...ReleaseListOption) (*rls.ListReleasesResponse, error)
InstallRelease(chStr string, opts ...InstallOption) (*rls.InstallReleaseResponse, error)
DeleteRelease(rlsName string, opts ...DeleteOption) (*rls.UninstallReleaseResponse, error)
ReleaseStatus(rlsName string, opts ...StatusOption) (*rls.GetReleaseStatusResponse, error)
UpdateRelease(rlsName string, opts ...UpdateOption) (*rls.UpdateReleaseResponse, error)
}
Loading…
Cancel
Save