ref(cmd): simplify cmd test setup

pull/3976/head
Adam Reese 6 years ago
parent 7bf0cb6c46
commit a5b7cde9e5
No known key found for this signature in database
GPG Key ID: 06F35E60A7A18DD6

14
Gopkg.lock generated

@ -337,6 +337,12 @@
revision = "d6bea18f789704b5f83375793155289da36a3c7f" revision = "d6bea18f789704b5f83375793155289da36a3c7f"
version = "v0.0.1" version = "v0.0.1"
[[projects]]
name = "github.com/mattn/go-shellwords"
packages = ["."]
revision = "02e3cf038dcea8290e44424da473dd12be796a8a"
version = "v1.0.3"
[[projects]] [[projects]]
name = "github.com/matttproud/golang_protobuf_extensions" name = "github.com/matttproud/golang_protobuf_extensions"
packages = ["pbutil"] packages = ["pbutil"]
@ -431,12 +437,14 @@
".", ".",
"doc" "doc"
] ]
revision = "f62e98d28ab7ad31d707ba837a966378465c7b57" revision = "a1f051bc3eba734da4772d60e2d677f47cf93ef4"
version = "v0.0.2"
[[projects]] [[projects]]
name = "github.com/spf13/pflag" name = "github.com/spf13/pflag"
packages = ["."] packages = ["."]
revision = "9ff6c6923cfffbcd502984b8e0c80539a94968b7" revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
version = "v1.0.1"
[[projects]] [[projects]]
name = "github.com/stretchr/testify" name = "github.com/stretchr/testify"
@ -1063,6 +1071,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "d27aa9378f7846f9dc4de8168f8a2dd6d9584fefddd26e2a9e172b9d8fc075c9" inputs-digest = "82526354be9627a0e3796098ee9bed433a3e7958495f65e371ecc27d8c71c111"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

@ -17,57 +17,51 @@ limitations under the License.
package main package main
import ( import (
"io"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/hapi/release" "k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
) )
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
resp := helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})
rels := []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})}
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "basic delete", name: "basic delete",
args: []string{"aeneas"}, cmd: "delete aeneas",
flags: []string{}, matches: `release "aeneas" deleted`,
expected: "", // Output of a delete is an empty string and exit 0. resp: resp,
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}), rels: rels,
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})},
}, },
{ {
name: "delete with timeout", name: "delete with timeout",
args: []string{"aeneas"}, cmd: "delete aeneas --timeout 120",
flags: []string{"--timeout", "120"}, matches: `release "aeneas" deleted`,
expected: "", resp: resp,
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}), rels: rels,
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})},
}, },
{ {
name: "delete without hooks", name: "delete without hooks",
args: []string{"aeneas"}, cmd: "delete aeneas --no-hooks",
flags: []string{"--no-hooks"}, matches: `release "aeneas" deleted`,
expected: "", resp: resp,
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}), rels: rels,
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})},
}, },
{ {
name: "purge", name: "purge",
args: []string{"aeneas"}, cmd: "delete aeneas --purge",
flags: []string{"--purge"}, matches: `release "aeneas" deleted`,
expected: "", resp: resp,
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}), rels: rels,
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})},
}, },
{ {
name: "delete without release", name: "delete without release",
args: []string{}, cmd: "delete",
err: true, wantError: true,
}, },
} }
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { testReleaseCmd(t, tests)
return newDeleteCmd(c, out)
})
} }

@ -16,43 +16,35 @@ limitations under the License.
package main package main
import ( import (
"io"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/helm"
) )
func TestDependencyListCmd(t *testing.T) { func TestDependencyListCmd(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "No such chart", name: "No such chart",
args: []string{"/no/such/chart"}, cmd: "dependency list /no/such/chart",
err: true, wantError: true,
}, },
{ {
name: "No requirements.yaml", name: "No requirements.yaml",
args: []string{"testdata/testcharts/alpine"}, cmd: "dependency list testdata/testcharts/alpine",
expected: "WARNING: no requirements at ", matches: "WARNING: no requirements at ",
}, },
{ {
name: "Requirements in chart dir", name: "Requirements in chart dir",
args: []string{"testdata/testcharts/reqtest"}, cmd: "dependency list testdata/testcharts/reqtest",
expected: "NAME \tVERSION\tREPOSITORY \tSTATUS \n" + matches: "NAME \tVERSION\tREPOSITORY \tSTATUS \n" +
"reqsubchart \t0.1.0 \thttps://example.com/charts\tunpacked\n" + "reqsubchart \t0.1.0 \thttps://example.com/charts\tunpacked\n" +
"reqsubchart2\t0.2.0 \thttps://example.com/charts\tunpacked\n" + "reqsubchart2\t0.2.0 \thttps://example.com/charts\tunpacked\n" +
"reqsubchart3\t>=0.1.0\thttps://example.com/charts\tok \n\n", "reqsubchart3\t>=0.1.0\thttps://example.com/charts\tok \n\n",
}, },
{ {
name: "Requirements in chart archive", name: "Requirements in chart archive",
args: []string{"testdata/testcharts/reqtest-0.1.0.tgz"}, cmd: "dependency list testdata/testcharts/reqtest-0.1.0.tgz",
expected: "NAME \tVERSION\tREPOSITORY \tSTATUS \nreqsubchart \t0.1.0 \thttps://example.com/charts\tmissing\nreqsubchart2\t0.2.0 \thttps://example.com/charts\tmissing\n", matches: "NAME \tVERSION\tREPOSITORY \tSTATUS \nreqsubchart \t0.1.0 \thttps://example.com/charts\tmissing\nreqsubchart2\t0.2.0 \thttps://example.com/charts\tmissing\n",
}, },
} }
testReleaseCmd(t, tests)
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command {
return newDependencyListCmd(out)
})
} }

@ -42,9 +42,10 @@ var errReleaseRequired = errors.New("release name is required")
type getCmd struct { type getCmd struct {
release string release string
out io.Writer
client helm.Interface
version int version int
out io.Writer
client helm.Interface
} }
func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command { func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
@ -69,9 +70,9 @@ func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command {
cmd.Flags().IntVar(&get.version, "revision", 0, "get the named release with revision") cmd.Flags().IntVar(&get.version, "revision", 0, "get the named release with revision")
cmd.AddCommand(newGetValuesCmd(nil, out)) cmd.AddCommand(newGetValuesCmd(client, out))
cmd.AddCommand(newGetManifestCmd(nil, out)) cmd.AddCommand(newGetManifestCmd(client, out))
cmd.AddCommand(newGetHooksCmd(nil, out)) cmd.AddCommand(newGetHooksCmd(client, out))
return cmd return cmd
} }

@ -17,11 +17,8 @@ limitations under the License.
package main package main
import ( import (
"io"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/hapi/release" "k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
) )
@ -29,19 +26,17 @@ import (
func TestGetHooks(t *testing.T) { func TestGetHooks(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "get hooks with release", name: "get hooks with release",
args: []string{"aeneas"}, cmd: "get hooks aeneas",
expected: helm.MockHookTemplate, matches: helm.MockHookTemplate,
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}),
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})},
}, },
{ {
name: "get hooks without args", name: "get hooks without args",
args: []string{}, cmd: "get hooks",
err: true, wantError: true,
}, },
} }
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { testReleaseCmd(t, tests)
return newGetHooksCmd(c, out)
})
} }

