testutils

package
v0.0.0-...-56ba7c4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package testutils holds the shared harness for integration tests: network helpers, gRPC and local-transport cluster startup, cluster config builders, and replica-state assertions. Domain-specific helpers (split topologies, data-dir layout checks, ...) stay in their test packages; the application core they all run is one of testcore's playground cores (or NopCore).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AllReplicaStates

func AllReplicaStates(admin ReplicaStateLister, targets []string) []*transport.ReplicaState

AllReplicaStates concatenates the replica states of every target, skipping unreachable ones.

func BootstrapNodes

func BootstrapNodes(t *testing.T, admin *grpc.AdminClient, addrs []string, ids []string, cfg *cluster.Config)

BootstrapNodes provisions node ids[i] at addrs[i] with cfg over the admin plane.

func FindLeader

func FindLeader(states []*transport.ReplicaState) (*transport.ReplicaState, bool)

FindLeader returns the first replica reporting itself the Raft leader.

func FindReplicaState

func FindReplicaState(states []*transport.ReplicaState, replicaId string) (*transport.ReplicaState, bool)

FindReplicaState returns the state of the replica with the given id.

func FreeAddr

func FreeAddr(t *testing.T) string

FreeAddr returns a currently-free 127.0.0.1 address. There is a small window between closing the probe listener and the node binding it, which is acceptable for a test.

func FreeAddrs

func FreeAddrs(t *testing.T, n int) []string

FreeAddrs returns n currently-free 127.0.0.1 addresses.

func InMemoryNodeConfig

func InMemoryNodeConfig() monstera.NodeConfig

InMemoryNodeConfig returns the default node config with the in-memory Raft store — the standard configuration for integration tests.

func ListReplicaStates

func ListReplicaStates(admin ReplicaStateLister, target string) (map[string]*transport.ReplicaState, error)

ListReplicaStates returns the replica states of one node, keyed by replica id.

func NewPlaygroundStub

func NewPlaygroundStub(cfg *cluster.Config) *testcore.PlaygroundApiMonsteraStub

NewPlaygroundStub returns a testcore playground stub talking to the cluster described by cfg over gRPC.

func PushConfig

func PushConfig(t *testing.T, admin *grpc.AdminClient, addrs []string, cfg *cluster.Config)

PushConfig validates cfg and installs it on every node.

func RequireLeader

func RequireLeader(t *testing.T, admin ReplicaStateLister, targets []string, replicaIds map[string]bool)

RequireLeader waits until some replica on some target reports itself the Raft leader. A non-nil replicaIds set restricts the wait to those replicas (e.g. one shard's); nil accepts any replica.

func SingleShardConfig

func SingleShardConfig(t *testing.T, addrs []string, replicas int) *cluster.Config

SingleShardConfig builds the standard test topology: nodes "node_1" .. "node_N" at the given addresses, one application "Core" with replication factor `replicas`, and one full-range ACTIVE shard with a replica on each of the first `replicas` nodes (any remaining nodes host nothing — the add-node/move-shard target).

func SingleShardLocalConfig

func SingleShardLocalConfig(t *testing.T, nodes int, replicas int) *cluster.Config

SingleShardLocalConfig is SingleShardConfig for the local (in-memory) transport, where a node's address is its id.

func StartLocalNode

func StartLocalNode(t *testing.T, baseDir, nodeId string, config *cluster.Config, trans *local.LocalTransport, inMemory bool) *monstera.Node

StartLocalNode creates a monstera node on the local (in-memory) transport, starts it, bootstraps it if fresh, and registers it under its assigned id so peers can reach it (a fresh node has no id until Bootstrap).

func WaitForListen

func WaitForListen(t *testing.T, addr string)

WaitForListen blocks until something accepts TCP connections on addr.

Types

type GrpcCluster

type GrpcCluster struct {
	Nodes   []*monstera.Node
	Servers []*grpc.GrpcServer
}

GrpcCluster tracks in-process nodes and gRPC servers so they can be torn down in the right order.

func NewGrpcCluster

func NewGrpcCluster(t *testing.T) *GrpcCluster

NewGrpcCluster returns an empty cluster whose Stop is registered as a test cleanup.

func (*GrpcCluster) KillNode

func (c *GrpcCluster) KillNode(i int)

KillNode abruptly stops node i: the gRPC server is hard-stopped first (closing live connections and Raft streams, so peers see a crash rather than a drain), then the node is stopped to release its on-disk stores for a later restart. The slot stays in Nodes/Servers; Stop tolerates it.

func (*GrpcCluster) StartNode

func (c *GrpcCluster) StartNode(t *testing.T, nodeConfig monstera.NodeConfig, addr string, descriptors monstera.ApplicationCoreDescriptors) *monstera.Node

StartNode creates a monstera node with a fresh t.TempDir data dir, starts it (UNPROVISIONED — bootstrap separately), and serves it over gRPC on addr.

func (*GrpcCluster) StartNodeAt

func (c *GrpcCluster) StartNodeAt(t *testing.T, baseDir string, nodeConfig monstera.NodeConfig, addr string, descriptors monstera.ApplicationCoreDescriptors) *monstera.Node

StartNodeAt is StartNode with a caller-owned data dir, so a test can stop a node and start a fresh one over the same durable state (kill/restart scenarios). A dir holding a provisioned node's state comes back READY; a fresh dir comes up UNPROVISIONED.

func (*GrpcCluster) Stop

func (c *GrpcCluster) Stop()

Stop tears the cluster down in two phases: stop every node first (each moves to STOPPED, rejecting Raft RPCs and cancelling its outbound streams), then GracefulStop every server. Stopping all nodes before any server prevents GracefulStop from blocking on Raft streams held open by peers that haven't been stopped yet — which deadlocks once a shard replica spans several running nodes.

type ReplicaStateLister

type ReplicaStateLister interface {
	ListReplicaStates(ctx context.Context, target string) ([]*transport.ReplicaState, error)
}

ReplicaStateLister is the one admin-plane call the state helpers need. Both grpc.AdminClient (target = address) and local.LocalTransport (target = node id) satisfy it, so the same assertions work over either harness.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL