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#

BehaviorWhat happens
Listings paginate and groupListObjectsV2 honours prefix, delimiter (with common prefixes), MaxKeys, and a continuation token — the paging contract your listing loop expects.
Server-side copyCopyObject duplicates the object and its metadata into the destination without a round-trip through your process.
Portable-API-only extrasMultipart upload, presigned URLs, lifecycle policies, versioning, tagging, CORS, and encryption config are driver-only — reach for them through the Portable Go API.

SDK-compat — Live#

Real S3, Blob, and GCS clients drive object storage end-to-end — see SDK-Compat for the full operation list.

On this page

On this page