github.com/joselitofilho/goreleaser@v0.155.1-0.20210123221854-e4891856c593/internal/pipe/blob/blob_minio_test.go (about) 1 package blob 2 3 // this is pretty much copied from the s3 pipe to ensure both work the same way 4 // only differences are that it sets `blobs` instead of `s3` on test cases and 5 // the test setup and teardown 6 7 import ( 8 "io" 9 "io/ioutil" 10 "net" 11 "os" 12 "os/exec" 13 "path/filepath" 14 "strings" 15 "testing" 16 "time" 17 18 "github.com/goreleaser/goreleaser/internal/artifact" 19 "github.com/goreleaser/goreleaser/pkg/config" 20 "github.com/goreleaser/goreleaser/pkg/context" 21 "github.com/stretchr/testify/require" 22 "gocloud.dev/blob" 23 ) 24 25 func TestMinioUpload(t *testing.T) { 26 var listen = randomListen(t) 27 var folder = t.TempDir() 28 srcpath := filepath.Join(folder, "source.tar.gz") 29 tgzpath := filepath.Join(folder, "bin.tar.gz") 30 debpath := filepath.Join(folder, "bin.deb") 31 checkpath := filepath.Join(folder, "check.txt") 32 require.NoError(t, ioutil.WriteFile(checkpath, []byte("fake checksums"), 0744)) 33 require.NoError(t, ioutil.WriteFile(srcpath, []byte("fake\nsrc"), 0744)) 34 require.NoError(t, ioutil.WriteFile(tgzpath, []byte("fake\ntargz"), 0744)) 35 require.NoError(t, ioutil.WriteFile(debpath, []byte("fake\ndeb"), 0744)) 36 var ctx = context.New(config.Project{ 37 Dist: folder, 38 ProjectName: "testupload", 39 Blobs: []config.Blob{ 40 { 41 Provider: "s3", 42 Bucket: "test", 43 Region: "us-east", 44 Endpoint: "http://" + listen, 45 IDs: []string{"foo", "bar"}, 46 }, 47 }, 48 }) 49 ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"} 50 ctx.Artifacts.Add(&artifact.Artifact{ 51 Type: artifact.Checksum, 52 Name: "checksum.txt", 53 Path: checkpath, 54 }) 55 ctx.Artifacts.Add(&artifact.Artifact{ 56 Type: artifact.UploadableSourceArchive, 57 Name: "source.tar.gz", 58 Path: srcpath, 59 Extra: map[string]interface{}{ 60 "Format": "tar.gz", 61 }, 62 }) 63 ctx.Artifacts.Add(&artifact.Artifact{ 64 Type: artifact.UploadableArchive, 65 Name: "bin.tar.gz", 66 Path: tgzpath, 67 Extra: map[string]interface{}{ 68 "ID": "foo", 69 }, 70 }) 71 ctx.Artifacts.Add(&artifact.Artifact{ 72 Type: artifact.LinuxPackage, 73 Name: "bin.deb", 74 Path: debpath, 75 Extra: map[string]interface{}{ 76 "ID": "bar", 77 }, 78 }) 79 var name = "test_upload" 80 start(t, name, listen) 81 prepareEnv() 82 require.NoError(t, Pipe{}.Default(ctx)) 83 require.NoError(t, Pipe{}.Publish(ctx)) 84 85 require.Subset(t, getFiles(t, ctx, ctx.Config.Blobs[0]), []string{ 86 "testupload/v1.0.0/bin.deb", 87 "testupload/v1.0.0/bin.tar.gz", 88 "testupload/v1.0.0/checksum.txt", 89 "testupload/v1.0.0/source.tar.gz", 90 }) 91 } 92 93 func TestMinioUploadCustomBucketID(t *testing.T) { 94 var listen = randomListen(t) 95 var folder = t.TempDir() 96 tgzpath := filepath.Join(folder, "bin.tar.gz") 97 debpath := filepath.Join(folder, "bin.deb") 98 require.NoError(t, ioutil.WriteFile(tgzpath, []byte("fake\ntargz"), 0744)) 99 require.NoError(t, ioutil.WriteFile(debpath, []byte("fake\ndeb"), 0744)) 100 // Set custom BUCKET_ID env variable. 101 require.NoError(t, os.Setenv("BUCKET_ID", "test")) 102 var ctx = context.New(config.Project{ 103 Dist: folder, 104 ProjectName: "testupload", 105 Blobs: []config.Blob{ 106 { 107 Provider: "s3", 108 Bucket: "{{.Env.BUCKET_ID}}", 109 Endpoint: "http://" + listen, 110 }, 111 }, 112 }) 113 ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"} 114 ctx.Artifacts.Add(&artifact.Artifact{ 115 Type: artifact.UploadableArchive, 116 Name: "bin.tar.gz", 117 Path: tgzpath, 118 }) 119 ctx.Artifacts.Add(&artifact.Artifact{ 120 Type: artifact.LinuxPackage, 121 Name: "bin.deb", 122 Path: debpath, 123 }) 124 var name = "custom_bucket_id" 125 start(t, name, listen) 126 prepareEnv() 127 require.NoError(t, Pipe{}.Default(ctx)) 128 require.NoError(t, Pipe{}.Publish(ctx)) 129 } 130 131 func TestMinioUploadInvalidCustomBucketID(t *testing.T) { 132 var listen = randomListen(t) 133 var folder = t.TempDir() 134 tgzpath := filepath.Join(folder, "bin.tar.gz") 135 debpath := filepath.Join(folder, "bin.deb") 136 require.NoError(t, ioutil.WriteFile(tgzpath, []byte("fake\ntargz"), 0744)) 137 require.NoError(t, ioutil.WriteFile(debpath, []byte("fake\ndeb"), 0744)) 138 var ctx = context.New(config.Project{ 139 Dist: folder, 140 ProjectName: "testupload", 141 Blobs: []config.Blob{ 142 { 143 Provider: "s3", 144 Bucket: "{{.Bad}}", 145 Endpoint: "http://" + listen, 146 }, 147 }, 148 }) 149 ctx.Git = context.GitInfo{CurrentTag: "v1.1.0"} 150 ctx.Artifacts.Add(&artifact.Artifact{ 151 Type: artifact.UploadableArchive, 152 Name: "bin.tar.gz", 153 Path: tgzpath, 154 }) 155 ctx.Artifacts.Add(&artifact.Artifact{ 156 Type: artifact.LinuxPackage, 157 Name: "bin.deb", 158 Path: debpath, 159 }) 160 var name = "invalid_bucket_id" 161 start(t, name, listen) 162 prepareEnv() 163 require.NoError(t, Pipe{}.Default(ctx)) 164 require.Error(t, Pipe{}.Publish(ctx)) 165 } 166 167 func TestMinioUploadSkipPublish(t *testing.T) { 168 var listen = randomListen(t) 169 var folder = t.TempDir() 170 srcpath := filepath.Join(folder, "source.tar.gz") 171 tgzpath := filepath.Join(folder, "bin.tar.gz") 172 debpath := filepath.Join(folder, "bin.deb") 173 checkpath := filepath.Join(folder, "check.txt") 174 require.NoError(t, ioutil.WriteFile(checkpath, []byte("fake checksums"), 0744)) 175 require.NoError(t, ioutil.WriteFile(srcpath, []byte("fake\nsrc"), 0744)) 176 require.NoError(t, ioutil.WriteFile(tgzpath, []byte("fake\ntargz"), 0744)) 177 require.NoError(t, ioutil.WriteFile(debpath, []byte("fake\ndeb"), 0744)) 178 var ctx = context.New(config.Project{ 179 Dist: folder, 180 ProjectName: "testupload", 181 Blobs: []config.Blob{ 182 { 183 Provider: "s3", 184 Bucket: "test", 185 Region: "us-east", 186 Endpoint: "http://" + listen, 187 IDs: []string{"foo", "bar"}, 188 }, 189 }, 190 }) 191 ctx.SkipPublish = true 192 ctx.Git = context.GitInfo{CurrentTag: "v1.2.0"} 193 ctx.Artifacts.Add(&artifact.Artifact{ 194 Type: artifact.Checksum, 195 Name: "checksum.txt", 196 Path: checkpath, 197 }) 198 ctx.Artifacts.Add(&artifact.Artifact{ 199 Type: artifact.UploadableSourceArchive, 200 Name: "source.tar.gz", 201 Path: srcpath, 202 Extra: map[string]interface{}{ 203 "Format": "tar.gz", 204 }, 205 }) 206 ctx.Artifacts.Add(&artifact.Artifact{ 207 Type: artifact.UploadableArchive, 208 Name: "bin.tar.gz", 209 Path: tgzpath, 210 Extra: map[string]interface{}{ 211 "ID": "foo", 212 }, 213 }) 214 ctx.Artifacts.Add(&artifact.Artifact{ 215 Type: artifact.LinuxPackage, 216 Name: "bin.deb", 217 Path: debpath, 218 Extra: map[string]interface{}{ 219 "ID": "bar", 220 }, 221 }) 222 var name = "test_upload" 223 start(t, name, listen) 224 prepareEnv() 225 require.NoError(t, Pipe{}.Default(ctx)) 226 require.NoError(t, Pipe{}.Publish(ctx)) 227 228 require.NotContains(t, getFiles(t, ctx, ctx.Config.Blobs[0]), []string{ 229 "testupload/v1.2.0/bin.deb", 230 "testupload/v1.2.0/bin.tar.gz", 231 "testupload/v1.2.0/checksum.txt", 232 "testupload/v1.2.0/source.tar.gz", 233 }) 234 } 235 236 func randomListen(t *testing.T) string { 237 t.Helper() 238 listener, err := net.Listen("tcp", "127.0.0.1:0") 239 require.NoError(t, err) 240 listener.Close() 241 return listener.Addr().String() 242 } 243 244 func prepareEnv() { 245 os.Setenv("AWS_ACCESS_KEY_ID", "minio") 246 os.Setenv("AWS_SECRET_ACCESS_KEY", "miniostorage") 247 os.Setenv("AWS_REGION", "us-east-1") 248 } 249 250 func start(t testing.TB, name, listen string) { 251 wd, err := os.Getwd() 252 require.NoError(t, err) 253 254 removeTestData() 255 256 t.Cleanup(func() { 257 if out, err := exec.Command("docker", "stop", name).CombinedOutput(); err != nil { 258 t.Fatalf("failed to stop minio: %s", string(out)) 259 } 260 removeTestData() 261 }) 262 263 if out, err := exec.Command( 264 "docker", "run", "-d", "--rm", 265 "-v", filepath.Join(wd, "testdata/data")+":/data", 266 "--name", name, 267 "-p", listen+":9000", 268 "-e", "MINIO_ACCESS_KEY=minio", 269 "-e", "MINIO_SECRET_KEY=miniostorage", 270 "--health-interval", "1s", 271 "--health-cmd=curl --silent --fail http://localhost:9000/minio/health/ready || exit 1", 272 "minio/minio", 273 "server", "/data", 274 ).CombinedOutput(); err != nil { 275 t.Fatalf("failed to start minio: %s", string(out)) 276 } 277 278 for range time.Tick(time.Second) { 279 out, err := exec.Command("docker", "inspect", "--format='{{json .State.Health}}'", name).CombinedOutput() 280 if err != nil { 281 t.Fatalf("failed to check minio status: %s", string(out)) 282 } 283 if strings.Contains(string(out), `"Status":"healthy"`) { 284 t.Log("minio is healthy") 285 break 286 } 287 t.Log("waiting for minio to be healthy") 288 } 289 } 290 291 func removeTestData() { 292 _ = os.RemoveAll("./testdata/data/test/testupload") // dont care if it fails 293 } 294 295 func getFiles(t *testing.T, ctx *context.Context, cfg config.Blob) []string { 296 t.Helper() 297 url, err := urlFor(ctx, cfg) 298 require.NoError(t, err) 299 conn, err := blob.OpenBucket(ctx, url) 300 require.NoError(t, err) 301 defer conn.Close() 302 var iter = conn.List(nil) 303 var files []string 304 for { 305 file, err := iter.Next(ctx) 306 if err != nil && err == io.EOF { 307 break 308 } 309 require.NoError(t, err) 310 files = append(files, file.Key) 311 } 312 return files 313 }