github.com/danielqsj/helm@v2.0.0-alpha.4.0.20160908204436-976e0ba5199b+incompatible/cmd/helm/helm_test.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors All rights reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "bytes" 21 "fmt" 22 "io" 23 "math/rand" 24 "regexp" 25 "testing" 26 27 "github.com/golang/protobuf/ptypes/timestamp" 28 "github.com/spf13/cobra" 29 30 "k8s.io/helm/pkg/helm" 31 "k8s.io/helm/pkg/proto/hapi/chart" 32 "k8s.io/helm/pkg/proto/hapi/release" 33 rls "k8s.io/helm/pkg/proto/hapi/services" 34 ) 35 36 var mockHookTemplate = `apiVersion: v1 37 kind: Job 38 metadata: 39 annotations: 40 "helm.sh/hooks": pre-install 41 ` 42 43 var mockManifest = `apiVersion: v1 44 kind: Secret 45 metadata: 46 name: fixture 47 ` 48 49 type releaseOptions struct { 50 name string 51 version int32 52 chart *chart.Chart 53 statusCode release.Status_Code 54 } 55 56 func releaseMock(opts *releaseOptions) *release.Release { 57 date := timestamp.Timestamp{Seconds: 242085845, Nanos: 0} 58 59 name := opts.name 60 if name == "" { 61 name = "testrelease-" + string(rand.Intn(100)) 62 } 63 64 var version int32 = 1 65 if opts.version != 0 { 66 version = opts.version 67 } 68 69 ch := opts.chart 70 if opts.chart == nil { 71 ch = &chart.Chart{ 72 Metadata: &chart.Metadata{ 73 Name: "foo", 74 Version: "0.1.0-beta.1", 75 }, 76 Templates: []*chart.Template{ 77 {Name: "foo.tpl", Data: []byte(mockManifest)}, 78 }, 79 } 80 } 81 82 scode := release.Status_DEPLOYED 83 if opts.statusCode > 0 { 84 scode = opts.statusCode 85 } 86 87 return &release.Release{ 88 Name: name, 89 Info: &release.Info{ 90 FirstDeployed: &date, 91 LastDeployed: &date, 92 Status: &release.Status{Code: scode}, 93 }, 94 Chart: ch, 95 Config: &chart.Config{Raw: `name: "value"`}, 96 Version: version, 97 Hooks: []*release.Hook{ 98 { 99 Name: "pre-install-hook", 100 Kind: "Job", 101 Path: "pre-install-hook.yaml", 102 Manifest: mockHookTemplate, 103 LastRun: &date, 104 Events: []release.Hook_Event{release.Hook_PRE_INSTALL}, 105 }, 106 }, 107 Manifest: mockManifest, 108 } 109 } 110 111 type fakeReleaseClient struct { 112 rels []*release.Release 113 err error 114 } 115 116 var _ helm.Interface = &fakeReleaseClient{} 117 var _ helm.Interface = &helm.Client{} 118 119 func (c *fakeReleaseClient) ListReleases(opts ...helm.ReleaseListOption) (*rls.ListReleasesResponse, error) { 120 resp := &rls.ListReleasesResponse{ 121 Count: int64(len(c.rels)), 122 Releases: c.rels, 123 } 124 return resp, c.err 125 } 126 127 func (c *fakeReleaseClient) InstallRelease(chStr, ns string, opts ...helm.InstallOption) (*rls.InstallReleaseResponse, error) { 128 return &rls.InstallReleaseResponse{ 129 Release: c.rels[0], 130 }, nil 131 } 132 133 func (c *fakeReleaseClient) DeleteRelease(rlsName string, opts ...helm.DeleteOption) (*rls.UninstallReleaseResponse, error) { 134 return nil, nil 135 } 136 137 func (c *fakeReleaseClient) ReleaseStatus(rlsName string, opts ...helm.StatusOption) (*rls.GetReleaseStatusResponse, error) { 138 if c.rels[0] != nil { 139 return &rls.GetReleaseStatusResponse{ 140 Name: c.rels[0].Name, 141 Info: c.rels[0].Info, 142 Namespace: c.rels[0].Namespace, 143 }, nil 144 } 145 return nil, fmt.Errorf("No such release: %s", rlsName) 146 } 147 148 func (c *fakeReleaseClient) UpdateRelease(rlsName string, chStr string, opts ...helm.UpdateOption) (*rls.UpdateReleaseResponse, error) { 149 return nil, nil 150 } 151 152 func (c *fakeReleaseClient) ReleaseContent(rlsName string, opts ...helm.ContentOption) (resp *rls.GetReleaseContentResponse, err error) { 153 if len(c.rels) > 0 { 154 resp = &rls.GetReleaseContentResponse{ 155 Release: c.rels[0], 156 } 157 } 158 return resp, c.err 159 } 160 161 func (c *fakeReleaseClient) Option(opt ...helm.Option) helm.Interface { 162 return c 163 } 164 165 // releaseCmd is a command that works with a fakeReleaseClient 166 type releaseCmd func(c *fakeReleaseClient, out io.Writer) *cobra.Command 167 168 // runReleaseCases runs a set of release cases through the given releaseCmd. 169 func runReleaseCases(t *testing.T, tests []releaseCase, rcmd releaseCmd) { 170 var buf bytes.Buffer 171 for _, tt := range tests { 172 c := &fakeReleaseClient{ 173 rels: []*release.Release{tt.resp}, 174 } 175 cmd := rcmd(c, &buf) 176 cmd.ParseFlags(tt.flags) 177 err := cmd.RunE(cmd, tt.args) 178 if (err != nil) != tt.err { 179 t.Errorf("%q. expected error, got '%v'", tt.name, err) 180 } 181 re := regexp.MustCompile(tt.expected) 182 if !re.Match(buf.Bytes()) { 183 t.Errorf("%q. expected\n%q\ngot\n%q", tt.name, tt.expected, buf.String()) 184 } 185 buf.Reset() 186 } 187 } 188 189 // releaseCase describes a test case that works with releases. 190 type releaseCase struct { 191 name string 192 args []string 193 flags []string 194 // expected is the string to be matched. This supports regular expressions. 195 expected string 196 err bool 197 resp *release.Release 198 }