@ -17,11 +17,8 @@ limitations under the License.
package main package main
import ( import (
"io"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/hapi/release" "k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
) )
@ -29,19 +26,17 @@ import (
func TestGetManifest(t *testing.T) { func TestGetManifest(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "get manifest with release", name: "get manifest with release",
args: []string{"juno"}, cmd: "get manifest juno",
expected: helm.MockManifest, matches: helm.MockManifest,
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "juno"}), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "juno"}),
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "juno"})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "juno"})},
}, },
{ {
name: "get manifest without args", name: "get manifest without args",
args: []string{}, cmd: "get manifest",
err: true, wantError: true,
}, },
} }
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { testReleaseCmd(t, tests)
return newGetManifestCmd(c, out)
})
} }

@ -17,11 +17,8 @@ limitations under the License.
package main package main
import ( import (
"io"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/hapi/release" "k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
) )
@ -29,20 +26,17 @@ import (
func TestGetCmd(t *testing.T) { func TestGetCmd(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "get with a release", name: "get with a release",
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}), cmd: "get thomas-guide",
args: []string{"thomas-guide"}, matches: "REVISION: 1\nRELEASED: (.*)\nCHART: foo-0.1.0-beta.1\nUSER-SUPPLIED VALUES:\nname: \"value\"\nCOMPUTED VALUES:\nname: value\n\nHOOKS:\n---\n# pre-install-hook\n" + helm.MockHookTemplate + "\nMANIFEST:",
expected: "REVISION: 1\nRELEASED: (.*)\nCHART: foo-0.1.0-beta.1\nUSER-SUPPLIED VALUES:\nname: \"value\"\nCOMPUTED VALUES:\nname: value\n\nHOOKS:\n---\n# pre-install-hook\n" + helm.MockHookTemplate + "\nMANIFEST:", rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"})},
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"})}, resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
}, },
{ {
name: "get requires release name arg", name: "get requires release name arg",
err: true, cmd: "get",
wantError: true,
}, },
} }
testReleaseCmd(t, tests)
cmd := func(c *helm.FakeClient, out io.Writer) *cobra.Command {
return newGetCmd(c, out)
}
runReleaseCases(t, tests, cmd)
} }

@ -17,11 +17,8 @@ limitations under the License.
package main package main
import ( import (
"io"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/hapi/release" "k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
) )
@ -29,19 +26,17 @@ import (
func TestGetValuesCmd(t *testing.T) { func TestGetValuesCmd(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "get values with a release", name: "get values with a release",
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}), cmd: "get values thomas-guide",
args: []string{"thomas-guide"}, matches: "name: \"value\"",
expected: "name: \"value\"", resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"})}, rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"})},
}, },
{ {
name: "get values requires release name arg", name: "get values requires release name arg",
err: true, cmd: "get values",
wantError: true,
}, },
} }
cmd := func(c *helm.FakeClient, out io.Writer) *cobra.Command { testReleaseCmd(t, tests)
return newGetValuesCmd(c, out)
}
runReleaseCases(t, tests, cmd)
} }

