Star 历史趋势
数据来源: GitHub API · 生成自 Stargazers.cn
README.md

testcontainers-floci-go

Go Reference CI License: MIT

Go Testcontainers module for Floci — the open-source, drop-in replacement for LocalStack Community Edition.

Floci emulates 42 AWS services in a single container with:

  • ~24 ms startup time (native image)
  • ~13 MiB idle memory
  • ~90 MB Docker image
  • No auth tokens, no feature gates, MIT license

Installation

go get github.com/floci-io/testcontainers-floci-go

Requires Go 1.25+ and a running Docker daemon.

Quick start

package myservice_test

import (
    "context"
    "strings"
    "testing"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/credentials"
    "github.com/aws/aws-sdk-go-v2/service/s3"

    floci "github.com/floci-io/testcontainers-floci-go"
)

func TestS3(t *testing.T) {
    ctx := context.Background()

    fc, err := floci.NewFlociContainer().Start(ctx)
    if err != nil {
        t.Fatal(err)
    }
    t.Cleanup(func() { _ = fc.Stop(ctx) })

    cfg, err := config.LoadDefaultConfig(ctx,
        config.WithRegion(fc.GetRegion()),
        config.WithBaseEndpoint(fc.GetEndpoint()),
        config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(
            fc.GetAccessKey(), fc.GetSecretKey(), "",
        )),
    )
    if err != nil {
        t.Fatal(err)
    }

    client := s3.NewFromConfig(cfg, func(o *s3.Options) {
        o.UsePathStyle = true // required for local endpoints
    })

    _, err = client.CreateBucket(ctx, &s3.CreateBucketInput{
        Bucket: aws.String("my-bucket"),
    })
    if err != nil {
        t.Fatal(err)
    }

    _, err = client.PutObject(ctx, &s3.PutObjectInput{
        Bucket: aws.String("my-bucket"),
        Key:    aws.String("hello.txt"),
        Body:   strings.NewReader("hello from floci"),
    })
    if err != nil {
        t.Fatal(err)
    }

    out, err := client.ListObjectsV2(ctx, &s3.ListObjectsV2Input{
        Bucket: aws.String("my-bucket"),
    })
    if err != nil {
        t.Fatal(err)
    }

    t.Logf("objects: %d", len(out.Contents))
}

S3 note: always use strings.NewReader or bytes.NewReader (seekable) when uploading objects. bytes.NewBufferString is not seekable and causes the AWS SDK to attempt trailing checksums, which require TLS and fail against a plain HTTP local endpoint.

Sharing a container across tests

Use TestMain to start the container once for the whole package:

package myservice_test

import (
    "context"
    "os"
    "testing"

    floci "github.com/floci-io/testcontainers-floci-go"
)

var fc *floci.StartedFlociContainer

func TestMain(m *testing.M) {
    ctx := context.Background()
    var err error
    fc, err = floci.NewFlociContainer().Start(ctx)
    if err != nil {
        panic(err)
    }
    code := m.Run()
    _ = fc.Stop(ctx)
    os.Exit(code)
}

Service configuration

Each of Floci's 42 services can be configured individually using typed config structs. Pass any struct to the corresponding With*Config method — unset fields keep their defaults.

S3

fc, _ := floci.NewFlociContainer().
    WithS3Config(floci.S3Config{
        Enabled:                     true,
        DefaultPresignExpirySeconds: 7200,
    }).
    Start(ctx)

SQS

fc, _ := floci.NewFlociContainer().
    WithSqsConfig(floci.SqsConfig{
        Enabled:                  true,
        DefaultVisibilityTimeout: 60,
        MaxMessageSize:           262144,
    }).
    Start(ctx)

DynamoDB

fc, _ := floci.NewFlociContainer().
    WithDynamoDbConfig(floci.DynamoDbConfig{Enabled: true}).
    Start(ctx)

Lambda

fc, _ := floci.NewFlociContainer().
    WithDedicatedNetwork(). // required for Lambda to reach Floci
    WithLambdaConfig(floci.LambdaConfig{
        Enabled:               true,
        DefaultMemoryMb:       256,
        DefaultTimeoutSeconds: 30,
        HotReloadEnabled:      true,
        ExposeRuntimePorts:    true, // invoke Lambdas from the host
    }).
    Start(ctx)

RDS (PostgreSQL / MySQL / MariaDB)

fc, _ := floci.NewFlociContainer().
    WithDedicatedNetwork().
    WithRdsConfig(floci.RdsConfig{
        Enabled:              true,
        DefaultPostgresImage: "postgres:16-alpine",
    }).
    Start(ctx)

