github.com/amane3/goreleaser@v0.182.0/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/amane3/goreleaser/internal/artifact" 19 "github.com/amane3/goreleaser/pkg/config" 20 "github.com/amane3/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 listener, err := net.Listen("tcp", "127.0.0.1:0") 238 require.NoError(t, err) 239 listener.Close() 240 return listener.Addr().String() 241 } 242 243 func prepareEnv() { 244 os.Setenv("AWS_ACCESS_KEY_ID", "minio") 245 os.Setenv("AWS_SECRET_ACCESS_KEY", "miniostorage") 246 os.Setenv("AWS_REGION", "us-east-1") 247 } 248 249 func start(t testing.TB, name, listen string) { 250 wd, err := os.Getwd() 251 require.NoError(t, err) 252 253 removeTestData() 254 255 t.Cleanup(func() { 256 if out, err := exec.Command("docker", "stop", name).CombinedOutput(); err != nil { 257 t.Fatalf("failed to stop minio: %s", string(out)) 258 } 259 removeTestData() 260 }) 261 262 if out, err := exec.Command( 263 "docker", "run", "-d", "--rm", 264 "-v", filepath.Join(wd, "testdata/data")+":/data", 265 "--name", name, 266 "-p", listen+":9000", 267 "-e", "MINIO_ACCESS_KEY=minio", 268 "-e", "MINIO_SECRET_KEY=miniostorage", 269 "--health-interval", "1s", 270 "--health-cmd=curl --silent --fail http://localhost:9000/minio/health/ready || exit 1", 271 "minio/minio", 272 "server", "/data", 273 ).CombinedOutput(); err != nil { 274 t.Fatalf("failed to start minio: %s", string(out)) 275 } 276 277 for range time.Tick(time.Second) { 278 out, err := exec.Command("docker", "inspect", "--format='{{json .State.Health}}'", name).CombinedOutput() 279 if err != nil { 280 t.Fatalf("failed to check minio status: %s", string(out)) 281 } 282 if strings.Contains(string(out), `"Status":"healthy"`) { 283 t.Log("minio is healthy") 284 break 285 } 286 t.Log("waiting for minio to be healthy") 287 } 288 } 289 290 func removeTestData() { 291 _ = os.RemoveAll("./testdata/data/test/testupload") // dont care if it fails 292 } 293 294 func getFiles(t *testing.T, ctx *context.Context, cfg config.Blob) []string { 295 url, err := urlFor(ctx, cfg) 296 require.NoError(t, err) 297 conn, err := blob.OpenBucket(ctx, url) 298 require.NoError(t, err) 299 defer conn.Close() 300 var iter = conn.List(nil) 301 var files []string 302 for { 303 file, err := iter.Next(ctx) 304 if err != nil && err == io.EOF { 305 break 306 } 307 require.NoError(t, err) 308 files = append(files, file.Key) 309 } 310 return files 311 }