@ -18,6 +18,7 @@ package main // import "k8s.io/helm/cmd/helm"
import ( import (
"fmt" "fmt"
"io"
"log" "log"
"os" "os"
"strings" "strings"
@ -61,7 +62,7 @@ Environment:
$KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config") $KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config")
` `
func newRootCmd(args []string) *cobra.Command { func newRootCmd(c helm.Interface, out io.Writer, args []string) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "helm", Use: "helm",
Short: "The Helm package manager for Kubernetes.", Short: "The Helm package manager for Kubernetes.",
@ -72,8 +73,6 @@ func newRootCmd(args []string) *cobra.Command {
settings.AddFlags(flags) settings.AddFlags(flags)
out := cmd.OutOrStdout()
cmd.AddCommand( cmd.AddCommand(
// chart commands // chart commands
newCreateCmd(out), newCreateCmd(out),
@ -87,15 +86,15 @@ func newRootCmd(args []string) *cobra.Command {
newVerifyCmd(out), newVerifyCmd(out),
// release commands // release commands
newDeleteCmd(nil, out), newDeleteCmd(c, out),
newGetCmd(nil, out), newGetCmd(c, out),
newHistoryCmd(nil, out), newHistoryCmd(c, out),
newInstallCmd(nil, out), newInstallCmd(c, out),
newListCmd(nil, out), newListCmd(c, out),
newReleaseTestCmd(nil, out), newReleaseTestCmd(c, out),
newRollbackCmd(nil, out), newRollbackCmd(c, out),
newStatusCmd(nil, out), newStatusCmd(c, out),
newUpgradeCmd(nil, out), newUpgradeCmd(c, out),
newCompletionCmd(out), newCompletionCmd(out),
newHomeCmd(out), newHomeCmd(out),
@ -131,7 +130,7 @@ func logf(format string, v ...interface{}) {
} }
func main() { func main() {
cmd := newRootCmd(os.Args[1:]) cmd := newRootCmd(nil, os.Stdout, os.Args[1:])
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 (
"bytes" "bytes"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -27,6 +26,7 @@ import (
"strings" "strings"
"testing" "testing"
shellwords "github.com/mattn/go-shellwords"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/helm/pkg/hapi/release" "k8s.io/helm/pkg/hapi/release"
@ -35,42 +35,53 @@ import (
"k8s.io/helm/pkg/repo" "k8s.io/helm/pkg/repo"
) )
// releaseCmd is a command that works with a FakeClient func executeCommand(c helm.Interface, cmd string) (string, error) {
type releaseCmd func(c *helm.FakeClient, out io.Writer) *cobra.Command _, output, err := executeCommandC(c, cmd)
return output, err
}
func executeCommandC(client helm.Interface, cmd string) (*cobra.Command, string, error) {
args, err := shellwords.Parse(cmd)
if err != nil {
return nil, "", err
}
buf := new(bytes.Buffer)
root := newRootCmd(client, buf, args)
root.SetOutput(buf)
root.SetArgs(args)
c, err := root.ExecuteC()
return c, buf.String(), err
}
// runReleaseCases runs a set of release cases through the given releaseCmd. func testReleaseCmd(t *testing.T, tests []releaseCase) {
func runReleaseCases(t *testing.T, tests []releaseCase, rcmd releaseCmd) {
var buf bytes.Buffer
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
c := &helm.FakeClient{ c := &helm.FakeClient{
Rels: tt.rels, Rels: tt.rels,
Responses: tt.responses, Responses: tt.responses,
} }
cmd := rcmd(c, &buf) out, err := executeCommand(c, tt.cmd)
cmd.ParseFlags(tt.flags) if (err != nil) != tt.wantError {
err := cmd.RunE(cmd, tt.args)
if (err != nil) != tt.err {
t.Errorf("expected error, got '%v'", err) t.Errorf("expected error, got '%v'", err)
} }
re := regexp.MustCompile(tt.expected) re := regexp.MustCompile(tt.matches)
if !re.Match(buf.Bytes()) { if !re.MatchString(out) {
t.Errorf("expected\n%q\ngot\n%q", tt.expected, buf.String()) t.Errorf("expected\n%q\ngot\n%q", tt.matches, out)
} }
buf.Reset()
}) })
} }
} }
// releaseCase describes a test case that works with releases. // releaseCase describes a test case that works with releases.
type releaseCase struct { type releaseCase struct {
name string name string
args []string cmd string
flags []string // matches is the string to be matched. This supports regular expressions.
// expected is the string to be matched. This supports regular expressions. matches string
expected string wantError bool
err bool resp *release.Release
resp *release.Release
// Rels are the available releases at the start of the test. // Rels are the available releases at the start of the test.
rels []*release.Release rels []*release.Release
responses map[string]release.TestRunStatus responses map[string]release.TestRunStatus
@ -131,7 +142,7 @@ func ensureTestHome(home helmpath.Home, t *testing.T) error {
} }
} }
t.Logf("$HELM_HOME has been configured at %s.\n", settings.Home.String()) t.Logf("$HELM_HOME has been configured at %s.\n", home)
return nil return nil
} }
@ -141,41 +152,39 @@ func TestRootCmd(t *testing.T) {
defer cleanup() defer cleanup()
tests := []struct { tests := []struct {
name string name, args, home string
args []string envars map[string]string
envars map[string]string
home string
}{ }{
{ {
name: "defaults", name: "defaults",
args: []string{"home"}, args: "home",
home: filepath.Join(os.Getenv("HOME"), "/.helm"), home: filepath.Join(os.Getenv("HOME"), "/.helm"),
}, },
{ {
name: "with --home set", name: "with --home set",
args: []string{"--home", "/foo"}, args: "--home /foo",
home: "/foo", home: "/foo",
}, },
{ {
name: "subcommands with --home set", name: "subcommands with --home set",
args: []string{"home", "--home", "/foo"}, args: "home --home /foo",
home: "/foo", home: "/foo",
}, },
{ {
name: "with $HELM_HOME set", name: "with $HELM_HOME set",
args: []string{"home"}, args: "home",
envars: map[string]string{"HELM_HOME": "/bar"}, envars: map[string]string{"HELM_HOME": "/bar"},
home: "/bar", home: "/bar",
}, },
{ {
name: "subcommands with $HELM_HOME set", name: "subcommands with $HELM_HOME set",
args: []string{"home"}, args: "home",
envars: map[string]string{"HELM_HOME": "/bar"}, envars: map[string]string{"HELM_HOME": "/bar"},
home: "/bar", home: "/bar",
}, },
{ {
name: "with $HELM_HOME and --home set", name: "with $HELM_HOME and --home set",
args: []string{"home", "--home", "/foo"}, args: "home --home /foo",
envars: map[string]string{"HELM_HOME": "/bar"}, envars: map[string]string{"HELM_HOME": "/bar"},
home: "/foo", home: "/foo",
}, },
@ -192,12 +201,9 @@ func TestRootCmd(t *testing.T) {
os.Setenv(k, v) os.Setenv(k, v)
} }
cmd := newRootCmd(tt.args) cmd, _, err := executeCommandC(nil, tt.args)
cmd.SetOutput(ioutil.Discard) if err != nil {
cmd.SetArgs(tt.args) t.Fatalf("unexpected error: %s", err)
cmd.Run = func(*cobra.Command, []string) {}
if err := cmd.Execute(); err != nil {
t.Errorf("unexpected error: %s", err)
} }
if settings.Home.String() != tt.home { if settings.Home.String() != tt.home {

@ -17,11 +17,8 @@ limitations under the License.
package main package main
import ( import (
"io"
"testing" "testing"
"github.com/spf13/cobra"
rpb "k8s.io/helm/pkg/hapi/release" rpb "k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
) )
@ -38,48 +35,42 @@ func TestHistoryCmd(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "get history for release", name: "get history for release",
args: []string{"angry-bird"}, cmd: "history angry-bird",
rels: []*rpb.Release{ rels: []*rpb.Release{
mk("angry-bird", 4, rpb.Status_DEPLOYED), mk("angry-bird", 4, rpb.Status_DEPLOYED),
mk("angry-bird", 3, rpb.Status_SUPERSEDED), mk("angry-bird", 3, rpb.Status_SUPERSEDED),
mk("angry-bird", 2, rpb.Status_SUPERSEDED), mk("angry-bird", 2, rpb.Status_SUPERSEDED),
mk("angry-bird", 1, rpb.Status_SUPERSEDED), mk("angry-bird", 1, rpb.Status_SUPERSEDED),
}, },
expected: `REVISION\s+UPDATED\s+STATUS\s+CHART\s+DESCRIPTION \n1\s+(.*)\s+SUPERSEDED\s+foo-0.1.0-beta.1\s+Release mock\n2(.*)SUPERSEDED\s+foo-0.1.0-beta.1\s+Release mock\n3(.*)SUPERSEDED\s+foo-0.1.0-beta.1\s+Release mock\n4(.*)DEPLOYED\s+foo-0.1.0-beta.1\s+Release mock\n`, matches: `REVISION\s+UPDATED\s+STATUS\s+CHART\s+DESCRIPTION \n1\s+(.*)\s+SUPERSEDED\s+foo-0.1.0-beta.1\s+Release mock\n2(.*)SUPERSEDED\s+foo-0.1.0-beta.1\s+Release mock\n3(.*)SUPERSEDED\s+foo-0.1.0-beta.1\s+Release mock\n4(.*)DEPLOYED\s+foo-0.1.0-beta.1\s+Release mock\n`,
}, },
{ {
name: "get history with max limit set", name: "get history with max limit set",
args: []string{"angry-bird"}, cmd: "history angry-bird --max 2",
flags: []string{"--max", "2"},
rels: []*rpb.Release{ rels: []*rpb.Release{
mk("angry-bird", 4, rpb.Status_DEPLOYED), mk("angry-bird", 4, rpb.Status_DEPLOYED),
mk("angry-bird", 3, rpb.Status_SUPERSEDED), mk("angry-bird", 3, rpb.Status_SUPERSEDED),
}, },
expected: `REVISION\s+UPDATED\s+STATUS\s+CHART\s+DESCRIPTION \n3\s+(.*)\s+SUPERSEDED\s+foo-0.1.0-beta.1\s+Release mock\n4\s+(.*)\s+DEPLOYED\s+foo-0.1.0-beta.1\s+Release mock\n`, matches: `REVISION\s+UPDATED\s+STATUS\s+CHART\s+DESCRIPTION \n3\s+(.*)\s+SUPERSEDED\s+foo-0.1.0-beta.1\s+Release mock\n4\s+(.*)\s+DEPLOYED\s+foo-0.1.0-beta.1\s+Release mock\n`,
}, },
{ {
name: "get history with yaml output format", name: "get history with yaml output format",
args: []string{"angry-bird"}, cmd: "history angry-bird --output yaml",
flags: []string{"--output", "yaml"},
rels: []*rpb.Release{ rels: []*rpb.Release{
mk("angry-bird", 4, rpb.Status_DEPLOYED), mk("angry-bird", 4, rpb.Status_DEPLOYED),
mk("angry-bird", 3, rpb.Status_SUPERSEDED), mk("angry-bird", 3, rpb.Status_SUPERSEDED),
}, },
expected: "- chart: foo-0.1.0-beta.1\n description: Release mock\n revision: 3\n status: SUPERSEDED\n updated: (.*)\n- chart: foo-0.1.0-beta.1\n description: Release mock\n revision: 4\n status: DEPLOYED\n updated: (.*)\n\n", matches: "- chart: foo-0.1.0-beta.1\n description: Release mock\n revision: 3\n status: SUPERSEDED\n updated: (.*)\n- chart: foo-0.1.0-beta.1\n description: Release mock\n revision: 4\n status: DEPLOYED\n updated: (.*)\n\n",
}, },
{ {
name: "get history with json output format", name: "get history with json output format",
args: []string{"angry-bird"}, cmd: "history angry-bird --output json",
flags: []string{"--output", "json"},
rels: []*rpb.Release{ rels: []*rpb.Release{
mk("angry-bird", 4, rpb.Status_DEPLOYED), mk("angry-bird", 4, rpb.Status_DEPLOYED),
mk("angry-bird", 3, rpb.Status_SUPERSEDED), mk("angry-bird", 3, rpb.Status_SUPERSEDED),
}, },
expected: `[{"revision":3,"updated":".*","status":"SUPERSEDED","chart":"foo\-0.1.0-beta.1","description":"Release mock"},{"revision":4,"updated":".*","status":"DEPLOYED","chart":"foo\-0.1.0-beta.1","description":"Release mock"}]\n`, matches: `[{"revision":3,"updated":".*","status":"SUPERSEDED","chart":"foo\-0.1.0-beta.1","description":"Release mock"},{"revision":4,"updated":".*","status":"DEPLOYED","chart":"foo\-0.1.0-beta.1","description":"Release mock"}]\n`,
}, },
} }
testReleaseCmd(t, tests)
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command {
return newHistoryCmd(c, out)
})
} }

