testutil

package
v0.18.5 Latest Latest
Warning

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

Go to latest
Published: May 8, 2024 License: Apache-2.0 Imports: 37 Imported by: 0

Documentation

Overview

Package testutil contains utility functions for writing tests for the grpcvtctldserver.

Index

Constants

View Source
const BackupStorageImplementation = "grpcvtctldserver.testutil"

BackupStorageImplementation is the name this package registers its test backupstorage.BackupStorage implementation as. Users should set *backupstorage.BackupStorageImplementation to this value before use.

Variables

View Source
var BackupStorage = &backupStorage{
	Backups: map[string][]string{},
}

BackupStorage is the singleton test backupstorage.BackupStorage intastnce. It is public and singleton to allow tests to both mutate and assert against its state.

Functions

func AddKeyspace

func AddKeyspace(ctx context.Context, t *testing.T, ts *topo.Server, ks *vtctldatapb.Keyspace)

AddKeyspace adds a keyspace to a topology, failing a test if that keyspace could not be added. It shallow copies the proto struct to prevent XXX_ fields from changing in the marshalling.

func AddKeyspaces

func AddKeyspaces(ctx context.Context, t *testing.T, ts *topo.Server, keyspaces ...*vtctldatapb.Keyspace)

AddKeyspaces adds a list of keyspaces to the topology, failing a test if any of those keyspaces cannot be added. See AddKeyspace for details.

func AddShards

func AddShards(ctx context.Context, t *testing.T, ts *topo.Server, shards ...*vtctldatapb.Shard)

AddShards adds a list of shards to the topology, failing a test if any of the shard records could not be created. It also ensures that every shard's keyspace exists, or creates an empty keyspace if that shard's keyspace does not exist.

func AddSrvKeyspaces

func AddSrvKeyspaces(t *testing.T, ts *topo.Server, srvKeyspaces ...*SrvKeyspace)

AddSrvKeyspaces adds one or more SrvKeyspace objects to the topology. It fails the calling test if any of the objects fail to update.

func AddTablet

func AddTablet(ctx context.Context, t *testing.T, ts *topo.Server, tablet *topodatapb.Tablet, opts *AddTabletOptions)

AddTablet adds a tablet to the topology, failing a test if that tablet record could not be created. It shallow copies to prevent XXX_ fields from changing, including nested proto message fields.

AddTablet also optionally adds empty keyspace and shard records to the topology, if they are set on the tablet record and they cannot be retrieved from the topo server without error.

If AddTablet receives a tablet record with a keyspace and shard set, and that tablet's type is PRIMARY, and opts.AlsoSetShardPrimary is set, then AddTablet will update the shard record to make that tablet the shard primary and set the shard to serving. If that shard record already has a serving primary, then AddTablet will fail the test.

func AddTablets

func AddTablets(ctx context.Context, t *testing.T, ts *topo.Server, opts *AddTabletOptions, tablets ...*topodatapb.Tablet)

AddTablets adds a list of tablets to the topology. See AddTablet for more details.

func AssertEmergencyReparentShardResponsesEqual

func AssertEmergencyReparentShardResponsesEqual(t *testing.T, expected *vtctldatapb.EmergencyReparentShardResponse, actual *vtctldatapb.EmergencyReparentShardResponse, msgAndArgs ...any)

AssertEmergencyReparentShardResponsesEqual asserts that two vtctldatapb.EmergencyReparentShardResponse objects are equal, ignoring their respective Events field in the comparison.

func AssertKeyspacesEqual

func AssertKeyspacesEqual(t *testing.T, expected *vtctldatapb.Keyspace, actual *vtctldatapb.Keyspace, msgAndArgs ...any)

AssertKeyspacesEqual is a convenience function to assert that two vtctldatapb.Keyspace objects are equal, after clearing out any reserved proto XXX_ fields.

func AssertLogutilEventsMatch added in v0.13.0

func AssertLogutilEventsMatch(t testing.TB, expected []*logutilpb.Event, actual []*logutilpb.Event)

AssertLogutilEventsMatch asserts that two slices of Events match, by their .Value fields. In the expected slice, .Value is treated as a regular expression; that is, it is passed as a regexp-like string to assert.Regexp.

NOTE: To match events independent of ordering, callers should run both their expected and actual event slices through the EventValueSorter before calling this function. This will mutate the slices, so make a copy first if that is an issue for your use case.

func AssertLogutilEventsOccurred

func AssertLogutilEventsOccurred(t *testing.T, container interface{ GetEvents() []*logutilpb.Event }, msgAndArgs ...any)

