Skip to content
cloudemu
Services

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.

ProviderServiceSDK-compatDriver
AWSS3✓ Liveaws.S3
AzureBlob Storage✓ Liveazure.BlobStorage
GCPGCS✓ Livegcp.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. ListObjectsV2 honours prefix, delimiter (with common prefixes), MaxKeys, and a continuation token — the same paging contract your production listing loop expects.
  • Copy is server-side. CopyObject duplicates 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.

On this page

On this page