Skip to content

Commit

Permalink
Fix incorrect checksum (base64 encoded).
Browse files Browse the repository at this point in the history
Create bucket in unittest instead of GitHub Actions.
  • Loading branch information
iredmail committed Sep 6, 2023
1 parent e735c69 commit 4dfe51a
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 30 deletions.
9 changes: 1 addition & 8 deletions .github/workflows/test-s3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,7 @@ jobs:
- 1.21.x
steps:
- name: Install MinIO
run: |
docker run -d -p 9000:9000 --name minio minio/minio server /data
export AWS_ACCESS_KEY_ID=minioadmin
export AWS_SECRET_ACCESS_KEY=minioadmin
export AWS_EC2_METADATA_DISABLED=true
aws --endpoint-url http://127.0.0.1:9000/ s3 mb s3://testbucket
run: docker run -d -p 9000:9000 --name minio minio/minio server /data
- name: Fetch Repository
uses: actions/checkout@v4
- name: Install Go
Expand Down
22 changes: 19 additions & 3 deletions s3/init_test.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,38 @@
package s3

import (
"os"
"testing"
"time"
)

const (
bucket = "testbucket"
)

var testStore *Storage

func init() {
func TestMain(m *testing.M) {
testStore = New(
Config{
Bucket: "testbucket",
Bucket: bucket,
Endpoint: "http://127.0.0.1:9000/",
Region: "us-east-1",
Credentials: Credentials{
AccessKey: "minioadmin",
SecretAccessKey: "minioadmin",
},
RequestTimeout: 10 * time.Second,
RequestTimeout: 3 * time.Second,
},
)

// Create test bucket.
_ = testStore.CreateBucket(bucket)

exitVal := m.Run()

// Delete test bucket.
_ = testStore.DeleteBucket(bucket)

os.Exit(exitVal)
}
6 changes: 3 additions & 3 deletions s3/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func (s *Storage) Close() error {
return nil
}

// Return database client
// Conn returns database client.
func (s *Storage) Conn() *s3.Client {
return s.svc
}
Expand All @@ -186,11 +186,11 @@ func returnAWSConfig(cfg Config) (aws.Config, error) {
})

if cfg.Credentials != (Credentials{}) {
credentials := credentials.NewStaticCredentialsProvider(cfg.Credentials.AccessKey, cfg.Credentials.SecretAccessKey, "")
creds := credentials.NewStaticCredentialsProvider(cfg.Credentials.AccessKey, cfg.Credentials.SecretAccessKey, "")
return awsconfig.LoadDefaultConfig(context.TODO(),
awsconfig.WithRegion(cfg.Region),
awsconfig.WithEndpointResolverWithOptions(endpoint),
awsconfig.WithCredentialsProvider(credentials),
awsconfig.WithCredentialsProvider(creds),
awsconfig.WithRetryer(func() aws.Retryer {
return retry.AddWithMaxAttempts(retry.NewStandard(), cfg.MaxAttempts)
}),
Expand Down
45 changes: 36 additions & 9 deletions s3/s3_methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package s3

import (
"bytes"
"encoding/base64"
"fmt"

"github.com/aws/aws-sdk-go-v2/aws"
Expand All @@ -11,6 +12,29 @@ import (

// Additional methods for S3, but not required by gofiber Storage interface.

// CreateBucket creates a new bucket.
func (s *Storage) CreateBucket(bucket string) error {
ctx, cancel := s.requestContext()
defer cancel()

_, err := s.svc.CreateBucket(ctx, &s3.CreateBucketInput{
Bucket: aws.String(bucket),
})

return err
}

func (s *Storage) DeleteBucket(bucket string) error {
ctx, cancel := s.requestContext()
defer cancel()

_, err := s.svc.DeleteBucket(ctx, &s3.DeleteBucketInput{
Bucket: aws.String(bucket),
})

return err
}

// SetWithChecksum sets key with value and checksum.
//
// Currently 4 algorithms are supported:
Expand All @@ -25,31 +49,34 @@ func (s *Storage) SetWithChecksum(key string, val []byte, checksum map[types.Che
return nil
}

ctx, cancel := s.requestContext()
defer cancel()

poi := &s3.PutObjectInput{
poi := s3.PutObjectInput{
Bucket: &s.bucket,
Key: aws.String(key),
Body: bytes.NewReader(val),
}

for alg, sum := range checksum {
// S3 requires base64 encoded checksum.
b64str := base64.StdEncoding.EncodeToString(sum)

switch alg {
case types.ChecksumAlgorithmCrc32:
poi.ChecksumCRC32 = aws.String(string(sum))
poi.ChecksumCRC32 = aws.String(b64str)
case types.ChecksumAlgorithmCrc32c:
poi.ChecksumCRC32C = aws.String(string(sum))
poi.ChecksumCRC32C = aws.String(b64str)
case types.ChecksumAlgorithmSha1:
poi.ChecksumSHA1 = aws.String(string(sum))
poi.ChecksumSHA1 = aws.String(b64str)
case types.ChecksumAlgorithmSha256:
poi.ChecksumSHA256 = aws.String(string(sum))
poi.ChecksumSHA256 = aws.String(b64str)
default:
return fmt.Errorf("invalid checksum algorithm: %s", alg)
}
}

_, err := s.uploader.Upload(ctx, poi)
ctx, cancel := s.requestContext()
defer cancel()

_, err := s.uploader.Upload(ctx, &poi)

return err
}
37 changes: 30 additions & 7 deletions s3/s3_methods_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,43 @@ import (
"github.com/stretchr/testify/require"
)

func Test_S3_CreateDeleteBucket(t *testing.T) {
bkt := "test-new-bucket"

err := testStore.CreateBucket(bkt)
require.NoError(t, err)

err = testStore.DeleteBucket(bkt)
require.NoError(t, err)
}

func Test_S3_SetWithChecksum(t *testing.T) {
var (
key = "set-with-checksum"
val = []byte("doe")
sha256sum = sha256.New().Sum(val)
checksum = map[types.ChecksumAlgorithm][]byte{
types.ChecksumAlgorithmSha256: sha256sum,
}
key = "set-with-checksum"
val = []byte("doe")
)

// Create SHA-256 hash and get checksum.
sha256Hash := sha256.New()
sha256Hash.Write(val)
sha256sum := sha256Hash.Sum(nil)

checksum := map[types.ChecksumAlgorithm][]byte{
types.ChecksumAlgorithmSha256: sha256sum,
}

err := testStore.SetWithChecksum(key, val, checksum)
require.NoError(t, err)

result, err := testStore.Get(key)
require.NoError(t, err)
require.Equal(t, sha256sum, sha256.New().Sum(result))

// Compare value.
require.Equal(t, result, val)

// Compare checksum.
hash2 := sha256.New()
hash2.Write(result)
sha256sum2 := hash2.Sum(nil)
require.Equal(t, sha256sum, sha256sum2)
}

0 comments on commit 4dfe51a

Please sign in to comment.