@ -105,31 +105,31 @@ charts in a repository, use 'helm search'.
` `
type installCmd struct { type installCmd struct {
name string name string // --name
valueFiles valueFiles valueFiles valueFiles // --values
chartPath string dryRun bool // --dry-run
dryRun bool disableHooks bool // --disable-hooks
disableHooks bool replace bool // --replace
replace bool verify bool // --verify
verify bool keyring string // --keyring
keyring string values []string // --set
out io.Writer stringValues []string // --set-string
client helm.Interface nameTemplate string // --name-template
values []string version string // --version
stringValues []string timeout int64 // --timeout
nameTemplate string wait bool // --wait
version string repoURL string // --repo
timeout int64 username string // --username
wait bool password string // --password
repoURL string devel bool // --devel
username string depUp bool // --dep-up
password string certFile string // --cert-file
devel bool keyFile string // --key-file
depUp bool caFile string // --ca-file
chartPath string // arg
certFile string
keyFile string out io.Writer
caFile string client helm.Interface
} }
type valueFiles []string type valueFiles []string
@ -291,7 +291,7 @@ func (i *installCmd) run() error {
} }
// Merges source and destination map, preferring values from the source map // Merges source and destination map, preferring values from the source map
func mergeValues(dest map[string]interface{}, src map[string]interface{}) map[string]interface{} { func mergeValues(dest, src map[string]interface{}) map[string]interface{} {
for k, v := range src { for k, v := range src {
// If the key doesn't exist already, then just set the key to that value // If the key doesn't exist already, then just set the key to that value
if _, exists := dest[k]; !exists { if _, exists := dest[k]; !exists {

@ -17,14 +17,10 @@ limitations under the License.
package main package main
import ( import (
"io"
"reflect" "reflect"
"regexp" "regexp"
"strings"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
) )
@ -32,125 +28,110 @@ func TestInstall(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
// Install, base case // Install, base case
{ {
name: "basic install", name: "basic install",
args: []string{"testdata/testcharts/alpine"}, cmd: "install testdata/testcharts/alpine --name aeneas",
flags: strings.Split("--name aeneas", " "), matches: "aeneas",
expected: "aeneas", resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}),
}, },
// Install, no hooks // Install, no hooks
{ {
name: "install without hooks", name: "install without hooks",
args: []string{"testdata/testcharts/alpine"}, cmd: "install testdata/testcharts/alpine --name aeneas --no-hooks",
flags: strings.Split("--name aeneas --no-hooks", " "), matches: "aeneas",
expected: "aeneas", resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}),
}, },
// Install, values from cli // Install, values from cli
{ {
name: "install with values", name: "install with values",
args: []string{"testdata/testcharts/alpine"}, cmd: "install testdata/testcharts/alpine --name virgil --set foo=bar",
flags: strings.Split("--name virgil --set foo=bar", " "), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}), matches: "virgil",
expected: "virgil",
}, },
// Install, values from cli via multiple --set // Install, values from cli via multiple --set
{ {
name: "install with multiple values", name: "install with multiple values",
args: []string{"testdata/testcharts/alpine"}, cmd: "install testdata/testcharts/alpine --name virgil --set foo=bar --set bar=foo",
flags: strings.Split("--name virgil --set foo=bar --set bar=foo", " "), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}), matches: "virgil",
expected: "virgil",
}, },
// Install, values from yaml // Install, values from yaml
{ {
name: "install with values", name: "install with values",
args: []string{"testdata/testcharts/alpine"}, cmd: "install testdata/testcharts/alpine --name virgil -f testdata/testcharts/alpine/extra_values.yaml",
flags: strings.Split("--name virgil -f testdata/testcharts/alpine/extra_values.yaml", " "), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}), matches: "virgil",
expected: "virgil",
}, },
// Install, values from multiple yaml // Install, values from multiple yaml
{ {
name: "install with values", name: "install with values",
args: []string{"testdata/testcharts/alpine"}, cmd: "install testdata/testcharts/alpine --name virgil -f testdata/testcharts/alpine/extra_values.yaml -f testdata/testcharts/alpine/more_values.yaml",
flags: strings.Split("--name virgil -f testdata/testcharts/alpine/extra_values.yaml -f testdata/testcharts/alpine/more_values.yaml", " "), resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}), matches: "virgil",
expected: "virgil",
}, },
// Install, no charts // Install, no charts
{ {
name: "install with no chart specified", name: "install with no chart specified",
args: []string{}, cmd: "install",
err: true, wantError: true,
}, },
// Install, re-use name // Install, re-use name
{ {
name: "install and replace release", name: "install and replace release",
args: []string{"testdata/testcharts/alpine"}, cmd: "install testdata/testcharts/alpine --name aeneas --replace",
flags: strings.Split("--name aeneas --replace", " "), matches: "aeneas",
expected: "aeneas", resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"}),
}, },
// Install, with timeout // Install, with timeout
{ {
name: "install with a timeout", name: "install with a timeout",
args: []string{"testdata/testcharts/alpine"}, cmd: "install testdata/testcharts/alpine --name foobar --timeout 120",
flags: strings.Split("--name foobar --timeout 120", " "), matches: "foobar",
expected: "foobar", resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "foobar"}),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "foobar"}),
}, },
// Install, with wait // Install, with wait
{ {
name: "install with a wait", name: "install with a wait",
args: []string{"testdata/testcharts/alpine"}, cmd: "install testdata/testcharts/alpine --name apollo --wait",
flags: strings.Split("--name apollo --wait", " "), matches: "apollo",
expected: "apollo", resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "apollo"}),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "apollo"}),
}, },
// Install, using the name-template // Install, using the name-template
{ {
name: "install with name-template", name: "install with name-template",
args: []string{"testdata/testcharts/alpine"}, cmd: "install testdata/testcharts/alpine --name-template '{{upper \"foobar\"}}'",
flags: []string{"--name-template", "{{upper \"foobar\"}}"}, matches: "FOOBAR",
expected: "FOOBAR", resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "FOOBAR"}),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "FOOBAR"}),
}, },
// Install, perform chart verification along the way. // Install, perform chart verification along the way.
{ {
name: "install with verification, missing provenance", name: "install with verification, missing provenance",
args: []string{"testdata/testcharts/compressedchart-0.1.0.tgz"}, cmd: "install testdata/testcharts/compressedchart-0.1.0.tgz --verify --keyring testdata/helm-test-key.pub",
flags: strings.Split("--verify --keyring testdata/helm-test-key.pub", " "), wantError: true,
err: true,
}, },
{ {
name: "install with verification, directory instead of file", name: "install with verification, directory instead of file",
args: []string{"testdata/testcharts/signtest"}, cmd: "install testdata/testcharts/signtest --verify --keyring testdata/helm-test-key.pub",
flags: strings.Split("--verify --keyring testdata/helm-test-key.pub", " "), wantError: true,
err: true,
}, },
{ {
name: "install with verification, valid", name: "install with verification, valid",
args: []string{"testdata/testcharts/signtest-0.1.0.tgz"}, cmd: "install testdata/testcharts/signtest-0.1.0.tgz --verify --keyring testdata/helm-test-key.pub",
flags: strings.Split("--verify --keyring testdata/helm-test-key.pub", " "),
}, },
// Install, chart with missing dependencies in /charts // Install, chart with missing dependencies in /charts
{ {
name: "install chart with missing dependencies", name: "install chart with missing dependencies",
args: []string{"testdata/testcharts/chart-missing-deps"}, cmd: "install testdata/testcharts/chart-missing-deps",
err: true, wantError: true,
}, },
// Install, chart with bad requirements.yaml in /charts // Install, chart with bad requirements.yaml in /charts
{ {
name: "install chart with bad requirements.yaml", name: "install chart with bad requirements.yaml",
args: []string{"testdata/testcharts/chart-bad-requirements"}, cmd: "install testdata/testcharts/chart-bad-requirements",
err: true, wantError: true,
}, },
} }
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { testReleaseCmd(t, tests)
return newInstallCmd(c, out)
})
} }
type nameTemplateTestCase struct { type nameTemplateTestCase struct {

@ -17,11 +17,8 @@ limitations under the License.
package main package main
import ( import (
"io"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/hapi/release" "k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
) )
@ -30,99 +27,100 @@ func TestListCmd(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "with a release", name: "with a release",
cmd: "list",
rels: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
}, },
expected: "thomas-guide", matches: "thomas-guide",
}, },
{ {
name: "list", name: "list",
cmd: "list",
rels: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas"}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas"}),
}, },
expected: `NAME\s+REVISION\s+UPDATED\s+STATUS\s+CHART\s+NAMESPACE\natlas\s+1\s+(.*)\s+DEPLOYED\s+foo-0.1.0-beta.1\s+default`, matches: `NAME\s+REVISION\s+UPDATED\s+STATUS\s+CHART\s+NAMESPACE\natlas\s+1\s+(.*)\s+DEPLOYED\s+foo-0.1.0-beta.1\s+default`,
}, },
{ {
name: "list, one deployed, one failed", name: "list, one deployed, one failed",
flags: []string{"-q"}, cmd: "list -q",
rels: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_FAILED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_FAILED}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
}, },
expected: "thomas-guide\natlas-guide", matches: "thomas-guide\natlas-guide",
}, },
{ {
name: "with a release, multiple flags", name: "with a release, multiple flags",
flags: []string{"--deleted", "--deployed", "--failed", "-q"}, cmd: "list --deleted --deployed --failed -q",
rels: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETED}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
}, },
// Note: We're really only testing that the flags parsed correctly. Which results are returned // Note: We're really only testing that the flags parsed correctly. Which results are returned
// depends on the backend. And until pkg/helm is done, we can't mock this. // depends on the backend. And until pkg/helm is done, we can't mock this.
expected: "thomas-guide\natlas-guide", matches: "thomas-guide\natlas-guide",
}, },
{ {
name: "with a release, multiple flags", name: "with a release, multiple flags",
flags: []string{"--all", "-q"}, cmd: "list --all -q",
rels: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETED}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
}, },
// See note on previous test. // See note on previous test.
expected: "thomas-guide\natlas-guide", matches: "thomas-guide\natlas-guide",
}, },
{ {
name: "with a release, multiple flags, deleting", name: "with a release, multiple flags, deleting",
flags: []string{"--all", "-q"}, cmd: "list --all -q",
rels: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETING}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETING}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
}, },
// See note on previous test. // See note on previous test.
expected: "thomas-guide\natlas-guide", matches: "thomas-guide\natlas-guide",
}, },
{ {
name: "namespace defined, multiple flags", name: "namespace defined, multiple flags",
flags: []string{"--all", "-q", "--namespace test123"}, cmd: "list --all -q --namespace test123",
rels: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Namespace: "test123"}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Namespace: "test123"}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Namespace: "test321"}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Namespace: "test321"}),
}, },
// See note on previous test. // See note on previous test.
expected: "thomas-guide", matches: "thomas-guide",
}, },
{ {
name: "with a pending release, multiple flags", name: "with a pending release, multiple flags",
flags: []string{"--all", "-q"}, cmd: "list --all -q",
rels: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_PENDING_INSTALL}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_PENDING_INSTALL}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
}, },
expected: "thomas-guide\natlas-guide", matches: "thomas-guide\natlas-guide",
}, },
{ {
name: "with a pending release, pending flag", name: "with a pending release, pending flag",
flags: []string{"--pending", "-q"}, cmd: "list --pending -q",
rels: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_PENDING_INSTALL}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_PENDING_INSTALL}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "wild-idea", StatusCode: release.Status_PENDING_UPGRADE}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "wild-idea", StatusCode: release.Status_PENDING_UPGRADE}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-maps", StatusCode: release.Status_PENDING_ROLLBACK}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-maps", StatusCode: release.Status_PENDING_ROLLBACK}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
}, },
expected: "thomas-guide\nwild-idea\ncrazy-maps", matches: "thomas-guide\nwild-idea\ncrazy-maps",
}, },
{ {
name: "with old releases", name: "with old releases",
cmd: "list",
rels: []*release.Release{ rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_FAILED}), helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_FAILED}),
}, },
expected: "thomas-guide", matches: "thomas-guide",
}, },
} }
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { testReleaseCmd(t, tests)
return newListCmd(c, out)
})
} }