AssertLogutilEventsOccurred asserts that for something containing a slice of logutilpb.Event, that the container is non-nil, and the event slice is non-zero.

This test function is generalized with an anonymous interface that any protobuf type containing a slice of logutilpb.Event elements called Events, which is the convention in protobuf types in the Vitess codebase, already implements.

func AssertNoLogutilEventsOccurred

func AssertNoLogutilEventsOccurred(t *testing.T, container interface{ GetEvents() []*logutilpb.Event }, msgAndArgs ...any)

AssertNoLogutilEventsOccurred asserts that for something containing a slice of logutilpb.Event, that the container is either nil, or that the event slice is exactly zero length.

This test function is generalized with an anonymous interface that any protobuf type containing a slice of logutilpb.Event elements called Events, which is the convention in protobuf types in the Vitess codebase, already implements.

func AssertPlannedReparentShardResponsesEqual

func AssertPlannedReparentShardResponsesEqual(t *testing.T, expected *vtctldatapb.PlannedReparentShardResponse, actual *vtctldatapb.PlannedReparentShardResponse)

AssertPlannedReparentShardResponsesEqual asserts that two vtctldatapb.PlannedReparentShardResponse objects are equal, ignoring their respective Events field in the comparison.

func AssertSameTablets added in v0.11.0

func AssertSameTablets(t *testing.T, expected, actual []*topodatapb.Tablet)

func MockGetVersionFromTablet added in v0.14.0

func MockGetVersionFromTablet(addrVersionMap map[string]string) func(ta string) (string, error)

func NewVtctldServerWithTabletManagerClient

func NewVtctldServerWithTabletManagerClient(t testing.TB, ts *topo.Server, tmc tmclient.TabletManagerClient, newVtctldServerFn func(ts *topo.Server) vtctlservicepb.VtctldServer) vtctlservicepb.VtctldServer

NewVtctldServerWithTabletManagerClient returns a new grpcvtctldserver.VtctldServer configured with the given topo server and tmclient.TabletManagerClient implementation for testing.

It synchronizes on private locks to prevent multiple goroutines from stepping on each other during VtctldServer initialization, but still run the rest of the test in parallel.

NOTE, THE FIRST: It is only safe to use in parallel with other tests using this method of creating a VtctldServer, or with tests that do not depend on a VtctldServer's tmclient.TabletManagerClient implementation.

NOTE, THE SECOND: It needs to register a unique name to the tmclient factory registry, so we keep a shadow map of factories registered for "protocols" by this function. That way, if we happen to have multiple tests with the same name, we can swap out the return value for the factory and allow both tests to run, rather than the second test failing when it attempts to register a second factory for the same "protocol" name.

NOTE, THE THIRD: we take a "new" func to produce a valid vtctlservicepb.VtctldServer implementation, rather than constructing directly ourselves with grpcvtctldserver.NewVtctldServer. This is to prevent an import cycle between this package and package grpcvtctldserver. Further, because the return type of NewVtctldServer is the struct type (*grpcvtctldserver.VtctldServer) and not the interface type vtctlservicepb.VtctldServer, tests will need to indirect that call through an extra layer rather than passing the function identifier directly, e.g.:

vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, ts, &testutil.TabletManagerClient{
	...
}, func(ts *topo.Server) vtctlservicepb.VtctldServer { return NewVtctldServer(ts) })

func SetupReplicationGraphs

func SetupReplicationGraphs(ctx context.Context, t *testing.T, ts *topo.Server, replicationGraphs ...*topo.ShardReplicationInfo)

SetupReplicationGraphs creates a set of ShardReplication objects in the topo, failing the test if any of the records could not be created.

func UpdateSrvKeyspaces

func UpdateSrvKeyspaces(ctx context.Context, t *testing.T, ts *topo.Server, srvkeyspacesByCellByKeyspace map[string]map[string]*topodatapb.SrvKeyspace)

UpdateSrvKeyspaces updates a set of SrvKeyspace records, grouped by cell and then by keyspace. It fails the test if any records cannot be updated.

func WithTestServer

func WithTestServer(
	t *testing.T,
	server vtctlservicepb.VtctldServer,
	test func(t *testing.T, client vtctldclient.VtctldClient),
)

WithTestServer creates a gRPC server listening locally with the given RPC implementation, then runs the test func with a client created to point at that server.

func WithTestServers

func WithTestServers(
	t *testing.T,
	test func(t *testing.T, clients ...vtctldclient.VtctldClient),
	servers ...vtctlservicepb.VtctldServer,
)

WithTestServers creates N gRPC servers listening locally with the given RPC implementations, and then runs the test func with N clients created, where clients[i] points at servers[i].

