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

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

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

@ -42,9 +42,10 @@ var errReleaseRequired = errors.New("release name is required")
type getCmd struct {
release string
version int
out io.Writer
client helm.Interface
version int
}
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.AddCommand(newGetValuesCmd(nil, out))
cmd.AddCommand(newGetManifestCmd(nil, out))
cmd.AddCommand(newGetHooksCmd(nil, out))
cmd.AddCommand(newGetValuesCmd(client, out))
cmd.AddCommand(newGetManifestCmd(client, out))
cmd.AddCommand(newGetHooksCmd(client, out))
return cmd
}

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

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

@ -17,11 +17,8 @@ limitations under the License.
package main
import (
"io"
"testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm"
)
@ -30,19 +27,16 @@ func TestGetCmd(t *testing.T) {
tests := []releaseCase{
{
name: "get with a release",
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
args: []string{"thomas-guide"},
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:",
cmd: "get 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:",
rels: []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"})},
resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
},
{
name: "get requires release name arg",
err: true,
cmd: "get",
wantError: true,
},
}
cmd := func(c *helm.FakeClient, out io.Writer) *cobra.Command {
return newGetCmd(c, out)
}
runReleaseCases(t, tests, cmd)
testReleaseCmd(t, tests)
}

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

@ -18,6 +18,7 @@ package main // import "k8s.io/helm/cmd/helm"
import (
"fmt"
"io"
"log"
"os"
"strings"
@ -61,7 +62,7 @@ Environment:
$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{
Use: "helm",
Short: "The Helm package manager for Kubernetes.",
@ -72,8 +73,6 @@ func newRootCmd(args []string) *cobra.Command {
settings.AddFlags(flags)
out := cmd.OutOrStdout()
cmd.AddCommand(
// chart commands
newCreateCmd(out),
@ -87,15 +86,15 @@ func newRootCmd(args []string) *cobra.Command {
newVerifyCmd(out),
// release commands
newDeleteCmd(nil, out),
newGetCmd(nil, out),
newHistoryCmd(nil, out),
newInstallCmd(nil, out),
newListCmd(nil, out),
newReleaseTestCmd(nil, out),
newRollbackCmd(nil, out),
newStatusCmd(nil, out),
newUpgradeCmd(nil, out),
newDeleteCmd(c, out),
newGetCmd(c, out),
newHistoryCmd(c, out),
newInstallCmd(c, out),
newListCmd(c, out),
newReleaseTestCmd(c, out),
newRollbackCmd(c, out),
newStatusCmd(c, out),
newUpgradeCmd(c, out),
newCompletionCmd(out),
newHomeCmd(out),
@ -131,7 +130,7 @@ func logf(format string, v ...interface{}) {
}
func main() {
cmd := newRootCmd(os.Args[1:])
cmd := newRootCmd(nil, os.Stdout, os.Args[1:])
if err := cmd.Execute(); err != nil {
os.Exit(1)
}

@ -19,7 +19,6 @@ package main
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
@ -27,6 +26,7 @@ import (
"strings"
"testing"
shellwords "github.com/mattn/go-shellwords"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/hapi/release"
@ -35,29 +35,41 @@ import (
"k8s.io/helm/pkg/repo"
)
// releaseCmd is a command that works with a FakeClient
type releaseCmd func(c *helm.FakeClient, out io.Writer) *cobra.Command
func executeCommand(c helm.Interface, cmd string) (string, error) {
_, 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()
// runReleaseCases runs a set of release cases through the given releaseCmd.
func runReleaseCases(t *testing.T, tests []releaseCase, rcmd releaseCmd) {
var buf bytes.Buffer
return c, buf.String(), err
}
func testReleaseCmd(t *testing.T, tests []releaseCase) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &helm.FakeClient{
Rels: tt.rels,
Responses: tt.responses,
}
cmd := rcmd(c, &buf)
cmd.ParseFlags(tt.flags)
err := cmd.RunE(cmd, tt.args)
if (err != nil) != tt.err {
out, err := executeCommand(c, tt.cmd)
if (err != nil) != tt.wantError {
t.Errorf("expected error, got '%v'", err)
}
re := regexp.MustCompile(tt.expected)
if !re.Match(buf.Bytes()) {
t.Errorf("expected\n%q\ngot\n%q", tt.expected, buf.String())
re := regexp.MustCompile(tt.matches)
if !re.MatchString(out) {
t.Errorf("expected\n%q\ngot\n%q", tt.matches, out)
}
buf.Reset()
})
}
}
@ -65,11 +77,10 @@ func runReleaseCases(t *testing.T, tests []releaseCase, rcmd releaseCmd) {
// releaseCase describes a test case that works with releases.
type releaseCase struct {
name string
args []string
flags []string
// expected is the string to be matched. This supports regular expressions.
expected string
err bool
cmd string
// matches is the string to be matched. This supports regular expressions.
matches string
wantError bool
resp *release.Release
// Rels are the available releases at the start of the test.
rels []*release.Release
@ -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
}
@ -141,41 +152,39 @@ func TestRootCmd(t *testing.T) {
defer cleanup()
tests := []struct {
name string
args []string
name, args, home string
envars map[string]string
home string
}{
{
name: "defaults",
args: []string{"home"},
args: "home",
home: filepath.Join(os.Getenv("HOME"), "/.helm"),
},
{
name: "with --home set",
args: []string{"--home", "/foo"},
args: "--home /foo",
home: "/foo",
},
{
name: "subcommands with --home set",
args: []string{"home", "--home", "/foo"},
args: "home --home /foo",
home: "/foo",
},
{
name: "with $HELM_HOME set",
args: []string{"home"},
args: "home",
envars: map[string]string{"HELM_HOME": "/bar"},
home: "/bar",
},
{
name: "subcommands with $HELM_HOME set",
args: []string{"home"},
args: "home",
envars: map[string]string{"HELM_HOME": "/bar"},
home: "/bar",
},
{
name: "with $HELM_HOME and --home set",
args: []string{"home", "--home", "/foo"},
args: "home --home /foo",
envars: map[string]string{"HELM_HOME": "/bar"},
home: "/foo",
},
@ -192,12 +201,9 @@ func TestRootCmd(t *testing.T) {
os.Setenv(k, v)
}
cmd := newRootCmd(tt.args)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tt.args)
cmd.Run = func(*cobra.Command, []string) {}
if err := cmd.Execute(); err != nil {
t.Errorf("unexpected error: %s", err)
cmd, _, err := executeCommandC(nil, tt.args)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
if settings.Home.String() != tt.home {

@ -17,11 +17,8 @@ limitations under the License.
package main
import (
"io"
"testing"
"github.com/spf13/cobra"
rpb "k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm"
)
@ -38,48 +35,42 @@ func TestHistoryCmd(t *testing.T) {
tests := []releaseCase{
{
name: "get history for release",
args: []string{"angry-bird"},
cmd: "history angry-bird",
rels: []*rpb.Release{
mk("angry-bird", 4, rpb.Status_DEPLOYED),
mk("angry-bird", 3, rpb.Status_SUPERSEDED),
mk("angry-bird", 2, 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",
args: []string{"angry-bird"},
flags: []string{"--max", "2"},
cmd: "history angry-bird --max 2",
rels: []*rpb.Release{
mk("angry-bird", 4, rpb.Status_DEPLOYED),
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",
args: []string{"angry-bird"},
flags: []string{"--output", "yaml"},
cmd: "history angry-bird --output yaml",
rels: []*rpb.Release{
mk("angry-bird", 4, rpb.Status_DEPLOYED),
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",
args: []string{"angry-bird"},
flags: []string{"--output", "json"},
cmd: "history angry-bird --output json",
rels: []*rpb.Release{
mk("angry-bird", 4, rpb.Status_DEPLOYED),
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`,
},
}
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command {
return newHistoryCmd(c, out)
})
testReleaseCmd(t, tests)
}

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

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

@ -17,11 +17,8 @@ limitations under the License.
package main
import (
"io"
"testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/hapi/release"
"k8s.io/helm/pkg/helm"
)
@ -30,99 +27,100 @@ func TestListCmd(t *testing.T) {
tests := []releaseCase{
{
name: "with a release",
cmd: "list",
rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
},
expected: "thomas-guide",
matches: "thomas-guide",
},
{
name: "list",
cmd: "list",
rels: []*release.Release{
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",
flags: []string{"-q"},
cmd: "list -q",
rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_FAILED}),
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",
flags: []string{"--deleted", "--deployed", "--failed", "-q"},
cmd: "list --deleted --deployed --failed -q",
rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETED}),
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
// 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",
flags: []string{"--all", "-q"},
cmd: "list --all -q",
rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETED}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
},
// See note on previous test.
expected: "thomas-guide\natlas-guide",
matches: "thomas-guide\natlas-guide",
},
{
name: "with a release, multiple flags, deleting",
flags: []string{"--all", "-q"},
cmd: "list --all -q",
rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_DELETING}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", StatusCode: release.Status_DEPLOYED}),
},
// See note on previous test.
expected: "thomas-guide\natlas-guide",
matches: "thomas-guide\natlas-guide",
},
{
name: "namespace defined, multiple flags",
flags: []string{"--all", "-q", "--namespace test123"},
cmd: "list --all -q --namespace test123",
rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", Namespace: "test123"}),
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "atlas-guide", Namespace: "test321"}),
},
// See note on previous test.
expected: "thomas-guide",
matches: "thomas-guide",
},
{
name: "with a pending release, multiple flags",
flags: []string{"--all", "-q"},
cmd: "list --all -q",
rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide", StatusCode: release.Status_PENDING_INSTALL}),
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",
flags: []string{"--pending", "-q"},
cmd: "list --pending -q",
rels: []*release.Release{
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: "crazy-maps", StatusCode: release.Status_PENDING_ROLLBACK}),
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",
cmd: "list",
rels: []*release.Release{
helm.ReleaseMock(&helm.MockReleaseOptions{Name: "thomas-guide"}),
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 {
return newListCmd(c, out)
})
testReleaseCmd(t, tests)
}

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

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

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

@ -236,14 +236,15 @@ func TestSearchByName(t *testing.T) {
i := loadTestIndex(t, false)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
charts, err := i.Search(tt.query, 100, tt.regexp)
if err != nil {
if tt.fail {
if !strings.Contains(err.Error(), tt.failMsg) {
t.Fatalf("%s: Unexpected error message: %s", tt.name, err)
t.Fatalf("Unexpected error message: %s", err)
}
continue
return
}
t.Fatalf("%s: %s", tt.name, err)
}
@ -252,20 +253,21 @@ func TestSearchByName(t *testing.T) {
l := len(charts)
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.
if l == 0 {
continue
return
}
for i, got := range charts {
ex := tt.expect[i]
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
import (
"io"
"testing"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/helm"
)
func TestSearchCmd(t *testing.T) {
tests := []releaseCase{
{
name: "search for 'maria', expect one match",
args: []string{"maria"},
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/mariadb\t0.3.0 \t \tChart for MariaDB",
cmd: "search maria",
matches: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/mariadb\t0.3.0 \t \tChart for MariaDB",
},
{
name: "search for 'alpine', expect two matches",
args: []string{"alpine"},
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod",
cmd: "search alpine",
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",
args: []string{"alpine"},
flags: []string{"--versions"},
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",
cmd: "search alpine --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",
},
{
name: "search for 'alpine' with version constraint, expect one match with version 0.1.0",
args: []string{"alpine"},
flags: []string{"--version", ">= 0.1, < 0.2"},
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod",
cmd: "search alpine --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",
},
{
name: "search for 'alpine' with version constraint, expect one match with version 0.1.0",
args: []string{"alpine"},
flags: []string{"--versions", "--version", ">= 0.1, < 0.2"},
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.1.0 \t1.2.3 \tDeploy a basic Alpine Linux pod",
cmd: "search alpine --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",
},
{
name: "search for 'alpine' with version constraint, expect one match with version 0.2.0",
args: []string{"alpine"},
flags: []string{"--version", ">= 0.1"},
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod",
cmd: "search alpine --version '>= 0.1'",
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 version constraint and --versions, expect two matches",
args: []string{"alpine"},
flags: []string{"--versions", "--version", ">= 0.1"},
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",
cmd: "search alpine --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",
},
{
name: "search for 'syzygy', expect no matches",
args: []string{"syzygy"},
expected: "No results found",
cmd: "search syzygy",
matches: "No results found",
},
{
name: "search for 'alp[a-z]+', expect two matches",
args: []string{"alp[a-z]+"},
flags: []string{"--regexp"},
expected: "NAME \tCHART VERSION\tAPP VERSION\tDESCRIPTION \ntesting/alpine\t0.2.0 \t2.3.4 \tDeploy a basic Alpine Linux pod",
cmd: "search alp[a-z]+ --regexp",
matches: "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",
args: []string{"alp["},
flags: []string{"--regexp"},
err: true,
cmd: "search alp[ --regexp",
wantError: true,
},
}
@ -90,8 +78,5 @@ func TestSearchCmd(t *testing.T) {
defer cleanup()
settings.Home = "testdata/helmhome"
runReleaseCases(t, tests, func(c *helm.FakeClient, out io.Writer) *cobra.Command {
return newSearchCmd(out)
})
testReleaseCmd(t, tests)
}

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

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

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

Loading…
Cancel
Save