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 }