Types

type AddTabletOptions

type AddTabletOptions struct {
	// AlsoSetShardPrimary is an option to control additional setup to take when
	// AddTablet receives a tablet of type PRIMARY. When set, AddTablet will also
	// update the shard record to make that tablet the primary, and fail the
	// test if the shard record has a serving primary already.
	AlsoSetShardPrimary bool
	// ForceSetShardPrimary, when combined with AlsoSetShardPrimary, will ignore
	// any existing primary in the shard, making the current tablet the serving
	// primary (given it is type PRIMARY), and log that it has done so.
	ForceSetShardPrimary bool
	// SkipShardCreation, when set, makes AddTablet never attempt to create a
	// shard record in the topo under any circumstances.
	SkipShardCreation bool
}

AddTabletOptions is a container for different behaviors tests need from AddTablet.

type EventValueSorter added in v0.13.0

type EventValueSorter []*logutilpb.Event

EventValueSorter implements sort.Interface for slices of logutil.Event, ordering by .Value lexicographically.

func (EventValueSorter) Len added in v0.13.0

func (events EventValueSorter) Len() int

func (EventValueSorter) Less added in v0.13.0

func (events EventValueSorter) Less(i, j int) bool

func (EventValueSorter) Swap added in v0.13.0

func (events EventValueSorter) Swap(i, j int)

type SrvKeyspace

type SrvKeyspace struct {
	Keyspace    string
	Cell        string
	SrvKeyspace *topodatapb.SrvKeyspace
}

SrvKeyspace groups a topodatapb.SrvKeyspace together with a keyspace and cell.

type TabletManagerClient