ElastiCache (Redis / Valkey)

fc, _ := floci.NewFlociContainer().
    WithDedicatedNetwork().
    WithElastiCacheConfig(floci.ElastiCacheConfig{
        Enabled:      true,
        DefaultImage: "valkey/valkey:8",
    }).
    Start(ctx)

OpenSearch

fc, _ := floci.NewFlociContainer().
    WithDedicatedNetwork().
    WithOpenSearchConfig(floci.OpenSearchConfig{
        Enabled: true,
        Mock:    false,
    }).
    Start(ctx)

MSK (Kafka via Redpanda)

fc, _ := floci.NewFlociContainer().
    WithDedicatedNetwork().
    WithMskConfig(floci.MskConfig{
        Enabled:      true,
        DefaultImage: "redpandadata/redpanda:latest",
    }).
    Start(ctx)

All available config structs

StructAWS service
AcmConfigAWS Certificate Manager
ApiGatewayConfigAPI Gateway (v1)
ApiGatewayV2ConfigAPI Gateway (v2)
AppConfigConfigAppConfig
AppConfigDataConfigAppConfig Data
AthenaConfigAthena
BedrockRuntimeConfigBedrock Runtime
CloudFormationConfigCloudFormation
CloudWatchLogsConfigCloudWatch Logs
CloudWatchMetricsConfigCloudWatch Metrics
CodeBuildConfigCodeBuild
CodeDeployConfigCodeDeploy
CognitoConfigCognito
DynamoDbConfigDynamoDB
Ec2ConfigEC2
EcrConfigECR
EcsConfigECS
EksConfigEKS
ElastiCacheConfigElastiCache
ElbV2ConfigELB v2
EventBridgeConfigEventBridge
FirehoseConfigKinesis Firehose
GlueConfigGlue
IamConfigIAM
KinesisConfigKinesis
KmsConfigKMS
LambdaConfigLambda
MskConfigMSK (Kafka)
OpenSearchConfigOpenSearch
PipesConfigEventBridge Pipes
RdsConfigRDS
ResourceGroupsTaggingConfigResource Groups Tagging
S3ConfigS3
SchedulerConfigEventBridge Scheduler
SecretsManagerConfigSecrets Manager
SesConfigSES
SesV2ConfigSES v2
SnsConfigSNS
SqsConfigSQS
SsmConfigSSM Parameter Store
StepFunctionsConfigStep Functions

Container options

fc, _ := floci.NewFlociContainer().
    WithImage("floci/floci:latest").   // pin a specific tag
    WithRegion("eu-west-1").
    WithAccountID("111122223333").
    WithAvailabilityZone("eu-west-1a").
    WithDedicatedNetwork().            // isolated Docker network for stateful services
    Start(ctx)

Connection details

MethodReturns
GetEndpoint()http://host:port — pass as base endpoint to AWS SDK clients
GetRegion()AWS region string
GetAccessKey()Access key ("test")
GetSecretKey()Secret key ("test")
GetAccountID()AWS account ID
GetAvailabilityZone()Availability zone
GetDedicatedNetworkName()Docker network name (empty if none)
GetMappedPort(ctx, port)Host port mapped from the given container port

Dedicated network

Services that spawn real Docker containers (Lambda, RDS, ElastiCache, MSK, OpenSearch, ECR, EKS) need a Docker network to communicate with Floci. Call WithDedicatedNetwork() to have the module create and manage one automatically:

fc, _ := floci.NewFlociContainer().
    WithDedicatedNetwork().
    WithLambdaConfig(floci.LambdaConfig{Enabled: true}).
    Start(ctx)

// The network name is passed to Floci automatically via FLOCI_SERVICES_DOCKER_NETWORK.
// fc.GetDedicatedNetworkName() returns it if you need it elsewhere.

The network is removed when Stop is called.

Docker image variants

TagDescription
floci/floci:latestNative image — sub-second startup (recommended)
floci/floci:x.y.zPinned release
floci/floci:latest-compatIncludes Python 3, AWS CLI, and boto3
floci/floci:nightlyLatest nightly build from main

Requirements

  • Go 1.25+
  • Docker (running locally or in CI)
  • github.com/testcontainers/testcontainers-go v0.42.0

Examples

Running the tests

go test -v ./...

Requires Docker running locally; the floci/floci:latest image is pulled automatically on first run.

Related projects

License

MIT

关于 About

No description, website, or topics provided.

语言 Languages

Go100.0%

提交活跃度 Commit Activity

代码提交热力图
过去 52 周的开发活跃度
10
Total Commits
峰值: 2次/周
Less
More

核心贡献者 Contributors