1package cmd_test 2 3import ( 4 "errors" 5 "fmt" 6 "io" 7 "os" 8 "path/filepath" 9 "syscall" 10 "time" 11 12 "code.cloudfoundry.org/clock" 13 "code.cloudfoundry.org/clock/fakeclock" 14 fakeui "github.com/cloudfoundry/bosh-cli/ui/fakes" 15 fakesys "github.com/cloudfoundry/bosh-utils/system/fakes" 16 . "github.com/onsi/ginkgo" 17 . "github.com/onsi/gomega" 18 19 . "github.com/cloudfoundry/bosh-cli/cmd" 20 fakedir "github.com/cloudfoundry/bosh-cli/director/directorfakes" 21) 22 23var _ = Describe("UIDownloader", func() { 24 var ( 25 director *fakedir.FakeDirector 26 fs *fakesys.FakeFileSystem 27 timeService clock.Clock 28 ui *fakeui.FakeUI 29 downloader UIDownloader 30 ) 31 32 BeforeEach(func() { 33 director = &fakedir.FakeDirector{} 34 timeService = fakeclock.NewFakeClock(time.Date(2009, time.November, 10, 23, 1, 2, 333, time.UTC)) 35 fs = fakesys.NewFakeFileSystem() 36 ui = &fakeui.FakeUI{} 37 downloader = NewUIDownloader(director, timeService, fs, ui) 38 }) 39 40 Describe("Download", func() { 41 var expectedPath string 42 43 BeforeEach(func() { 44 expectedPath = filepath.Join("/", "fake-dst-dir", "prefix-20091110-230102-000000333.tgz") 45 46 err := fs.MkdirAll("/fake-dst-dir", os.ModePerm) 47 Expect(err).ToNot(HaveOccurred()) 48 }) 49 50 itReturnsErrs := func(act func() error) { 51 It("returns error if downloading resource fails", func() { 52 err := fs.MkdirAll("/fake-dst-dir", os.ModePerm) 53 Expect(err).ToNot(HaveOccurred()) 54 55 fs.ReturnTempFile = fakesys.NewFakeFile("/some-tmp-file", fs) 56 57 director.DownloadResourceUncheckedStub = func(_ string, _ io.Writer) error { 58 return errors.New("fake-err") 59 } 60 61 err = act() 62 Expect(err).To(HaveOccurred()) 63 Expect(err.Error()).To(ContainSubstring("fake-err")) 64 65 Expect(fs.FileExists("/some-tmp-file")).To(BeFalse()) 66 Expect(fs.FileExists(expectedPath)).To(BeFalse()) 67 }) 68 69 It("returns error if temp file cannot be created", func() { 70 fs.TempFileError = errors.New("fake-err") 71 72 err := act() 73 Expect(err).To(HaveOccurred()) 74 Expect(err.Error()).To(ContainSubstring("fake-err")) 75 76 Expect(director.DownloadResourceUncheckedCallCount()).To(Equal(0)) 77 Expect(fs.FileExists(expectedPath)).To(BeFalse()) 78 }) 79 } 80 81 Context("when SHA1 is provided", func() { 82 act := func() error { 83 return downloader.Download("fake-blob-id", "a2511842a89119b9da922f9528307b7f8f55b798", "prefix", "/fake-dst-dir") 84 } 85 86 It("downloads specified blob to a specific destination", func() { 87 fakeFile := fakesys.NewFakeFile("/some-tmp-file", fs) 88 fakeFile.Write([]byte("file-contents")) 89 fs.ReturnTempFile = fakeFile 90 91 director.DownloadResourceUncheckedStub = func(_ string, out io.Writer) error { 92 out.Write([]byte("file-contents")) 93 return nil 94 } 95 96 err := act() 97 Expect(err).ToNot(HaveOccurred()) 98 99 Expect(fs.FileExists("/some-tmp-file")).To(BeFalse()) 100 Expect(fs.FileExists(expectedPath)).To(BeTrue()) 101 Expect(fs.ReadFileString(expectedPath)).To(Equal("file-contents")) 102 103 blobID, _ := director.DownloadResourceUncheckedArgsForCall(0) 104 Expect(blobID).To(Equal("fake-blob-id")) 105 106 Expect(ui.Said).To(Equal([]string{ 107 fmt.Sprintf("Downloading resource 'fake-blob-id' to '%s'...", expectedPath)})) 108 }) 109 110 It("returns error if sha1 does not match expected sha1", func() { 111 fakeFile := fakesys.NewFakeFile("/some-tmp-file", fs) 112 fakeFile.Write([]byte("file-contents-that-were-corrupted")) 113 fs.ReturnTempFile = fakeFile 114 115 err := act() 116 Expect(err).To(HaveOccurred()) 117 Expect(err.Error()).To(Equal("Expected stream to have digest 'a2511842a89119b9da922f9528307b7f8f55b798' but was '93135ede4065c7d5958ab7e328d501f8d4d9e2aa'")) 118 119 Expect(fs.FileExists(expectedPath)).To(BeFalse()) 120 }) 121 122 It("returns error if sha1 check fails", func() { 123 fakeFile := fakesys.NewFakeFile("/some-tmp-file", fs) 124 fakeFile.Write([]byte("file-contents-that-were-corrupted")) 125 fs.ReturnTempFile = fakeFile 126 fs.OpenFileErr = errors.New("fake-err") 127 128 err := act() 129 Expect(err).To(HaveOccurred()) 130 Expect(err.Error()).To(ContainSubstring("fake-err")) 131 132 Expect(fs.FileExists(expectedPath)).To(BeFalse()) 133 }) 134 135 itReturnsErrs(act) 136 }) 137 138 Context("when SHA1 is not provided", func() { 139 act := func() error { return downloader.Download("fake-blob-id", "", "prefix", "/fake-dst-dir") } 140 141 It("downloads specified blob to a specific destination without checking SHA1", func() { 142 fs.ReturnTempFile = fakesys.NewFakeFile("/some-tmp-file", fs) 143 144 director.DownloadResourceUncheckedStub = func(_ string, out io.Writer) error { 145 out.Write([]byte("content")) 146 return nil 147 } 148 149 err := act() 150 Expect(err).ToNot(HaveOccurred()) 151 152 Expect(fs.FileExists("/some-tmp-file")).To(BeFalse()) 153 Expect(fs.FileExists(expectedPath)).To(BeTrue()) 154 Expect(fs.ReadFileString(expectedPath)).To(Equal("content")) 155 156 blobID, _ := director.DownloadResourceUncheckedArgsForCall(0) 157 Expect(blobID).To(Equal("fake-blob-id")) 158 159 Expect(ui.Said).To(Equal([]string{ 160 fmt.Sprintf("Downloading resource 'fake-blob-id' to '%s'...", expectedPath)})) 161 }) 162 163 itReturnsErrs(act) 164 }) 165 166 Context("when downloading across devices", func() { 167 BeforeEach(func() { 168 fs.RenameError = &os.LinkError{ 169 Err: syscall.Errno(0x12), 170 } 171 }) 172 173 act := func() error { return downloader.Download("fake-blob-id", "", "prefix", "/fake-dst-dir") } 174 175 It("downloads specified blob to a specific destination without checking SHA1", func() { 176 fs.ReturnTempFile = fakesys.NewFakeFile("/some-tmp-file", fs) 177 178 director.DownloadResourceUncheckedStub = func(_ string, out io.Writer) error { 179 out.Write([]byte("content")) 180 return nil 181 } 182 183 err := act() 184 Expect(err).ToNot(HaveOccurred()) 185 186 Expect(fs.FileExists("/some-tmp-file")).To(BeFalse()) 187 Expect(fs.FileExists(expectedPath)).To(BeTrue()) 188 Expect(fs.ReadFileString(expectedPath)).To(Equal("content")) 189 190 blobID, _ := director.DownloadResourceUncheckedArgsForCall(0) 191 Expect(blobID).To(Equal("fake-blob-id")) 192 193 Expect(ui.Said).To(Equal([]string{ 194 fmt.Sprintf("Downloading resource 'fake-blob-id' to '%s'...", expectedPath)})) 195 }) 196 197 itReturnsErrs(act) 198 }) 199 }) 200}) 201