type TabletManagerClient struct {
	tmclient.TabletManagerClient
	// TopoServer is used for certain TabletManagerClient rpcs that update topo
	// information, e.g. ChangeType. To force an error result for those rpcs in
	// a test, set tmc.TopoServer = nil.
	TopoServer *topo.Server
	Backups    map[string]struct {
		Events        []*logutilpb.Event
		EventInterval time.Duration
		EventJitter   time.Duration
		ErrorAfter    time.Duration
	}
	// keyed by tablet alias.
	ChangeTabletTypeResult map[string]error
	// keyed by tablet alias.
	DemotePrimaryDelays map[string]time.Duration
	// keyed by tablet alias.
	DemotePrimaryResults map[string]struct {
		Status *replicationdatapb.PrimaryStatus
		Error  error
	}
	// keyed by tablet alias.
	ExecuteFetchAsAppDelays map[string]time.Duration
	// keyed by tablet alias.
	ExecuteFetchAsAppResults map[string]struct {
		Response *querypb.QueryResult
		Error    error
	}
	// keyed by tablet alias.
	ExecuteFetchAsDbaDelays map[string]time.Duration
	// keyed by tablet alias.
	ExecuteFetchAsDbaResults map[string]struct {
		Response *querypb.QueryResult
		Error    error
	}
	// keyed by tablet alias.
	ExecuteHookDelays map[string]time.Duration
	// keyed by tablet alias.
	ExecuteHookResults map[string]struct {
		Response *hk.HookResult
		Error    error
	}
	// keyed by tablet alias.
	ExecuteQueryDelays map[string]time.Duration
	// keyed by tablet alias.
	ExecuteQueryResults map[string]struct {
		Response *querypb.QueryResult
		Error    error
	}
	// FullStatus result
	FullStatusResult *replicationdatapb.FullStatus
	// keyed by tablet alias.
	GetPermissionsDelays map[string]time.Duration
	// keyed by tablet alias.
	GetPermissionsResults map[string]struct {
		Permissions *tabletmanagerdatapb.Permissions
		Error       error
	}
	// keyed by tablet alias.
	GetReplicasResults map[string]struct {
		Replicas []string
		Error    error
	}
	// keyed by tablet alias.
	GetSchemaDelays map[string]time.Duration
	// keyed by tablet alias.
	GetSchemaResults map[string]struct {
		Schema *tabletmanagerdatapb.SchemaDefinition
		Error  error
	}
	// keyed by tablet alias.
	InitPrimaryDelays map[string]time.Duration
	// keyed by tablet alias. injects a sleep to the end of the function
	// regardless of parent context timeout or error result.
	InitPrimaryPostDelays map[string]time.Duration
	// keyed by tablet alias.
	InitPrimaryResults map[string]struct {
		Result string
		Error  error
	}
	// keyed by tablet alias.
	PrimaryPositionDelays map[string]time.Duration
	// keyed by tablet alias.
	PrimaryPositionResults map[string]struct {
		Position string
		Error    error
	}
	// keyed by tablet alias
	PingDelays map[string]time.Duration
	// keyed by tablet alias
	PingResults map[string]error
	// keyed by tablet alias.
	PopulateReparentJournalDelays map[string]time.Duration
	// keyed by tablet alias
	PopulateReparentJournalResults map[string]error
	// keyed by tablet alias.
	PromoteReplicaDelays map[string]time.Duration
	// keyed by tablet alias. injects a sleep to the end of the function
	// regardless of parent context timeout or error result.
	PromoteReplicaPostDelays map[string]time.Duration
	// keyed by tablet alias.
	PromoteReplicaResults map[string]struct {
		Result string
		Error  error
	}
	// keyed by tablet alias.
	RefreshStateResults map[string]error
	// keyed by `<tablet_alias>/<wait_pos>`.
	ReloadSchemaDelays map[string]time.Duration
	// keyed by `<tablet_alias>/<wait_pos>`.
	ReloadSchemaResults      map[string]error
	ReplicationStatusDelays  map[string]time.Duration
	ReplicationStatusResults map[string]struct {
		Position *replicationdatapb.Status
		Error    error
	}
	PrimaryStatusDelays  map[string]time.Duration
	PrimaryStatusResults map[string]struct {
		Status *replicationdatapb.PrimaryStatus
		Error  error
	}
	RestoreFromBackupResults map[string]struct {
		Events        []*logutilpb.Event
		EventInterval time.Duration
		EventJitter   time.Duration
		ErrorAfter    time.Duration
	}
	// keyed by tablet alias
	RunHealthCheckDelays map[string]time.Duration
	// keyed by tablet alias
	RunHealthCheckResults map[string]error
	// keyed by tablet alias.
	SetReplicationSourceDelays map[string]time.Duration
	// keyed by tablet alias.
	SetReplicationSourceResults map[string]error
	// keyed by tablet alias.
	SetReplicationSourceSemiSync map[string]bool
	// keyed by tablet alias
	SetReadOnlyDelays map[string]time.Duration
	// keyed by tablet alias
	SetReadOnlyResults map[string]error
	// keyed by tablet alias.
	SetReadWriteDelays map[string]time.Duration
	// keyed by tablet alias.
	SetReadWriteResults map[string]error
	// keyed by tablet alias
	SleepDelays map[string]time.Duration
	// keyed by tablet alias
	SleepResults map[string]error
	// keyed by tablet alias
	StartReplicationDelays map[string]time.Duration
	// keyed by tablet alias
	StartReplicationResults map[string]error
	// keyed by tablet alias
	StopReplicationDelays map[string]time.Duration
	// keyed by tablet alias
	StopReplicationResults map[string]error
	// keyed by tablet alias.
	StopReplicationAndGetStatusDelays map[string]time.Duration
	// keyed by tablet alias.
	StopReplicationAndGetStatusResults map[string]struct {
		StopStatus *replicationdatapb.StopReplicationStatus
		Error      error
	}
	// keyed by tablet alias.
	UndoDemotePrimaryDelays map[string]time.Duration
	// keyed by tablet alias
	UndoDemotePrimaryResults map[string]error
	// tablet alias => duration
	VReplicationExecDelays map[string]time.Duration
	// tablet alias => query string => result
	VReplicationExecResults map[string]map[string]struct {
		Result *querypb.QueryResult
		Error  error
	}
	// keyed by tablet alias.
	WaitForPositionDelays map[string]time.Duration
	// keyed by tablet alias. injects a sleep to the end of the function
	// regardless of parent context timeout or error result.
	WaitForPositionPostDelays map[string]time.Duration
	// WaitForPosition(tablet *topodatapb.Tablet, position string) error, so we
	// key by tablet alias and then by position.
	WaitForPositionResults map[string]map[string]error
	// tablet alias => duration
	CheckThrottlerDelays map[string]time.Duration
	// keyed by tablet alias
	CheckThrottlerResults map[string]*tabletmanagerdatapb.CheckThrottlerResponse
}

TabletManagerClient implements the tmclient.TabletManagerClient interface with mock delays and response values, for use in unit tests.

func (*TabletManagerClient) Backup added in v0.14.0

Backup is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) ChangeType

func (fake *TabletManagerClient) ChangeType(ctx context.Context, tablet *topodatapb.Tablet, newType topodatapb.TabletType, semiSync bool) error

ChangeType is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) CheckThrottler added in v0.18.0

CheckThrottler is part of the tmclient.TabletManagerCLient interface.

func (*TabletManagerClient) DemotePrimary added in v0.13.0