@ -17,56 +17,46 @@ limitations under the License.
package main package main
import ( import (
"io"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/hapi/release" "k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm"
) )
func TestReleaseTesting(t *testing.T) { func TestReleaseTesting(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "basic test", name: "basic test",
args: []string{"example-release"}, cmd: "test example-release",
flags: []string{},
responses: map[string]release.TestRunStatus{"PASSED: green lights everywhere": release.TestRun_SUCCESS}, responses: map[string]release.TestRunStatus{"PASSED: green lights everywhere": release.TestRun_SUCCESS},
err: false, wantError: false,
}, },
{ {
name: "test failure", name: "test failure",
args: []string{"example-fail"}, cmd: "test example-fail",
flags: []string{},
responses: map[string]release.TestRunStatus{"FAILURE: red lights everywhere": release.TestRun_FAILURE}, responses: map[string]release.TestRunStatus{"FAILURE: red lights everywhere": release.TestRun_FAILURE},
err: true, wantError: true,
}, },
{ {
name: "test unknown", name: "test unknown",
args: []string{"example-unknown"}, cmd: "test example-unknown",
flags: []string{},
responses: map[string]release.TestRunStatus{"UNKNOWN: yellow lights everywhere": release.TestRun_UNKNOWN}, responses: map[string]release.TestRunStatus{"UNKNOWN: yellow lights everywhere": release.TestRun_UNKNOWN},
err: false, wantError: false,
}, },
{ {
name: "test error", name: "test error",
args: []string{"example-error"}, cmd: "test example-error",
flags: []string{},
responses: map[string]release.TestRunStatus{"ERROR: yellow lights everywhere": release.TestRun_FAILURE}, responses: map[string]release.TestRunStatus{"ERROR: yellow lights everywhere": release.TestRun_FAILURE},
err: true, wantError: true,
}, },
{ {
name: "test running", name: "test running",
args: []string{"example-running"}, cmd: "test example-running",
flags: []string{},
responses: map[string]release.TestRunStatus{"RUNNING: things are happpeningggg": release.TestRun_RUNNING}, responses: map[string]release.TestRunStatus{"RUNNING: things are happpeningggg": release.TestRun_RUNNING},
err: false, wantError: false,
}, },
{ {
name: "multiple tests example", name: "multiple tests example",
args: []string{"example-suite"}, cmd: "test example-suite",
flags: []string{},
responses: map[string]release.TestRunStatus{ responses: map[string]release.TestRunStatus{
"RUNNING: things are happpeningggg": release.TestRun_RUNNING, "RUNNING: things are happpeningggg": release.TestRun_RUNNING,
"PASSED: party time": release.TestRun_SUCCESS, "PASSED: party time": release.TestRun_SUCCESS,
@ -74,11 +64,8 @@ func TestReleaseTesting(t *testing.T) {
"FAILURE: good thing u checked :)": release.TestRun_FAILURE, "FAILURE: good thing u checked :)": release.TestRun_FAILURE,
"RUNNING: things are happpeningggg yet again": release.TestRun_RUNNING, "RUNNING: things are happpeningggg yet again": release.TestRun_RUNNING,
"PASSED: feel free to party again": release.TestRun_SUCCESS}, "PASSED: feel free to party again": release.TestRun_SUCCESS},
err: true, wantError: true,
}, },
} }
testReleaseCmd(t, tests)
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command {
return newReleaseTestCmd(c, out)
})
} }

