summaryrefslogtreecommitdiffstats
path: root/modules/storage/minio_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/storage/minio_test.go')
-rw-r--r--modules/storage/minio_test.go216
1 files changed, 216 insertions, 0 deletions
diff --git a/modules/storage/minio_test.go b/modules/storage/minio_test.go
new file mode 100644
index 00000000..9ce1dbc7
--- /dev/null
+++ b/modules/storage/minio_test.go
@@ -0,0 +1,216 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package storage
+
+import (
+ "context"
+ "net/http"
+ "net/http/httptest"
+ "os"
+ "testing"
+
+ "code.gitea.io/gitea/modules/setting"
+
+ "github.com/minio/minio-go/v7"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestMinioStorageIterator(t *testing.T) {
+ if os.Getenv("CI") == "" {
+ t.Skip("minioStorage not present outside of CI")
+ return
+ }
+ testStorageIterator(t, setting.MinioStorageType, &setting.Storage{
+ MinioConfig: setting.MinioStorageConfig{
+ Endpoint: "minio:9000",
+ AccessKeyID: "123456",
+ SecretAccessKey: "12345678",
+ Bucket: "gitea",
+ Location: "us-east-1",
+ },
+ })
+}
+
+func TestVirtualHostMinioStorage(t *testing.T) {
+ if os.Getenv("CI") == "" {
+ t.Skip("minioStorage not present outside of CI")
+ return
+ }
+ testStorageIterator(t, setting.MinioStorageType, &setting.Storage{
+ MinioConfig: setting.MinioStorageConfig{
+ Endpoint: "minio:9000",
+ AccessKeyID: "123456",
+ SecretAccessKey: "12345678",
+ Bucket: "gitea",
+ Location: "us-east-1",
+ BucketLookup: "dns",
+ },
+ })
+}
+
+func TestMinioStoragePath(t *testing.T) {
+ m := &MinioStorage{basePath: ""}
+ assert.Equal(t, "", m.buildMinioPath("/"))
+ assert.Equal(t, "", m.buildMinioPath("."))
+ assert.Equal(t, "a", m.buildMinioPath("/a"))
+ assert.Equal(t, "a/b", m.buildMinioPath("/a/b/"))
+ assert.Equal(t, "", m.buildMinioDirPrefix(""))
+ assert.Equal(t, "a/", m.buildMinioDirPrefix("/a/"))
+
+ m = &MinioStorage{basePath: "/"}
+ assert.Equal(t, "", m.buildMinioPath("/"))
+ assert.Equal(t, "", m.buildMinioPath("."))
+ assert.Equal(t, "a", m.buildMinioPath("/a"))
+ assert.Equal(t, "a/b", m.buildMinioPath("/a/b/"))
+ assert.Equal(t, "", m.buildMinioDirPrefix(""))
+ assert.Equal(t, "a/", m.buildMinioDirPrefix("/a/"))
+
+ m = &MinioStorage{basePath: "/base"}
+ assert.Equal(t, "base", m.buildMinioPath("/"))
+ assert.Equal(t, "base", m.buildMinioPath("."))
+ assert.Equal(t, "base/a", m.buildMinioPath("/a"))
+ assert.Equal(t, "base/a/b", m.buildMinioPath("/a/b/"))
+ assert.Equal(t, "base/", m.buildMinioDirPrefix(""))
+ assert.Equal(t, "base/a/", m.buildMinioDirPrefix("/a/"))
+
+ m = &MinioStorage{basePath: "/base/"}
+ assert.Equal(t, "base", m.buildMinioPath("/"))
+ assert.Equal(t, "base", m.buildMinioPath("."))
+ assert.Equal(t, "base/a", m.buildMinioPath("/a"))
+ assert.Equal(t, "base/a/b", m.buildMinioPath("/a/b/"))
+ assert.Equal(t, "base/", m.buildMinioDirPrefix(""))
+ assert.Equal(t, "base/a/", m.buildMinioDirPrefix("/a/"))
+}
+
+func TestS3StorageBadRequest(t *testing.T) {
+ if os.Getenv("CI") == "" {
+ t.Skip("S3Storage not present outside of CI")
+ return
+ }
+ cfg := &setting.Storage{
+ MinioConfig: setting.MinioStorageConfig{
+ Endpoint: "minio:9000",
+ AccessKeyID: "123456",
+ SecretAccessKey: "12345678",
+ Bucket: "bucket",
+ Location: "us-east-1",
+ },
+ }
+ message := "ERROR"
+ old := getBucketVersioning
+ defer func() { getBucketVersioning = old }()
+ getBucketVersioning = func(ctx context.Context, minioClient *minio.Client, bucket string) error {
+ return minio.ErrorResponse{
+ StatusCode: http.StatusBadRequest,
+ Code: "FixtureError",
+ Message: message,
+ }
+ }
+ _, err := NewStorage(setting.MinioStorageType, cfg)
+ require.ErrorContains(t, err, message)
+}
+
+func TestMinioCredentials(t *testing.T) {
+ const (
+ ExpectedAccessKey = "ExampleAccessKeyID"
+ ExpectedSecretAccessKey = "ExampleSecretAccessKeyID"
+ // Use a FakeEndpoint for IAM credentials to avoid logging any
+ // potential real IAM credentials when running in EC2.
+ FakeEndpoint = "http://localhost"
+ )
+
+ t.Run("Static Credentials", func(t *testing.T) {
+ cfg := setting.MinioStorageConfig{
+ AccessKeyID: ExpectedAccessKey,
+ SecretAccessKey: ExpectedSecretAccessKey,
+ }
+ creds := buildMinioCredentials(cfg, FakeEndpoint)
+ v, err := creds.Get()
+
+ require.NoError(t, err)
+ assert.Equal(t, ExpectedAccessKey, v.AccessKeyID)
+ assert.Equal(t, ExpectedSecretAccessKey, v.SecretAccessKey)
+ })
+
+ t.Run("Chain", func(t *testing.T) {
+ cfg := setting.MinioStorageConfig{}
+
+ t.Run("EnvMinio", func(t *testing.T) {
+ t.Setenv("MINIO_ACCESS_KEY", ExpectedAccessKey+"Minio")
+ t.Setenv("MINIO_SECRET_KEY", ExpectedSecretAccessKey+"Minio")
+
+ creds := buildMinioCredentials(cfg, FakeEndpoint)
+ v, err := creds.Get()
+
+ require.NoError(t, err)
+ assert.Equal(t, ExpectedAccessKey+"Minio", v.AccessKeyID)
+ assert.Equal(t, ExpectedSecretAccessKey+"Minio", v.SecretAccessKey)
+ })
+
+ t.Run("EnvAWS", func(t *testing.T) {
+ t.Setenv("AWS_ACCESS_KEY", ExpectedAccessKey+"AWS")
+ t.Setenv("AWS_SECRET_KEY", ExpectedSecretAccessKey+"AWS")
+
+ creds := buildMinioCredentials(cfg, FakeEndpoint)
+ v, err := creds.Get()
+
+ require.NoError(t, err)
+ assert.Equal(t, ExpectedAccessKey+"AWS", v.AccessKeyID)
+ assert.Equal(t, ExpectedSecretAccessKey+"AWS", v.SecretAccessKey)
+ })
+
+ t.Run("FileMinio", func(t *testing.T) {
+ t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/minio.json")
+ // prevent loading any actual credentials files from the user
+ t.Setenv("AWS_SHARED_CREDENTIALS_FILE", "testdata/fake")
+
+ creds := buildMinioCredentials(cfg, FakeEndpoint)
+ v, err := creds.Get()
+
+ require.NoError(t, err)
+ assert.Equal(t, ExpectedAccessKey+"MinioFile", v.AccessKeyID)
+ assert.Equal(t, ExpectedSecretAccessKey+"MinioFile", v.SecretAccessKey)
+ })
+
+ t.Run("FileAWS", func(t *testing.T) {
+ // prevent loading any actual credentials files from the user
+ t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/fake.json")
+ t.Setenv("AWS_SHARED_CREDENTIALS_FILE", "testdata/aws_credentials")
+
+ creds := buildMinioCredentials(cfg, FakeEndpoint)
+ v, err := creds.Get()
+
+ require.NoError(t, err)
+ assert.Equal(t, ExpectedAccessKey+"AWSFile", v.AccessKeyID)
+ assert.Equal(t, ExpectedSecretAccessKey+"AWSFile", v.SecretAccessKey)
+ })
+
+ t.Run("IAM", func(t *testing.T) {
+ // prevent loading any actual credentials files from the user
+ t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/fake.json")
+ t.Setenv("AWS_SHARED_CREDENTIALS_FILE", "testdata/fake")
+
+ // Spawn a server to emulate the EC2 Instance Metadata
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ // The client will actually make 3 requests here,
+ // first will be to get the IMDSv2 token, second to
+ // get the role, and third for the actual
+ // credentials. However, we can return credentials
+ // every request since we're not emulating a full
+ // IMDSv2 flow.
+ w.Write([]byte(`{"Code":"Success","AccessKeyId":"ExampleAccessKeyIDIAM","SecretAccessKey":"ExampleSecretAccessKeyIDIAM"}`))
+ }))
+ defer server.Close()
+
+ // Use the provided EC2 Instance Metadata server
+ creds := buildMinioCredentials(cfg, server.URL)
+ v, err := creds.Get()
+
+ require.NoError(t, err)
+ assert.Equal(t, ExpectedAccessKey+"IAM", v.AccessKeyID)
+ assert.Equal(t, ExpectedSecretAccessKey+"IAM", v.SecretAccessKey)
+ })
+ })
+}