DemotePrimary is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) ExecuteFetchAsApp added in v0.14.0

ExecuteFetchAsApp is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) ExecuteFetchAsDba added in v0.14.0

ExecuteFetchAsDba is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) ExecuteHook added in v0.13.0

func (fake *TabletManagerClient) ExecuteHook(ctx context.Context, tablet *topodatapb.Tablet, hook *hk.Hook) (*hk.HookResult, error)

ExecuteHook is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) ExecuteQuery added in v0.18.0

ExecuteQuery is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) FullStatus added in v0.15.0

FullStatus is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) GetPermissions added in v0.14.0

GetPermissions is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) GetReplicas added in v0.12.0

func (fake *TabletManagerClient) GetReplicas(ctx context.Context, tablet *topodatapb.Tablet) ([]string, error)

GetReplicas is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) GetSchema

GetSchema is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) InitPrimary added in v0.13.0

func (fake *TabletManagerClient) InitPrimary(ctx context.Context, tablet *topodatapb.Tablet, semiSync bool) (string, error)

InitPrimary is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) Ping added in v0.12.0

func (fake *TabletManagerClient) Ping(ctx context.Context, tablet *topodatapb.Tablet) error

Ping is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) PopulateReparentJournal

func (fake *TabletManagerClient) PopulateReparentJournal(ctx context.Context, tablet *topodatapb.Tablet, timeCreatedNS int64, actionName string, primaryAlias *topodatapb.TabletAlias, pos string) error

PopulateReparentJournal is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) PrimaryPosition added in v0.13.0

func (fake *TabletManagerClient) PrimaryPosition(ctx context.Context, tablet *topodatapb.Tablet) (string, error)

PrimaryPosition is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) PrimaryStatus added in v0.18.0

PrimaryStatus is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) PromoteReplica

func (fake *TabletManagerClient) PromoteReplica(ctx context.Context, tablet *topodatapb.Tablet, semiSync bool) (string, error)

PromoteReplica is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) RefreshState added in v0.11.0

func (fake *TabletManagerClient) RefreshState(ctx context.Context, tablet *topodatapb.Tablet) error

RefreshState is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) ReloadSchema added in v0.13.0

func (fake *TabletManagerClient) ReloadSchema(ctx context.Context, tablet *topodatapb.Tablet, waitPosition string) error

ReloadSchema is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) ReplicationStatus

func (fake *TabletManagerClient) ReplicationStatus(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.Status, error)

ReplicationStatus is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) RestoreFromBackup added in v0.14.0

RestoreFromBackup is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) RunHealthCheck added in v0.12.0

func (fake *TabletManagerClient) RunHealthCheck(ctx context.Context, tablet *topodatapb.Tablet) error

RunHealthCheck is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) SetReadOnly added in v0.12.0

func (fake *TabletManagerClient) SetReadOnly(ctx context.Context, tablet *topodatapb.Tablet) error

SetReadOnly is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) SetReadWrite

func (fake *TabletManagerClient) SetReadWrite(ctx context.Context, tablet *topodatapb.Tablet) error

SetReadWrite is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) SetReplicationSource added in v0.13.0

func (fake *TabletManagerClient) SetReplicationSource(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartReplication bool, semiSync bool) error

SetReplicationSource is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) Sleep added in v0.12.0

func (fake *TabletManagerClient) Sleep(ctx context.Context, tablet *topodatapb.Tablet, duration time.Duration) error

Sleep is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) StartReplication added in v0.12.0

func (fake *TabletManagerClient) StartReplication(ctx context.Context, tablet *topodatapb.Tablet, semiSync bool) error

StartReplication is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) StopReplication added in v0.12.0

func (fake *TabletManagerClient) StopReplication(ctx context.Context, tablet *topodatapb.Tablet) error

StopReplication is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) StopReplicationAndGetStatus

StopReplicationAndGetStatus is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) UndoDemotePrimary added in v0.13.0

func (fake *TabletManagerClient) UndoDemotePrimary(ctx context.Context, tablet *topodatapb.Tablet, semiSync bool) error

UndoDemotePrimary is part of the tmclient.TabletManagerClient interface.

func (*TabletManagerClient) VReplicationExec

func (fake *TabletManagerClient) VReplicationExec(ctx context.Context, tablet *topodatapb.Tablet, query string) (*querypb.QueryResult, error)

VReplicationExec is part of the tmclient.TabletManagerCLient interface.

func (*TabletManagerClient) WaitForPosition

func (fake *TabletManagerClient) WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, position string) error

WaitForPosition is part of the tmclient.TabletManagerClient interface.

Jump to

Keyboard shortcuts

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