@ -17,13 +17,10 @@ limitations under the License.
package main package main
import ( import (
"io" "fmt"
"os" "os"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/repo" "k8s.io/helm/pkg/repo"
"k8s.io/helm/pkg/repo/repotest" "k8s.io/helm/pkg/repo/repotest"
) )
@ -48,17 +45,13 @@ func TestRepoAddCmd(t *testing.T) {
settings.Home = thome settings.Home = thome
tests := []releaseCase{ tests := []releaseCase{{
{ name: "add a repository",
name: "add a repository", cmd: fmt.Sprintf("repo add %s %s --home %s", testName, srv.URL(), thome),
args: []string{testName, srv.URL()}, matches: "\"" + testName + "\" has been added to your repositories",
expected: "\"" + testName + "\" has been added to your repositories", }}
},
}
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { testReleaseCmd(t, tests)
return newRepoAddCmd(out)
})
} }
func TestRepoAdd(t *testing.T) { func TestRepoAdd(t *testing.T) {

@ -17,45 +17,32 @@ limitations under the License.
package main package main
import ( import (
"io"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/helm"
) )
func TestRollbackCmd(t *testing.T) { func TestRollbackCmd(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "rollback a release", name: "rollback a release",
args: []string{"funny-honey", "1"}, cmd: "rollback funny-honey 1",
expected: "Rollback was a success! Happy Helming!", matches: "Rollback was a success! Happy Helming!",
}, },
{ {
name: "rollback a release with timeout", name: "rollback a release with timeout",
args: []string{"funny-honey", "1"}, cmd: "rollback funny-honey 1 --timeout 120",
flags: []string{"--timeout", "120"}, matches: "Rollback was a success! Happy Helming!",
expected: "Rollback was a success! Happy Helming!",
}, },
{ {
name: "rollback a release with wait", name: "rollback a release with wait",
args: []string{"funny-honey", "1"}, cmd: "rollback funny-honey 1 --wait",
flags: []string{"--wait"}, matches: "Rollback was a success! Happy Helming!",
expected: "Rollback was a success! Happy Helming!",
}, },
{ {
name: "rollback a release without revision", name: "rollback a release without revision",
args: []string{"funny-honey"}, cmd: "rollback funny-honey",
err: true, wantError: true,
}, },
} }
testReleaseCmd(t, tests)
cmd := func(c *helm.FakeClient, out io.Writer) *cobra.Command {
return newRollbackCmd(c, out)
}
runReleaseCases(t, tests, cmd)
} }

@ -236,36 +236,38 @@ func TestSearchByName(t *testing.T) {
i := loadTestIndex(t, false) i := loadTestIndex(t, false)
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
charts, err := i.Search(tt.query, 100, tt.regexp) charts, err := i.Search(tt.query, 100, tt.regexp)
if err != nil { if err != nil {
if tt.fail { if tt.fail {
if !strings.Contains(err.Error(), tt.failMsg) { if !strings.Contains(err.Error(), tt.failMsg) {
t.Fatalf("%s: Unexpected error message: %s", tt.name, err) t.Fatalf("Unexpected error message: %s", err)
}
return
} }
continue t.Fatalf("%s: %s", tt.name, err)
} }
t.Fatalf("%s: %s", tt.name, err) // Give us predictably ordered results.
} SortScore(charts)
// Give us predictably ordered results.
SortScore(charts)
l := len(charts) l := len(charts)
if l != len(tt.expect) { if l != len(tt.expect) {
t.Fatalf("%s: Expected %d result, got %d", tt.name, len(tt.expect), l) t.Fatalf("Expected %d result, got %d", len(tt.expect), l)
} }
// For empty result sets, just keep going. // For empty result sets, just keep going.
if l == 0 { if l == 0 {
continue return
} }
for i, got := range charts { for i, got := range charts {
ex := tt.expect[i] ex := tt.expect[i]
if got.Name != ex.Name { if got.Name != ex.Name {
t.Errorf("%s[%d]: Expected name %q, got %q", tt.name, i, ex.Name, got.Name) t.Errorf("[%d]: Expected name %q, got %q", i, ex.Name, got.Name)
}
} }
}
})
} }
} }

