11package commands_test
22
33import (
4- "io/ioutil"
4+ "archive/tar"
5+ "compress/gzip"
6+ "crypto/sha1"
7+ "fmt"
8+ "io"
59 "log"
10+ "os"
11+ "strings"
12+ "time"
613
714 . "github.com/onsi/ginkgo"
815 . "github.com/onsi/gomega"
@@ -30,7 +37,7 @@ var _ = Describe("UploadRelease", func() {
3037 Region : "mars-2" ,
3138 AccessKeyId : "id" ,
3239 SecretAccessKey : "secret" ,
33- Regex : "^ (?P<release_name>[a-z-_0-9]+)-(?P<release_version>v?[0-9\\ .]+-?[a-zA-Z0-9]\\ .?[0-9]*)\\ .tgz$" ,
40+ Regex : `^\w+/ (?P<release_name>[a-z-_0-9]+)-(?P<release_version>v?[0-9\.]+-?[a-zA-Z0-9]\.?[0-9]*)\.tgz$` ,
3441 },
3542 {
3643 Type : "boshio" ,
@@ -44,8 +51,49 @@ var _ = Describe("UploadRelease", func() {
4451 },
4552 }
4653 }
54+
55+ expectedReleaseSHA string
4756 )
4857
58+ var writeReleaseTarball = func (path , name , version string ) string {
59+ f , err := fs .Create (path )
60+ Expect (err ).NotTo (HaveOccurred ())
61+
62+ gw := gzip .NewWriter (f )
63+ tw := tar .NewWriter (gw )
64+
65+ releaseManifest := `
66+ name: ` + name + `
67+ version: ` + version + `
68+ `
69+ manifestReader := strings .NewReader (releaseManifest )
70+
71+ header := & tar.Header {
72+ Name : "release.MF" ,
73+ Size : manifestReader .Size (),
74+ Mode : int64 (os .O_RDONLY ),
75+ ModTime : time .Now (),
76+ }
77+ Expect (tw .WriteHeader (header )).To (Succeed ())
78+
79+ _ , err = io .Copy (tw , manifestReader )
80+ Expect (err ).NotTo (HaveOccurred ())
81+
82+ Expect (tw .Close ()).To (Succeed ())
83+ Expect (gw .Close ()).To (Succeed ())
84+ Expect (f .Close ()).To (Succeed ())
85+
86+ tarball , err := fs .Open (path )
87+ Expect (err ).NotTo (HaveOccurred ())
88+ defer tarball .Close ()
89+
90+ hash := sha1 .New ()
91+ _ , err = io .Copy (hash , tarball )
92+ Expect (err ).NotTo (HaveOccurred ())
93+
94+ return fmt .Sprintf ("%x" , hash .Sum (nil ))
95+ }
96+
4997 BeforeEach (func () {
5098 fs = memfs .New ()
5199 loader = new (fakes.KilnfileLoader )
@@ -60,19 +108,14 @@ var _ = Describe("UploadRelease", func() {
60108 return nil
61109 },
62110 }
111+ expectedReleaseSHA = writeReleaseTarball ("banana-release.tgz" , "banana" , "1.2.3" )
63112 })
64113
65114 When ("it receives a correct tarball path" , func () {
66115 BeforeEach (func () {
67116 loader .LoadKilnfilesReturns (
68117 cargo.Kilnfile {ReleaseSources : exampleReleaseSourceList ()},
69118 cargo.KilnfileLock {}, nil )
70-
71- f , err := fs .Create ("banana-release.tgz" )
72- _ , _ = f .Write ([]byte ("banana" ))
73- f .Close ()
74-
75- Expect (err ).NotTo (HaveOccurred ())
76119 })
77120
78121 It ("uploads the tarball to the release source" , func () {
@@ -89,28 +132,56 @@ var _ = Describe("UploadRelease", func() {
89132 err := uploadRelease .Execute ([]string {
90133 "--kilnfile" , "not-read-see-struct/Kilnfile" ,
91134 "--local-path" , "banana-release.tgz" ,
92- "--remote-path" , "banana-release-1.2.3.tgz" ,
93135 "--release-source" , "orange-bucket" ,
94136 "--variables-file" , "my-secrets" ,
95137 })
96138
97139 Expect (err ).NotTo (HaveOccurred ())
140+
98141 Expect (configUploaderCallCount ).To (Equal (1 ))
142+
99143 Expect (relSrcConfig ).NotTo (BeNil ())
100144 Expect (relSrcConfig .Bucket ).To (Equal ("orange-bucket" ))
145+
101146 Expect (uploader .UploadCallCount ()).To (Equal (1 ))
102147
103148 opts , fns := uploader .UploadArgsForCall (0 )
104-
105149 Expect (fns ).To (HaveLen (0 ))
106-
107150 Expect (opts .Bucket ).NotTo (BeNil ())
108151 Expect (* opts .Bucket ).To (Equal ("orange-bucket" ))
109152 Expect (opts .Key ).NotTo (BeNil ())
110- Expect (* opts .Key ).To (Equal ("banana-release -1.2.3.tgz" ))
153+ Expect (* opts .Key ).To (Equal ("banana/banana -1.2.3.tgz" ))
111154
112- buf , _ := ioutil .ReadAll (opts .Body )
113- Expect (string (buf )).To (Equal ("banana" ))
155+ hash := sha1 .New ()
156+ _ , err = io .Copy (hash , opts .Body )
157+ Expect (err ).NotTo (HaveOccurred ())
158+
159+ releaseSHA := fmt .Sprintf ("%x" , hash .Sum (nil ))
160+ Expect (releaseSHA ).To (Equal (expectedReleaseSHA ))
161+ })
162+ })
163+
164+ When ("the release tarball is invalid" , func () {
165+ BeforeEach (func () {
166+ f , err := fs .Create ("invalid-release.tgz" )
167+ _ , _ = f .Write ([]byte ("invalid" ))
168+ f .Close ()
169+
170+ Expect (err ).NotTo (HaveOccurred ())
171+
172+ loader .LoadKilnfilesReturns (
173+ cargo.Kilnfile {ReleaseSources : exampleReleaseSourceList ()},
174+ cargo.KilnfileLock {}, nil )
175+ })
176+
177+ It ("errors" , func () {
178+ err := uploadRelease .Execute ([]string {
179+ "--kilnfile" , "not-read-see-struct/Kilnfile" ,
180+ "--local-path" , "invalid-release.tgz" ,
181+ "--release-source" , "orange-bucket" ,
182+ "--variables-file" , "my-secrets" ,
183+ })
184+ Expect (err ).To (MatchError (ContainSubstring ("error reading the release manifest" )))
114185 })
115186 })
116187
@@ -124,22 +195,15 @@ var _ = Describe("UploadRelease", func() {
124195 ReleaseSources : relSrcList ,
125196 }, cargo.KilnfileLock {}, nil )
126197
127- f , err := fs .Create ("banana-release.tgz" )
128- _ , _ = f .Write ([]byte ("banana" ))
129- f .Close ()
130-
131198 uploadRelease .UploaderConfig = func (rsc * cargo.ReleaseSourceConfig ) commands.S3Uploader {
132199 return uploader
133200 }
134-
135- Expect (err ).NotTo (HaveOccurred ())
136201 })
137202
138203 It ("returns a descriptive error" , func () {
139204 err := uploadRelease .Execute ([]string {
140205 "--kilnfile" , "not-read-see-struct/Kilnfile" ,
141206 "--local-path" , "banana-release.tgz" ,
142- "--remote-path" , "banana-release-1.2.3.tgz" ,
143207 "--release-source" , "orange-bucket" ,
144208 "--variables-file" , "my-secrets" ,
145209 })
@@ -148,82 +212,71 @@ var _ = Describe("UploadRelease", func() {
148212 })
149213 })
150214
151- When ("the remote-path does not match the regex in the release_source" , func () {
215+ When ("the conventional remote-path does not match the regex in the release_source" , func () {
152216 BeforeEach (func () {
153- relSrcList := exampleReleaseSourceList ()
217+ relSrcList := []cargo.ReleaseSourceConfig {
218+ {
219+ Type : "s3" ,
220+ Bucket : "orange-bucket" ,
221+ Region : "mars-2" ,
222+ AccessKeyId : "id" ,
223+ SecretAccessKey : "secret" ,
224+ Regex : "^pointless-root-dir/(?P<release_name>[a-z-_0-9]+)-(?P<release_version>v?[0-9\\ .]+-?[a-zA-Z0-9]\\ .?[0-9]*)\\ .tgz$" ,
225+ },
226+ }
154227
155228 loader .LoadKilnfilesReturns (cargo.Kilnfile {
156229 ReleaseSources : relSrcList ,
157230 }, cargo.KilnfileLock {}, nil )
158231
159- f , err := fs .Create ("banana-release.tgz" )
160- _ , _ = f .Write ([]byte ("banana" ))
161- f .Close ()
162-
163232 uploadRelease .UploaderConfig = func (rsc * cargo.ReleaseSourceConfig ) commands.S3Uploader {
164233 return uploader
165234 }
166-
167- Expect (err ).NotTo (HaveOccurred ())
168235 })
169236
170237 It ("returns a descriptive error" , func () {
171238 err := uploadRelease .Execute ([]string {
172239 "--kilnfile" , "not-read-see-struct/Kilnfile" ,
173240 "--local-path" , "banana-release.tgz" ,
174- "--remote-path" , "BLA_BLA_BLA.tgz" ,
175241 "--release-source" , "orange-bucket" ,
176242 "--variables-file" , "my-secrets" ,
177243 })
178244
179- Expect (err ).To (MatchError (ContainSubstring (" remote- path does not match" )))
245+ Expect (err ).To (MatchError (ContainSubstring (` remote path "banana/banana-1.2.3.tgz" does not match` )))
180246 })
181247 })
182248
183- When ("some the remote does not exist in the Kilnfile " , func () {
249+ When ("the given release source doesn't exist " , func () {
184250 When ("no release sources are s3 buckets" , func () {
185251 BeforeEach (func () {
186252 loader .LoadKilnfilesReturns (cargo.Kilnfile {}, cargo.KilnfileLock {}, nil )
187-
188- f , err := fs .Create ("banana-release.tgz" )
189- _ , _ = f .Write ([]byte ("banana" ))
190- f .Close ()
191-
192- Expect (err ).NotTo (HaveOccurred ())
193253 })
194254
195255 It ("returns an error without suggested release sources" , func () {
196256 err := uploadRelease .Execute ([]string {
197257 "--kilnfile" , "not-read-see-struct/Kilnfile" ,
198258 "--local-path" , "banana-release.tgz" ,
199- "--remote-path" , "banana-release-1.2.3.tgz" ,
200259 "--release-source" , "orange-bucket" ,
201260 "--variables-file" , "my-secrets" ,
202261 })
203262
204263 Expect (err ).To (MatchError (ContainSubstring ("remote release source" )))
205264 })
206265 })
207- When ("at least one release source is an s3 bucket" , func () {
266+
267+ When ("some release sources are s3 buckets" , func () {
208268 BeforeEach (func () {
209269 loader .LoadKilnfilesReturns (
210270 cargo.Kilnfile {ReleaseSources : exampleReleaseSourceList ()},
211271 cargo.KilnfileLock {}, nil ,
212272 )
213-
214- f , err := fs .Create ("banana-release.tgz" )
215- _ , _ = f .Write ([]byte ("banana" ))
216- f .Close ()
217-
218- Expect (err ).NotTo (HaveOccurred ())
219273 })
220274
221- It ("returns an error without suggested release sources" , func () {
275+ It ("returns an error that suggests valid release sources" , func () {
222276 err := uploadRelease .Execute ([]string {
223277 "--kilnfile" , "not-read-see-struct/Kilnfile" ,
224278 "--local-path" , "banana-release.tgz" ,
225- "--remote-path" , "banana-release-1.2.3.tgz" ,
226- "--release-source" , "dog-bucket" ,
279+ "--release-source" , "no-such-release-source" ,
227280 "--variables-file" , "my-secrets" ,
228281 })
229282
0 commit comments