Documentation
¶
Overview ¶
Package foundationdb provides a testcontainers module for FoundationDB.
This module creates a single FoundationDB container (no socat proxy) and provides two connectivity modes:
- External (host/sandbox): via Docker port mapping (localhost:mappedPort). Works from Bazel sandboxes, CI runners, Docker Desktop, etc.
- Internal (cross-container): via Docker bridge IP (containerIP:4500). Used by sidecar containers on the same Docker network.
The container is auto-initialized by default (configured for single-node operation with tenant support). Use WithoutInit to skip.
Basic usage:
container, err := foundationdb.Run(ctx, "") clusterFile, _ := container.ClusterFile(ctx) db, _ := fdb.OpenDatabase(writeToFile(clusterFile))
Multi-container usage (e.g., binding tester):
nw, _ := foundationdb.CreateNetwork(ctx)
fdb, _ := foundationdb.Run(ctx, "", foundationdb.WithNetwork(nw))
// Attach another container to the same network:
otherReq.Networks = []string{fdb.NetworkName()}
// Use InternalClusterFile() for the other container's cluster file.
Index ¶
- func CreateNetwork(ctx context.Context) (*testcontainers.DockerNetwork, error)
- type Cluster
- type Container
- func (c *Container) APIVersion() int
- func (c *Container) ClusterFile(_ context.Context) (string, error)
- func (c *Container) ClusterFilePath(_ context.Context) (string, error)
- func (c *Container) ConnectionString(ctx context.Context) (string, error)
- func (c *Container) Database() string
- func (c *Container) FDBCLIExec(ctx context.Context, command string) (string, error)
- func (c *Container) FDBPort() int
- func (c *Container) InitializeDatabase(ctx context.Context) error
- func (c *Container) InternalAddress() string
- func (c *Container) InternalClusterFile() string
- func (c *Container) MappedPort() int
- func (c *Container) MustClusterFile(ctx context.Context) string
- func (c *Container) NetworkName() string
- func (c *Container) Pause(ctx context.Context) error
- func (c *Container) Status(ctx context.Context) (string, error)
- func (c *Container) Terminate(ctx context.Context) error
- func (c *Container) Unpause(ctx context.Context) error
- func (c *Container) Version() string
- type Option
- func WithAPIVersion(version int) Option
- func WithDataOnDisk() Option
- func WithDatabase(name string) Option
- func WithDirectIP() Option
- func WithFDBPort(port int) Option
- func WithKnob(name, value string) Option
- func WithNetwork(nw *testcontainers.DockerNetwork, aliases ...string) Option
- func WithNetworkAliases(aliases ...string) Option
- func WithProcessCount(n int) Option
- func WithRedundancyMode(mode string) Option
- func WithStartupTimeout(timeout time.Duration) Option
- func WithStorageEngine(engine string) Option
- func WithTenantMode(mode string) Option
- func WithVersion(version string) Option
- func WithoutInit() Option
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CreateNetwork ¶
func CreateNetwork(ctx context.Context) (*testcontainers.DockerNetwork, error)
CreateNetwork creates a new Docker network. This is a convenience for tests that need to share a network between multiple containers without letting each Run call create its own.
The caller is responsible for removing the network.
Types ¶
type Cluster ¶
type Cluster struct {
Coordinator *Container
Replicas []*Container // all containers including coordinator
// contains filtered or unexported fields
}
Cluster represents a multi-container FDB cluster. Each container runs one fdbserver process. The first is the coordinator.
Example:
cluster, err := foundationdb.RunCluster(ctx, 3,
foundationdb.WithStorageEngine("ssd"),
foundationdb.WithRedundancyMode("double"),
)
defer cluster.Terminate(ctx)
cf, _ := cluster.ClusterFile(ctx)
func RunCluster ¶
func RunCluster(ctx context.Context, size int, opts ...testcontainers.ContainerCustomizer) (*Cluster, error)
RunCluster creates an N-container FDB cluster on a shared Docker network. The first container is the coordinator; additional containers join as storage.
All options from Run() are supported. WithNetwork is set automatically.
func (*Cluster) ClusterFile ¶
ClusterFile returns the cluster file for external clients (via coordinator).
func (*Cluster) InternalClusterFile ¶
InternalClusterFile returns the cluster file for containers on the same network.
type Container ¶
type Container struct {
testcontainers.Container
// contains filtered or unexported fields
}
Container represents a running FoundationDB container.
External clients (host, Bazel sandbox) connect via localhost:mappedPort. Internal clients (containers on the same Docker network) connect via containerIP:4500.
func Run ¶
func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*Container, error)
Run creates, starts, and (by default) initializes a FoundationDB container.
The container exposes FDB port 4500 via Docker port mapping. External clients (including Bazel sandbox tests) connect via localhost:mappedPort. For cross-container communication, use [InternalClusterFile] with a shared network via WithNetwork.
By default, the database is auto-initialized for single-node operation with tenant_mode=optional_experimental. Use WithoutInit to skip initialization.
The image parameter can be empty ("") to use the default image with the version from FDB_VERSION env var or the built-in default.
Example ¶
ctx := context.Background()
// Start a FoundationDB container — auto-initialized, ready to use.
container, err := Run(ctx, "")
if err != nil {
log.Fatal(err)
}
defer container.Terminate(ctx)
clusterFile, err := container.ClusterFile(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Cluster file: %s\n", clusterFile)
Example (WithCustomConfiguration) ¶
ctx := context.Background()
container, err := Run(ctx, "",
WithDatabase("my_test_db"),
WithAPIVersion(720),
WithVersion("7.1.61"),
)
if err != nil {
log.Fatal(err)
}
defer container.Terminate(ctx)
fmt.Printf("Database: %s\n", container.Database())
fmt.Printf("API Version: %d\n", container.APIVersion())
fmt.Printf("Version: %s\n", container.Version())
func (*Container) APIVersion ¶
APIVersion returns the configured FDB API version.
func (*Container) ClusterFile ¶
ClusterFile returns the cluster file content for external clients. Uses localhost:mappedPort, which works from Bazel sandboxes, CI runners, etc.
func (*Container) ClusterFilePath ¶
ClusterFilePath writes the cluster file to a temp file and returns the path. The file persists until the caller removes it.
func (*Container) ConnectionString ¶
ConnectionString returns "host:port" for the FDB server (external, port-mapped).
func (*Container) FDBCLIExec ¶
FDBCLIExec runs an fdbcli command inside the container and returns the output.
Example:
output, err := container.FDBCLIExec(ctx, "status details")
Example ¶
ctx := context.Background()
container, err := Run(ctx, "")
if err != nil {
log.Fatal(err)
}
defer container.Terminate(ctx)
output, err := container.FDBCLIExec(ctx, "status minimal")
if err != nil {
log.Fatal(err)
}
fmt.Printf("FDB status: %s\n", output)
func (*Container) InitializeDatabase ¶
InitializeDatabase configures the database for single-node operation. This is called automatically by Run unless WithoutInit is used.
The configure command uses the storage engine and redundancy mode from options. Default: "memory" engine, "single" redundancy, tenant_mode=optional_experimental.
This method is idempotent — calling it on an already-configured database is safe.
func (*Container) InternalAddress ¶
InternalAddress returns the FDB address reachable from within Docker networks. Uses the container's bridge IP: "containerIP:4500".
func (*Container) InternalClusterFile ¶
InternalClusterFile returns a cluster file string usable from containers on the same Docker network. Uses the container's bridge IP (no port mapping needed).
func (*Container) MappedPort ¶
MappedPort returns the host port mapped to FDB's container port.
func (*Container) MustClusterFile ¶
MustClusterFile returns the cluster file content, panicking on error.
func (*Container) NetworkName ¶
NetworkName returns the Docker network name. Returns empty string if the container is on the default bridge (no custom network). Use this to attach other containers to the same network for inter-container communication.
func (*Container) Pause ¶
Pause freezes all processes in the container using Docker pause. The container remains running but FDB becomes unreachable. TCP connections stay open but will time out. Use this to simulate network partitions or FDB hangs.
Call [Unpause] to resume.
func (*Container) Terminate ¶
Terminate terminates the container. The network, if user-provided via WithNetwork, is NOT removed — the caller owns it.
type Option ¶
type Option struct {
// contains filtered or unexported fields
}
Option configures the FoundationDB container. Options implement testcontainers.ContainerCustomizer so they can be mixed with standard testcontainers options in the Run call.
func WithAPIVersion ¶
WithAPIVersion sets the FDB API version. This is metadata for callers to know which version to pass to fdb.MustAPIVersion(). It doesn't configure the container.
func WithDataOnDisk ¶
func WithDataOnDisk() Option
WithDataOnDisk stores /var/fdb/data on disk (the container's writable layer) instead of the default tmpfs. The default tmpfs keeps tests fast and avoids a leaked anonymous volume, but caps a dataset at host RAM; use this (with an SSD storage engine, e.g. WithStorageEngine("ssd-redwood-1")) for datasets larger than memory. The container's anonymous data volume is on disk and is cleaned up with the container.
func WithDatabase ¶
WithDatabase sets the database name. This is metadata for callers — FDB itself doesn't have named databases (it has one keyspace per cluster).
func WithDirectIP ¶
func WithDirectIP() Option
WithDirectIP makes Container.ClusterFile return the container's bridge IP instead of localhost:mappedPort. This avoids Docker DNAT which causes FDB canonicalRemotePort assertion spam under high connection churn.
Direct IP requires the test process to route to Docker bridge IPs. This works on Linux hosts but NOT from Bazel's linux-sandbox.
func WithFDBPort ¶
WithFDBPort overrides the default FDB port (4500). This sets the FDB_PORT environment variable in the container.
func WithKnob ¶
WithKnob sets a server-side FDB knob. Knobs are passed as --knob_NAME=VALUE to the fdbserver process. This is useful for forcing shard splits (e.g., WithKnob("min_shard_bytes", "40000")) or other server behavior changes.
The knob is injected by modifying the entrypoint script inside the container. Multiple WithKnob calls accumulate.
func WithNetwork ¶
func WithNetwork(nw *testcontainers.DockerNetwork, aliases ...string) Option
WithNetwork attaches the container to an existing Docker network instead of creating a new one. The network will NOT be removed on Container.Terminate. Additional aliases can be specified for DNS resolution within the network.
Example ¶
ctx := context.Background()
// Create a shared network for multi-container setups.
nw, err := CreateNetwork(ctx)
if err != nil {
log.Fatal(err)
}
defer nw.Remove(ctx)
container, err := Run(ctx, "",
WithNetwork(nw, "fdb-primary"),
)
if err != nil {
log.Fatal(err)
}
defer container.Terminate(ctx)
fmt.Printf("Network: %s\n", container.NetworkName())
fmt.Printf("Internal address: %s\n", container.InternalAddress())
func WithNetworkAliases ¶
WithNetworkAliases adds network aliases for the container. These are DNS names resolvable by other containers on the same Docker network.
func WithProcessCount ¶
WithProcessCount sets the number of fdbserver processes to run inside the container. Default is 1. When n > 1, additional processes are started on ports 4501..4500+n-1 after the primary process joins the cluster.
Use with WithRedundancyMode("double") or ("triple") to enable data replication across processes. Multiple storage servers enable shard splits, which is required for testing cross-shard GetRange behavior.
Example:
Run(ctx, "",
WithProcessCount(3),
WithRedundancyMode("double"),
WithKnob("min_shard_bytes", "40000"),
)
func WithRedundancyMode ¶
WithRedundancyMode configures FDB replication for the configure command. Valid values: "single" (default), "double", "triple".
func WithStartupTimeout ¶
WithStartupTimeout sets the timeout for waiting for the FDB container to start. Default: 60 seconds.
func WithStorageEngine ¶
WithStorageEngine configures the FDB storage engine for the configure command. Valid values: "memory" (default, fast for tests), "ssd" (persistent).
func WithTenantMode ¶
WithTenantMode configures FDB tenant mode for the configure command. Valid values: "disabled", "optional_experimental", "required". Default: "optional_experimental".
func WithVersion ¶
WithVersion sets the FoundationDB Docker image tag.
func WithoutInit ¶
func WithoutInit() Option
WithoutInit skips automatic database initialization in Run. Use Container.InitializeDatabase for manual initialization.
func (Option) Customize ¶
func (o Option) Customize(_ *testcontainers.GenericContainerRequest) error
Customize implements testcontainers.ContainerCustomizer. Module options don't modify the container request directly — they configure our options struct.