@ -17,72 +17,60 @@ limitations under the License.
package main package main
import ( import (
"io"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/helm"
) )
func TestSearchCmd(t *testing.T) { func TestSearchCmd(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "search for 'maria', expect one match", name: "search for 'maria', expect one match",
args: []string{"maria"}, cmd: "search maria",
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/mariadb\t0.3.0 \t \tChart for MariaDB", matches: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/mariadb\t0.3.0 \t \tChart for MariaDB",
}, },
{ {
name: "search for 'alpine', expect two matches", name: "search for 'alpine', expect two matches",
args: []string{"alpine"}, cmd: "search alpine",
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod", matches: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod",
}, },
{ {
name: "search for 'alpine' with versions, expect three matches", name: "search for 'alpine' with versions, expect three matches",
args: []string{"alpine"}, cmd: "search alpine --versions",
flags: []string{"--versions"}, matches: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod\ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod",
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod\ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod",
}, },
{ {
name: "search for 'alpine' with version constraint, expect one match with version 0.1.0", name: "search for 'alpine' with version constraint, expect one match with version 0.1.0",
args: []string{"alpine"}, cmd: "search alpine --version '>= 0.1, < 0.2'",
flags: []string{"--version", ">= 0.1, < 0.2"}, matches: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod",
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod",
}, },
{ {
name: "search for 'alpine' with version constraint, expect one match with version 0.1.0", name: "search for 'alpine' with version constraint, expect one match with version 0.1.0",
args: []string{"alpine"}, cmd: "search alpine --versions --version '>= 0.1, < 0.2'",
flags: []string{"--versions", "--version", ">= 0.1, < 0.2"}, matches: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod",
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod",
}, },
{ {
name: "search for 'alpine' with version constraint, expect one match with version 0.2.0", name: "search for 'alpine' with version constraint, expect one match with version 0.2.0",
args: []string{"alpine"}, cmd: "search alpine --version '>= 0.1'",
flags: []string{"--version", ">= 0.1"}, matches: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod",
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod",
}, },
{ {
name: "search for 'alpine' with version constraint and --versions, expect two matches", name: "search for 'alpine' with version constraint and --versions, expect two matches",
args: []string{"alpine"}, cmd: "search alpine --versions --version '>= 0.1'",
flags: []string{"--versions", "--version", ">= 0.1"}, matches: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod\ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod",
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod\ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod",
}, },
{ {
name: "search for 'syzygy', expect no matches", name: "search for 'syzygy', expect no matches",
args: []string{"syzygy"}, cmd: "search syzygy",
expected: "No results found", matches: "No results found",
}, },
{ {
name: "search for 'alp[a-z]+', expect two matches", name: "search for 'alp[a-z]+', expect two matches",
args: []string{"alp[a-z]+"}, cmd: "search alp[a-z]+ --regexp",
flags: []string{"--regexp"}, matches: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod",
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod",
}, },
{ {
name: "search for 'alp[', expect failure to compile regexp", name: "search for 'alp[', expect failure to compile regexp",
args: []string{"alp["}, cmd: "search alp[ --regexp",
flags: []string{"--regexp"}, wantError: true,
err: true,
}, },
} }
@ -90,8 +78,5 @@ func TestSearchCmd(t *testing.T) {
defer cleanup() defer cleanup()
settings.Home = "testdata/helmhome" settings.Home = "testdata/helmhome"
testReleaseCmd(t, tests)
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command {
return newSearchCmd(out)
})
} }

