package erasure import ( "context" "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "net/http" "net/http/httptest" "strings" "testing" "time" ) type mockShardStore struct { puts []string } func (m *mockShardStore) PutShard(_ context.Context, bucket, key string, _ []byte) error { m.puts = append(m.puts, bucket+"/"+key) return nil } func (m *mockShardStore) HeadBucket(context.Context, string) error { return nil } func TestAttachS3SwarmUploadsSixShards(t *testing.T) { priv, _ := rsa.GenerateKey(rand.Reader, 2048) pemBytes := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) store := &mockShardStore{} cfg := HydrateAWSSwarmFromEnv(AWSSwarmSettings{ S3Bucket: "my-bucket", CloudFrontDomain: "d123.cloudfront.net", Region: "us-east-1", AccessKeyID: "AKIA", SecretAccessKey: "secret", KeyPairID: "KPAIR", PrivateKeyPEM: string(pemBytes), }) shards := [][]byte{[]byte("a"), []byte("b"), []byte("c"), []byte("d"), []byte("e"), []byte("f")} hashes := ShardContentHashes(shards) result, err := AttachS3Swarm(context.Background(), cfg, store, "tok", "deadbeef", 6, DefaultParams(), shards, hashes) if err != nil || len(store.puts) != 6 || result == nil || !strings.Contains(result.SwarmMagnet, "xs=") { t.Fatalf("err=%v puts=%d result=%+v", err, len(store.puts), result) } } func TestS3HTTPStorePutShardSigV4(t *testing.T) { var method, auth string srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { method = r.Method auth = r.Header.Get("Authorization") w.WriteHeader(http.StatusOK) })) defer srv.Close() store := &S3HTTPStore{ Settings: AWSSwarmSettings{S3Bucket: "b", Region: "us-east-1", AccessKeyID: "A", SecretAccessKey: "s"}, Endpoint: srv.URL, } if err := store.PutShard(context.Background(), "b", "shards/tok/us-east-1/0-ab.bin", []byte("x")); err != nil { t.Fatal(err) } if method != http.MethodPut || !strings.HasPrefix(auth, "AWS4-HMAC-SHA256") { t.Fatalf("method=%s auth=%q", method, auth) } } func TestCloudFrontSignedShardURL(t *testing.T) { priv, _ := rsa.GenerateKey(rand.Reader, 2048) pemBytes := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) cfg := AWSSwarmSettings{S3Bucket: "b", CloudFrontDomain: "d.cf.net", KeyPairID: "K", PrivateKeyPEM: string(pemBytes)} u, err := CloudFrontSignedShardURL(cfg, "/shards/tok/us-east-1/0-ab.bin", time.Hour) if err != nil || !strings.Contains(u, "Expires=") { t.Fatalf("url=%q err=%v", u, err) } }