Storage
In-memory object storage modelled on S3, Azure Blob Storage, and GCS, driven with the real cloud SDKs
aws S3azr Blob Storagegcp GCS
Emulates managed object storage — the S3/Blob/GCS bucket where your app keeps uploads, exports, and config blobs. You create named buckets, then put, get, list, and copy objects as byte payloads with a content type and metadata. Everything lives in memory, so a test run starts from an empty store and leaves nothing behind.
Reach for it in tests whenever your code writes a file to a bucket and reads it back, paginates a listing, or copies objects between prefixes — so you can exercise those paths without a real S3 account or network. Because the SDK-compat server speaks the real wire protocol, your production upload/download code runs unchanged against it.
| Provider | Service | SDK-compat | Driver |
|---|---|---|---|
| AWS | S3 | ✓ Live | aws.S3 |
| Azure | Blob Storage | ✓ Live | azure.BlobStorage |
| GCP | GCS | ✓ Live | gcp.GCS |
Drive it with the real SDK#
The recommended path is to drop the SDK-compat server in front of cloudemu and point your existing production code at it — no code changes, just a rewritten endpoint. This example stands up an in-memory S3, creates a bucket, writes an object, and reads it back exactly as the real client would:
import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/stackshy/cloudemu/v2"
awsserver "github.com/stackshy/cloudemu/v2/server/aws"
)
cloud := cloudemu.NewAWS()
ts := httptest.NewServer(awsserver.New(awsserver.Drivers{S3: cloud.S3}))
defer ts.Close()
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.BaseEndpoint = aws.String(ts.URL)
o.UsePathStyle = true
})
client.CreateBucket(ctx, &s3.CreateBucketInput{Bucket: aws.String("my-bucket")})
client.PutObject(ctx, &s3.PutObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String("config.yaml"),
Body: bytes.NewReader([]byte("port: 8080")),
})
out, _ := client.GetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String("my-bucket"), Key: aws.String("config.yaml"),
})The same pattern works with armappservice / azblob (Azure) and cloud.google.com/go/storage (GCP). See the SDK-Compat Server page for full quick starts per provider.
Call the driver directly#
When you don't need to drive a real SDK — for example in cloudemu-only setup code — skip the HTTP hop and call the driver. The same three operations, minus the client boilerplate:
aws.S3.CreateBucket(ctx, "my-bucket")
aws.S3.PutObject(ctx, "my-bucket", "config.yaml", []byte("..."), "text/yaml", nil)
obj, _ := aws.S3.GetObject(ctx, "my-bucket", "config.yaml")PutObject's last two arguments are the content type and an optional metadata map (pass nil for none). GetObject returns the object with its data and info; a missing bucket or key returns an error.
Behavior & fidelity#
- Listings paginate and group.
ListObjectsV2honoursprefix,delimiter(with common prefixes),MaxKeys, and a continuation token — the same paging contract your production listing loop expects. - Copy is server-side.
CopyObjectduplicates the object and its metadata into the destination without a round-trip through your process. - Portable-API-only extras. The driver also exposes operations not yet on the SDK-compat surface — multipart upload, presigned URLs, lifecycle policies, versioning, bucket/object tagging, CORS, and encryption config. Reach for these through the Portable Go API when your test needs them.
- SDK-compat status — Live. CreateBucket, DeleteBucket, ListBuckets, PutObject, GetObject, HeadObject, DeleteObject, ListObjectsV2, and CopyObject all work through the real S3, Blob, and GCS SDKs today. See SDK-Compat for the current surface.