@ -18,22 +18,18 @@ package main
import ( import (
"fmt" "fmt"
"io"
"testing" "testing"
"time" "time"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/hapi/release" "k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm"
) )
func TestStatusCmd(t *testing.T) { func TestStatusCmd(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "get status of a deployed release", name: "get status of a deployed release",
args: []string{"flummoxed-chickadee"}, cmd: "status flummoxed-chickadee",
expected: outputWithStatus("DEPLOYED"), matches: outputWithStatus("DEPLOYED"),
rels: []*release.Release{ rels: []*release.Release{
releaseMockWithStatus(&release.Status{ releaseMockWithStatus(&release.Status{
Code: release.Status_DEPLOYED, Code: release.Status_DEPLOYED,
@ -41,9 +37,9 @@ func TestStatusCmd(t *testing.T) {
}, },
}, },
{ {
name: "get status of a deployed release with notes", name: "get status of a deployed release with notes",
args: []string{"flummoxed-chickadee"}, cmd: "status flummoxed-chickadee",
expected: outputWithStatus("DEPLOYED\n\nNOTES:\nrelease notes\n"), matches: outputWithStatus("DEPLOYED\n\nNOTES:\nrelease notes\n"),
rels: []*release.Release{ rels: []*release.Release{
releaseMockWithStatus(&release.Status{ releaseMockWithStatus(&release.Status{
Code: release.Status_DEPLOYED, Code: release.Status_DEPLOYED,
@ -52,10 +48,9 @@ func TestStatusCmd(t *testing.T) {
}, },
}, },
{ {
name: "get status of a deployed release with notes in json", name: "get status of a deployed release with notes in json",
args: []string{"flummoxed-chickadee"}, cmd: "status flummoxed-chickadee -o json",
flags: []string{"-o", "json"}, matches: `{"name":"flummoxed-chickadee","info":{"status":{"code":1,"notes":"release notes"},"first_deployed":(.*),"last_deployed":(.*)}}`,
expected: `{"name":"flummoxed-chickadee","info":{"status":{"code":1,"notes":"release notes"},"first_deployed":(.*),"last_deployed":(.*)}}`,
rels: []*release.Release{ rels: []*release.Release{
releaseMockWithStatus(&release.Status{ releaseMockWithStatus(&release.Status{
Code: release.Status_DEPLOYED, Code: release.Status_DEPLOYED,
@ -64,9 +59,9 @@ func TestStatusCmd(t *testing.T) {
}, },
}, },
{ {
name: "get status of a deployed release with resources", name: "get status of a deployed release with resources",
args: []string{"flummoxed-chickadee"}, cmd: "status flummoxed-chickadee",
expected: outputWithStatus("DEPLOYED\n\nRESOURCES:\nresource A\nresource B\n\n"), matches: outputWithStatus("DEPLOYED\n\nRESOURCES:\nresource A\nresource B\n\n"),
rels: []*release.Release{ rels: []*release.Release{
releaseMockWithStatus(&release.Status{ releaseMockWithStatus(&release.Status{
Code: release.Status_DEPLOYED, Code: release.Status_DEPLOYED,
@ -75,10 +70,9 @@ func TestStatusCmd(t *testing.T) {
}, },
}, },
{ {
name: "get status of a deployed release with resources in YAML", name: "get status of a deployed release with resources in YAML",
args: []string{"flummoxed-chickadee"}, cmd: "status flummoxed-chickadee -o yaml",
flags: []string{"-o", "yaml"}, matches: "info:\n (.*)first_deployed:\n (.*)seconds: 242085845\n (.*)last_deployed:\n (.*)seconds: 242085845\n (.*)status:\n code: 1\n (.*)resources: |\n (.*)resource A\n (.*)resource B\nname: flummoxed-chickadee\n",
expected: "info:\n (.*)first_deployed:\n (.*)seconds: 242085845\n (.*)last_deployed:\n (.*)seconds: 242085845\n (.*)status:\n code: 1\n (.*)resources: |\n (.*)resource A\n (.*)resource B\nname: flummoxed-chickadee\n",
rels: []*release.Release{ rels: []*release.Release{
releaseMockWithStatus(&release.Status{ releaseMockWithStatus(&release.Status{
Code: release.Status_DEPLOYED, Code: release.Status_DEPLOYED,
@ -88,8 +82,8 @@ func TestStatusCmd(t *testing.T) {
}, },
{ {
name: "get status of a deployed release with test suite", name: "get status of a deployed release with test suite",
args: []string{"flummoxed-chickadee"}, cmd: "status flummoxed-chickadee",
expected: outputWithStatus( matches: outputWithStatus(
"DEPLOYED\n\nTEST SUITE:\nLast Started: (.*)\nLast Completed: (.*)\n\n" + "DEPLOYED\n\nTEST SUITE:\nLast Started: (.*)\nLast Completed: (.*)\n\n" +
"TEST \tSTATUS (.*)\tINFO (.*)\tSTARTED (.*)\tCOMPLETED (.*)\n" + "TEST \tSTATUS (.*)\tINFO (.*)\tSTARTED (.*)\tCOMPLETED (.*)\n" +
"test run 1\tSUCCESS (.*)\textra info\t(.*)\t(.*)\n" + "test run 1\tSUCCESS (.*)\textra info\t(.*)\t(.*)\n" +
@ -120,11 +114,7 @@ func TestStatusCmd(t *testing.T) {
}, },
}, },
} }
testReleaseCmd(t, tests)
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command {
return newStatusCmd(c, out)
})
} }
func outputWithStatus(status string) string { func outputWithStatus(status string) string {

@ -17,14 +17,11 @@ limitations under the License.
package main package main
import ( import (
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/hapi/chart" "k8s.io/helm/pkg/hapi/chart"
"k8s.io/helm/pkg/hapi/release" "k8s.io/helm/pkg/hapi/release"
@ -91,80 +88,73 @@ func TestUpgradeCmd(t *testing.T) {
t.Errorf("Error loading chart with missing dependencies: %v", err) t.Errorf("Error loading chart with missing dependencies: %v", err)
} }
relMock := func(n string, v int, ch *chart.Chart) *release.Release {
return helm.ReleaseMock(&helm.MockReleaseOptions{Name: n, Version: v, Chart: ch})
}
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "upgrade a release", name: "upgrade a release",
args: []string{"funny-bunny", chartPath}, cmd: "upgrade funny-bunny " + chartPath,
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 2, Chart: ch}), resp: relMock("funny-bunny", 2, ch),
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n", matches: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 2, Chart: ch})}, rels: []*release.Release{relMock("funny-bunny", 2, ch)},
}, },
{ {
name: "upgrade a release with timeout", name: "upgrade a release with timeout",
args: []string{"funny-bunny", chartPath}, cmd: "upgrade funny-bunny --timeout 120 " + chartPath,
flags: []string{"--timeout", "120"}, resp: relMock("funny-bunny", 3, ch2),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 3, Chart: ch2}), matches: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n", rels: []*release.Release{relMock("funny-bunny", 3, ch2)},
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 3, Chart: ch2})},
}, },
{ {
name: "upgrade a release with --reset-values", name: "upgrade a release with --reset-values",
args: []string{"funny-bunny", chartPath}, cmd: "upgrade funny-bunny --reset-values " + chartPath,
flags: []string{"--reset-values", "true"}, resp: relMock("funny-bunny", 4, ch2),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 4, Chart: ch2}), matches: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n", rels: []*release.Release{relMock("funny-bunny", 4, ch2)},
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 4, Chart: ch2})},
}, },
{ {
name: "upgrade a release with --reuse-values", name: "upgrade a release with --reuse-values",
args: []string{"funny-bunny", chartPath}, cmd: "upgrade funny-bunny --reuse-values " + chartPath,
flags: []string{"--reuse-values", "true"}, resp: relMock("funny-bunny", 5, ch2),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 5, Chart: ch2}), matches: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"funny-bunny\" has been upgraded. Happy Helming!\n", rels: []*release.Release{relMock("funny-bunny", 5, ch2)},
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "funny-bunny", Version: 5, Chart: ch2})},
}, },
{ {
name: "install a release with 'upgrade --install'", name: "install a release with 'upgrade --install'",
args: []string{"zany-bunny", chartPath}, cmd: "upgrade zany-bunny -i " + chartPath,
flags: []string{"-i"}, resp: relMock("zany-bunny", 1, ch),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "zany-bunny", Version: 1, Chart: ch}), matches: "Release \"zany-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"zany-bunny\" has been upgraded. Happy Helming!\n", rels: []*release.Release{relMock("zany-bunny", 1, ch)},
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "zany-bunny", Version: 1, Chart: ch})},
}, },
{ {
name: "install a release with 'upgrade --install' and timeout", name: "install a release with 'upgrade --install' and timeout",
args: []string{"crazy-bunny", chartPath}, cmd: "upgrade crazy-bunny -i --timeout 120 " + chartPath,
flags: []string{"-i", "--timeout", "120"}, resp: relMock("crazy-bunny", 1, ch),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch}), matches: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n", rels: []*release.Release{relMock("crazy-bunny", 1, ch)},
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 1, Chart: ch})},
}, },
{ {
name: "upgrade a release with wait", name: "upgrade a release with wait",
args: []string{"crazy-bunny", chartPath}, cmd: "upgrade crazy-bunny --wait " + chartPath,
flags: []string{"--wait"}, resp: relMock("crazy-bunny", 2, ch2),
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2}), matches: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n",
expected: "Release \"crazy-bunny\" has been upgraded. Happy Helming!\n", rels: []*release.Release{relMock("crazy-bunny", 2, ch2)},
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "crazy-bunny", Version: 2, Chart: ch2})},
}, },
{ {
name: "upgrade a release with missing dependencies", name: "upgrade a release with missing dependencies",
args: []string{"bonkers-bunny", missingDepsPath}, cmd: "upgrade bonkers-bunny" + missingDepsPath,
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "bonkers-bunny", Version: 1, Chart: ch3}), resp: relMock("bonkers-bunny", 1, ch3),
err: true, wantError: true,
}, },
{ {
name: "upgrade a release with bad dependencies", name: "upgrade a release with bad dependencies",
args: []string{"bonkers-bunny", badDepsPath}, cmd: "upgrade bonkers-bunny " + badDepsPath,
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "bonkers-bunny", Version: 1, Chart: ch3}), resp: relMock("bonkers-bunny", 1, ch3),
err: true, wantError: true,
}, },
} }
testReleaseCmd(t, tests)
cmd := func(c *helm.FakeClient, out io.Writer) *cobra.Command {
return newUpgradeCmd(c, out)
}
runReleaseCases(t, tests, cmd)
} }

@ -17,13 +17,9 @@ package main
import ( import (
"fmt" "fmt"
"io"
"regexp" "regexp"
"testing" "testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/version" "k8s.io/helm/pkg/version"
) )
@ -33,18 +29,15 @@ func TestVersion(t *testing.T) {
tests := []releaseCase{ tests := []releaseCase{
{ {
name: "default", name: "default",
args: []string{}, cmd: "version",
expected: clientVersion, matches: clientVersion,
}, },
{ {
name: "template", name: "template",
args: []string{}, cmd: "version --template='{{.Client.SemVer}}'",
flags: []string{"--template", "{{ .Client.SemVer }}"}, matches: lver,
expected: lver,
}, },
} }
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command { testReleaseCmd(t, tests)
return newVersionCmd(out)
})
} }

Loading…
Cancel
Save