github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/pkg/blob/downloader_test.go (about) 1 package blob_test 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "net/http" 8 "os" 9 "path/filepath" 10 "testing" 11 12 "github.com/heroku/color" 13 "github.com/onsi/gomega/ghttp" 14 "github.com/sclevine/spec" 15 "github.com/sclevine/spec/report" 16 17 "github.com/buildpacks/pack/internal/paths" 18 "github.com/buildpacks/pack/pkg/archive" 19 "github.com/buildpacks/pack/pkg/blob" 20 h "github.com/buildpacks/pack/testhelpers" 21 ) 22 23 func TestDownloader(t *testing.T) { 24 color.Disable(true) 25 defer color.Disable(false) 26 spec.Run(t, "Downloader", testDownloader, spec.Sequential(), spec.Report(report.Terminal{})) 27 } 28 29 func testDownloader(t *testing.T, when spec.G, it spec.S) { 30 when("#Download", func() { 31 var ( 32 cacheDir string 33 err error 34 subject blob.Downloader 35 ) 36 37 it.Before(func() { 38 cacheDir, err = os.MkdirTemp("", "cache") 39 h.AssertNil(t, err) 40 subject = blob.NewDownloader(&logger{io.Discard}, cacheDir) 41 }) 42 43 it.After(func() { 44 h.AssertNil(t, os.RemoveAll(cacheDir)) 45 }) 46 47 when("is path", func() { 48 var ( 49 relPath string 50 ) 51 52 it.Before(func() { 53 relPath = filepath.Join("testdata", "blob") 54 }) 55 56 when("is absolute", func() { 57 it("return the absolute path", func() { 58 absPath, err := filepath.Abs(relPath) 59 h.AssertNil(t, err) 60 61 b, err := subject.Download(context.TODO(), absPath) 62 h.AssertNil(t, err) 63 assertBlob(t, b) 64 }) 65 }) 66 67 when("is relative", func() { 68 it("resolves the absolute path", func() { 69 b, err := subject.Download(context.TODO(), relPath) 70 h.AssertNil(t, err) 71 assertBlob(t, b) 72 }) 73 }) 74 75 when("path is a file:// uri", func() { 76 it("resolves the absolute path", func() { 77 absPath, err := filepath.Abs(relPath) 78 h.AssertNil(t, err) 79 80 uri, err := paths.FilePathToURI(absPath, "") 81 h.AssertNil(t, err) 82 83 b, err := subject.Download(context.TODO(), uri) 84 h.AssertNil(t, err) 85 assertBlob(t, b) 86 }) 87 }) 88 }) 89 90 when("is uri", func() { 91 var ( 92 server *ghttp.Server 93 uri string 94 tgz string 95 ) 96 97 it.Before(func() { 98 server = ghttp.NewServer() 99 uri = server.URL() + "/downloader/somefile.tgz" 100 101 tgz = h.CreateTGZ(t, filepath.Join("testdata", "blob"), "./", 0777) 102 }) 103 104 it.After(func() { 105 os.Remove(tgz) 106 server.Close() 107 }) 108 109 when("uri is valid", func() { 110 it.Before(func() { 111 server.AppendHandlers(func(w http.ResponseWriter, r *http.Request) { 112 w.Header().Add("ETag", "A") 113 http.ServeFile(w, r, tgz) 114 }) 115 116 server.AppendHandlers(func(w http.ResponseWriter, r *http.Request) { 117 w.WriteHeader(304) 118 }) 119 }) 120 121 it("downloads from a 'http(s)://' URI", func() { 122 b, err := subject.Download(context.TODO(), uri) 123 h.AssertNil(t, err) 124 assertBlob(t, b) 125 }) 126 127 it("uses cache from a 'http(s)://' URI tgz", func() { 128 b, err := subject.Download(context.TODO(), uri) 129 h.AssertNil(t, err) 130 assertBlob(t, b) 131 132 b, err = subject.Download(context.TODO(), uri) 133 h.AssertNil(t, err) 134 assertBlob(t, b) 135 }) 136 }) 137 138 when("uri is invalid", func() { 139 when("uri file is not found", func() { 140 it.Before(func() { 141 server.AppendHandlers(func(w http.ResponseWriter, r *http.Request) { 142 w.WriteHeader(404) 143 }) 144 145 server.AppendHandlers(func(w http.ResponseWriter, r *http.Request) { 146 w.WriteHeader(404) 147 }) 148 }) 149 150 it("should return error", func() { 151 _, err := subject.Download(context.TODO(), uri) 152 h.AssertError(t, err, "could not download") 153 h.AssertError(t, err, "http status '404'") 154 }) 155 }) 156 157 when("uri is unsupported", func() { 158 it("should return error", func() { 159 _, err := subject.Download(context.TODO(), "not-supported://file.tgz") 160 h.AssertError(t, err, "unsupported protocol 'not-supported'") 161 }) 162 }) 163 }) 164 }) 165 }) 166 } 167 168 func assertBlob(t *testing.T, b blob.Blob) { 169 t.Helper() 170 r, err := b.Open() 171 h.AssertNil(t, err) 172 defer r.Close() 173 174 _, bytes, err := archive.ReadTarEntry(r, "file.txt") 175 h.AssertNil(t, err) 176 177 h.AssertEq(t, string(bytes), "contents") 178 } 179 180 type logger struct { 181 writer io.Writer 182 } 183 184 func (l *logger) Debugf(format string, v ...interface{}) { 185 fmt.Fprintln(l.writer, format, v) 186 } 187 188 func (l *logger) Infof(format string, v ...interface{}) { 189 fmt.Fprintln(l.writer, format, v) 190 } 191 192 func (l *logger) Writer() io.Writer { 193 return l.writer 194 }