github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/testutils/serverutils/test_cluster_shim.go (about)

     1  // Copyright 2016 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  //
    11  // This file provides generic interfaces that allow tests to set up test
    12  // clusters without importing the testcluster (and indirectly server) package
    13  // (avoiding circular dependencies). To be used, the binary needs to call
    14  // InitTestClusterFactory(testcluster.TestClusterFactory), generally from a
    15  // TestMain() in an "foo_test" package (which can import testcluster and is
    16  // linked together with the other tests in package "foo").
    17  
    18  package serverutils
    19  
    20  import (
    21  	gosql "database/sql"
    22  	"testing"
    23  
    24  	"github.com/cockroachdb/cockroach/pkg/base"
    25  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    26  	"github.com/cockroachdb/cockroach/pkg/util/stop"
    27  )
    28  
    29  // TestClusterInterface defines TestCluster functionality used by tests.
    30  type TestClusterInterface interface {
    31  	NumServers() int
    32  
    33  	// Server returns the TestServerInterface corresponding to a specific node.
    34  	Server(idx int) TestServerInterface
    35  
    36  	// ServerConn returns a gosql.DB connection to a specific node.
    37  	ServerConn(idx int) *gosql.DB
    38  
    39  	// StopServer stops a single server.
    40  	StopServer(idx int)
    41  
    42  	// Stopper retrieves the stopper for this test cluster. Tests should call or
    43  	// defer the Stop() method on this stopper after starting a test cluster.
    44  	Stopper() *stop.Stopper
    45  
    46  	// AddReplicas adds replicas for a range on a set of stores.
    47  	// It's illegal to have multiple replicas of the same range on stores of a single
    48  	// node.
    49  	// The method blocks until a snapshot of the range has been copied to all the
    50  	// new replicas and the new replicas become part of the Raft group.
    51  	AddReplicas(
    52  		startKey roachpb.Key, targets ...roachpb.ReplicationTarget,
    53  	) (roachpb.RangeDescriptor, error)
    54  
    55  	// AddReplicasMulti is the same as AddReplicas but will execute multiple jobs.
    56  	AddReplicasMulti(
    57  		kts ...KeyAndTargets,
    58  	) ([]roachpb.RangeDescriptor, []error)
    59  
    60  	// AddReplicasOrFatal is the same as AddReplicas but will Fatal the test on
    61  	// error.
    62  	AddReplicasOrFatal(
    63  		t testing.TB, startKey roachpb.Key, targets ...roachpb.ReplicationTarget,
    64  	) roachpb.RangeDescriptor
    65  
    66  	// RemoveReplicas removes one or more replicas from a range.
    67  	RemoveReplicas(
    68  		startKey roachpb.Key, targets ...roachpb.ReplicationTarget,
    69  	) (roachpb.RangeDescriptor, error)
    70  
    71  	// RemoveReplicasOrFatal is the same as RemoveReplicas but will Fatal the test on
    72  	// error.
    73  	RemoveReplicasOrFatal(
    74  		t testing.TB, startKey roachpb.Key, targets ...roachpb.ReplicationTarget,
    75  	) roachpb.RangeDescriptor
    76  
    77  	// FindRangeLeaseHolder returns the current lease holder for the given range.
    78  	// In particular, it returns one particular node's (the hint, if specified) view
    79  	// of the current lease.
    80  	// An error is returned if there's no active lease.
    81  	//
    82  	// Note that not all nodes have necessarily applied the latest lease,
    83  	// particularly immediately after a TransferRangeLease() call. So specifying
    84  	// different hints can yield different results. The one server that's guaranteed
    85  	// to have applied the transfer is the previous lease holder.
    86  	FindRangeLeaseHolder(
    87  		rangeDesc roachpb.RangeDescriptor,
    88  		hint *roachpb.ReplicationTarget,
    89  	) (roachpb.ReplicationTarget, error)
    90  
    91  	// TransferRangeLease transfers the lease for a range from whoever has it to
    92  	// a particular store. That store must already have a replica of the range. If
    93  	// that replica already has the (active) lease, this method is a no-op.
    94  	//
    95  	// When this method returns, it's guaranteed that the old lease holder has
    96  	// applied the new lease, but that's about it. It's not guaranteed that the new
    97  	// lease holder has applied it (so it might not know immediately that it is the
    98  	// new lease holder).
    99  	TransferRangeLease(
   100  		rangeDesc roachpb.RangeDescriptor, dest roachpb.ReplicationTarget,
   101  	) error
   102  
   103  	// LookupRange returns the descriptor of the range containing key.
   104  	LookupRange(key roachpb.Key) (roachpb.RangeDescriptor, error)
   105  
   106  	// LookupRangeOrFatal is the same as LookupRange but will Fatal the test on
   107  	// error.
   108  	LookupRangeOrFatal(t testing.TB, key roachpb.Key) roachpb.RangeDescriptor
   109  
   110  	// Target returns a roachpb.ReplicationTarget for the specified server.
   111  	Target(serverIdx int) roachpb.ReplicationTarget
   112  
   113  	// ReplicationMode returns the ReplicationMode that the test cluster was
   114  	// configured with.
   115  	ReplicationMode() base.TestClusterReplicationMode
   116  }
   117  
   118  // TestClusterFactory encompasses the actual implementation of the shim
   119  // service.
   120  type TestClusterFactory interface {
   121  	// New instantiates a test server.
   122  	StartTestCluster(t testing.TB, numNodes int, args base.TestClusterArgs) TestClusterInterface
   123  }
   124  
   125  var clusterFactoryImpl TestClusterFactory
   126  
   127  // InitTestClusterFactory should be called once to provide the implementation
   128  // of the service. It will be called from a xx_test package that can import the
   129  // server package.
   130  func InitTestClusterFactory(impl TestClusterFactory) {
   131  	clusterFactoryImpl = impl
   132  }
   133  
   134  // StartTestCluster starts up a TestCluster made up of numNodes in-memory
   135  // testing servers. The cluster should be stopped using Stopper().Stop().
   136  func StartTestCluster(t testing.TB, numNodes int, args base.TestClusterArgs) TestClusterInterface {
   137  	if clusterFactoryImpl == nil {
   138  		panic("TestClusterFactory not initialized. One needs to be injected " +
   139  			"from the package's TestMain()")
   140  	}
   141  	return clusterFactoryImpl.StartTestCluster(t, numNodes, args)
   142  }
   143  
   144  // KeyAndTargets contains replica startKey and targets.
   145  type KeyAndTargets struct {
   146  	StartKey roachpb.Key
   147  	Targets  []roachpb.ReplicationTarget
   148  }