github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/server/testserver.go (about)

     1  // Copyright 2014 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  package server
    12  
    13  import (
    14  	"context"
    15  	"fmt"
    16  	"net"
    17  	"net/http"
    18  	"net/http/cookiejar"
    19  	"net/url"
    20  	"path/filepath"
    21  	"sync"
    22  	"time"
    23  
    24  	"github.com/cenkalti/backoff"
    25  	circuit "github.com/cockroachdb/circuitbreaker"
    26  	"github.com/cockroachdb/cockroach/pkg/base"
    27  	"github.com/cockroachdb/cockroach/pkg/config"
    28  	"github.com/cockroachdb/cockroach/pkg/config/zonepb"
    29  	"github.com/cockroachdb/cockroach/pkg/gossip"
    30  	"github.com/cockroachdb/cockroach/pkg/gossip/resolver"
    31  	"github.com/cockroachdb/cockroach/pkg/jobs"
    32  	"github.com/cockroachdb/cockroach/pkg/keys"
    33  	"github.com/cockroachdb/cockroach/pkg/kv"
    34  	"github.com/cockroachdb/cockroach/pkg/kv/kvclient/kvcoord"
    35  	"github.com/cockroachdb/cockroach/pkg/kv/kvserver"
    36  	"github.com/cockroachdb/cockroach/pkg/kv/kvserver/protectedts"
    37  	"github.com/cockroachdb/cockroach/pkg/kv/kvserver/protectedts/ptpb"
    38  	"github.com/cockroachdb/cockroach/pkg/kv/kvserver/protectedts/ptprovider"
    39  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    40  	"github.com/cockroachdb/cockroach/pkg/rpc"
    41  	"github.com/cockroachdb/cockroach/pkg/rpc/nodedialer"
    42  	"github.com/cockroachdb/cockroach/pkg/security"
    43  	"github.com/cockroachdb/cockroach/pkg/server/serverpb"
    44  	"github.com/cockroachdb/cockroach/pkg/server/status"
    45  	"github.com/cockroachdb/cockroach/pkg/settings/cluster"
    46  	"github.com/cockroachdb/cockroach/pkg/sql"
    47  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire"
    48  	"github.com/cockroachdb/cockroach/pkg/sql/physicalplan"
    49  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    50  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    51  	"github.com/cockroachdb/cockroach/pkg/sqlmigrations"
    52  	"github.com/cockroachdb/cockroach/pkg/storage"
    53  	"github.com/cockroachdb/cockroach/pkg/storage/cloud"
    54  	"github.com/cockroachdb/cockroach/pkg/storage/enginepb"
    55  	"github.com/cockroachdb/cockroach/pkg/ts"
    56  	"github.com/cockroachdb/cockroach/pkg/util"
    57  	"github.com/cockroachdb/cockroach/pkg/util/hlc"
    58  	"github.com/cockroachdb/cockroach/pkg/util/metric"
    59  	"github.com/cockroachdb/cockroach/pkg/util/netutil"
    60  	"github.com/cockroachdb/cockroach/pkg/util/stop"
    61  	"github.com/cockroachdb/errors"
    62  	"github.com/gogo/protobuf/proto"
    63  )
    64  
    65  const (
    66  	// TestUser is a fixed user used in unittests.
    67  	// It has valid embedded client certs.
    68  	TestUser = "testuser"
    69  )
    70  
    71  // makeTestConfig returns a config for testing. It overrides the
    72  // Certs with the test certs directory.
    73  // We need to override the certs loader.
    74  func makeTestConfig(st *cluster.Settings) Config {
    75  	return Config{
    76  		BaseConfig: makeTestBaseConfig(st),
    77  		KVConfig:   makeTestKVConfig(),
    78  		SQLConfig:  makeTestSQLConfig(st, roachpb.SystemTenantID),
    79  	}
    80  }
    81  
    82  func makeTestBaseConfig(st *cluster.Settings) BaseConfig {
    83  	baseCfg := MakeBaseConfig(st)
    84  	// Test servers start in secure mode by default.
    85  	baseCfg.Insecure = false
    86  	// Configure test storage engine.
    87  	baseCfg.StorageEngine = storage.DefaultStorageEngine
    88  	// Resolve the storage engine to a specific type if it's the default value.
    89  	if baseCfg.StorageEngine == enginepb.EngineTypeDefault {
    90  		baseCfg.StorageEngine = enginepb.EngineTypePebble
    91  	}
    92  	// Load test certs. In addition, the tests requiring certs
    93  	// need to call security.SetAssetLoader(securitytest.EmbeddedAssets)
    94  	// in their init to mock out the file system calls for calls to AssetFS,
    95  	// which has the test certs compiled in. Typically this is done
    96  	// once per package, in main_test.go.
    97  	baseCfg.SSLCertsDir = security.EmbeddedCertsDir
    98  	// Addr defaults to localhost with port set at time of call to
    99  	// Start() to an available port. May be overridden later (as in
   100  	// makeTestConfigFromParams). Call TestServer.ServingRPCAddr() and
   101  	// .ServingSQLAddr() for the full address (including bound port).
   102  	baseCfg.Addr = util.TestAddr.String()
   103  	baseCfg.SQLAddr = util.TestAddr.String()
   104  	baseCfg.AdvertiseAddr = util.TestAddr.String()
   105  	baseCfg.SQLAdvertiseAddr = util.TestAddr.String()
   106  	baseCfg.SplitListenSQL = true
   107  	baseCfg.HTTPAddr = util.TestAddr.String()
   108  	// Set standard user for intra-cluster traffic.
   109  	baseCfg.User = security.NodeUser
   110  	return baseCfg
   111  }
   112  
   113  func makeTestKVConfig() KVConfig {
   114  	kvCfg := MakeKVConfig(base.DefaultTestStoreSpec)
   115  	// Enable web session authentication.
   116  	kvCfg.EnableWebSessionAuthentication = true
   117  	return kvCfg
   118  }
   119  
   120  func makeTestSQLConfig(st *cluster.Settings, tenID roachpb.TenantID) SQLConfig {
   121  	sqlCfg := MakeSQLConfig(tenID, base.DefaultTestTempStorageConfig(st))
   122  	// Configure the default in-memory temp storage for all tests unless
   123  	// otherwise configured.
   124  	sqlCfg.TempStorageConfig = base.DefaultTestTempStorageConfig(st)
   125  	return sqlCfg
   126  }
   127  
   128  // makeTestConfigFromParams creates a Config from a TestServerParams.
   129  func makeTestConfigFromParams(params base.TestServerArgs) Config {
   130  	st := params.Settings
   131  	if params.Settings == nil {
   132  		st = cluster.MakeClusterSettings()
   133  	}
   134  	st.ExternalIODir = params.ExternalIODir
   135  	cfg := makeTestConfig(st)
   136  	cfg.TestingKnobs = params.Knobs
   137  	cfg.RaftConfig = params.RaftConfig
   138  	cfg.RaftConfig.SetDefaults()
   139  	if params.LeaseManagerConfig != nil {
   140  		cfg.LeaseManagerConfig = params.LeaseManagerConfig
   141  	} else {
   142  		cfg.LeaseManagerConfig = base.NewLeaseManagerConfig()
   143  	}
   144  	if params.JoinAddr != "" {
   145  		cfg.JoinList = []string{params.JoinAddr}
   146  	}
   147  	cfg.ClusterName = params.ClusterName
   148  	cfg.Insecure = params.Insecure
   149  	cfg.SocketFile = params.SocketFile
   150  	cfg.RetryOptions = params.RetryOptions
   151  	cfg.Locality = params.Locality
   152  	if knobs := params.Knobs.Store; knobs != nil {
   153  		if mo := knobs.(*kvserver.StoreTestingKnobs).MaxOffset; mo != 0 {
   154  			cfg.MaxOffset = MaxOffsetType(mo)
   155  		}
   156  	}
   157  	if params.Knobs.Server != nil {
   158  		if zoneConfig := params.Knobs.Server.(*TestingKnobs).DefaultZoneConfigOverride; zoneConfig != nil {
   159  			cfg.DefaultZoneConfig = *zoneConfig
   160  		}
   161  		if systemZoneConfig := params.Knobs.Server.(*TestingKnobs).DefaultSystemZoneConfigOverride; systemZoneConfig != nil {
   162  			cfg.DefaultSystemZoneConfig = *systemZoneConfig
   163  		}
   164  	}
   165  	if params.ScanInterval != 0 {
   166  		cfg.ScanInterval = params.ScanInterval
   167  	}
   168  	if params.ScanMinIdleTime != 0 {
   169  		cfg.ScanMinIdleTime = params.ScanMinIdleTime
   170  	}
   171  	if params.ScanMaxIdleTime != 0 {
   172  		cfg.ScanMaxIdleTime = params.ScanMaxIdleTime
   173  	}
   174  	if params.SSLCertsDir != "" {
   175  		cfg.SSLCertsDir = params.SSLCertsDir
   176  	}
   177  	if params.TimeSeriesQueryWorkerMax != 0 {
   178  		cfg.TimeSeriesServerConfig.QueryWorkerMax = params.TimeSeriesQueryWorkerMax
   179  	}
   180  	if params.TimeSeriesQueryMemoryBudget != 0 {
   181  		cfg.TimeSeriesServerConfig.QueryMemoryMax = params.TimeSeriesQueryMemoryBudget
   182  	}
   183  	if params.DisableEventLog {
   184  		cfg.EventLogEnabled = false
   185  	}
   186  	if params.SQLMemoryPoolSize != 0 {
   187  		cfg.MemoryPoolSize = params.SQLMemoryPoolSize
   188  	}
   189  	if params.CacheSize != 0 {
   190  		cfg.CacheSize = params.CacheSize
   191  	}
   192  
   193  	if params.JoinAddr != "" {
   194  		cfg.JoinList = []string{params.JoinAddr}
   195  	}
   196  	if cfg.Insecure {
   197  		// Whenever we can (i.e. in insecure mode), use IsolatedTestAddr
   198  		// to prevent issues that can occur when running a test under
   199  		// stress.
   200  		cfg.Addr = util.IsolatedTestAddr.String()
   201  		cfg.AdvertiseAddr = util.IsolatedTestAddr.String()
   202  		cfg.SQLAddr = util.IsolatedTestAddr.String()
   203  		cfg.SQLAdvertiseAddr = util.IsolatedTestAddr.String()
   204  		cfg.HTTPAddr = util.IsolatedTestAddr.String()
   205  	} else {
   206  		cfg.Addr = util.TestAddr.String()
   207  		cfg.AdvertiseAddr = util.TestAddr.String()
   208  		cfg.SQLAddr = util.TestAddr.String()
   209  		cfg.SQLAdvertiseAddr = util.TestAddr.String()
   210  		cfg.HTTPAddr = util.TestAddr.String()
   211  	}
   212  	if params.Addr != "" {
   213  		cfg.Addr = params.Addr
   214  		cfg.AdvertiseAddr = params.Addr
   215  	}
   216  	if params.SQLAddr != "" {
   217  		cfg.SQLAddr = params.SQLAddr
   218  		cfg.SQLAdvertiseAddr = params.SQLAddr
   219  	}
   220  	if params.HTTPAddr != "" {
   221  		cfg.HTTPAddr = params.HTTPAddr
   222  	}
   223  	cfg.DisableTLSForHTTP = params.DisableTLSForHTTP
   224  	if params.DisableWebSessionAuthentication {
   225  		cfg.EnableWebSessionAuthentication = false
   226  	}
   227  
   228  	// Ensure we have the correct number of engines. Add in-memory ones where
   229  	// needed. There must be at least one store/engine.
   230  	if len(params.StoreSpecs) == 0 {
   231  		params.StoreSpecs = []base.StoreSpec{base.DefaultTestStoreSpec}
   232  	}
   233  	// Validate the store specs.
   234  	for _, storeSpec := range params.StoreSpecs {
   235  		if storeSpec.InMemory {
   236  			if storeSpec.Size.Percent > 0 {
   237  				panic(fmt.Sprintf("test server does not yet support in memory stores based on percentage of total memory: %s", storeSpec))
   238  			}
   239  		} else {
   240  			// The default store spec is in-memory, so if this one is on-disk then
   241  			// one specific test must have requested it. A failure is returned if
   242  			// the Path field is empty, which means the test is then forced to pick
   243  			// the dir (and the test is then responsible for cleaning it up, not
   244  			// TestServer).
   245  
   246  			// HeapProfileDirName and GoroutineDumpDirName are normally set by the
   247  			// cli, once, to the path of the first store.
   248  			if cfg.HeapProfileDirName == "" {
   249  				cfg.HeapProfileDirName = filepath.Join(storeSpec.Path, "logs", base.HeapProfileDir)
   250  			}
   251  			if cfg.GoroutineDumpDirName == "" {
   252  				cfg.GoroutineDumpDirName = filepath.Join(storeSpec.Path, "logs", base.GoroutineDumpDir)
   253  			}
   254  		}
   255  	}
   256  	cfg.Stores = base.StoreSpecList{Specs: params.StoreSpecs}
   257  	if params.TempStorageConfig.InMemory || params.TempStorageConfig.Path != "" {
   258  		cfg.TempStorageConfig = params.TempStorageConfig
   259  	}
   260  
   261  	if cfg.TestingKnobs.Store == nil {
   262  		cfg.TestingKnobs.Store = &kvserver.StoreTestingKnobs{}
   263  	}
   264  	cfg.TestingKnobs.Store.(*kvserver.StoreTestingKnobs).SkipMinSizeCheck = true
   265  	return cfg
   266  }
   267  
   268  // A TestServer encapsulates an in-memory instantiation of a cockroach node with
   269  // a single store. It provides tests with access to Server internals.
   270  // Where possible, it should be used through the
   271  // testingshim.TestServerInterface.
   272  //
   273  // Example usage of a TestServer:
   274  //
   275  //   s, db, kvDB := serverutils.StartServer(t, base.TestServerArgs{})
   276  //   defer s.Stopper().Stop()
   277  //   // If really needed, in tests that can depend on server, downcast to
   278  //   // server.TestServer:
   279  //   ts := s.(*server.TestServer)
   280  //
   281  type TestServer struct {
   282  	Cfg *Config
   283  	// server is the embedded Cockroach server struct.
   284  	*Server
   285  	// authClient is an http.Client that has been authenticated to access the
   286  	// Admin UI.
   287  	authClient [2]struct {
   288  		httpClient http.Client
   289  		cookie     *serverpb.SessionCookie
   290  		once       sync.Once
   291  		err        error
   292  	}
   293  }
   294  
   295  // Node returns the Node as an interface{}.
   296  func (ts *TestServer) Node() interface{} {
   297  	return ts.node
   298  }
   299  
   300  // Stopper returns the embedded server's Stopper.
   301  func (ts *TestServer) Stopper() *stop.Stopper {
   302  	return ts.stopper
   303  }
   304  
   305  // GossipI is part of TestServerInterface.
   306  func (ts *TestServer) GossipI() interface{} {
   307  	return ts.Gossip()
   308  }
   309  
   310  // Gossip is like GossipI but returns the real type instead of interface{}.
   311  func (ts *TestServer) Gossip() *gossip.Gossip {
   312  	if ts != nil {
   313  		return ts.gossip
   314  	}
   315  	return nil
   316  }
   317  
   318  // Clock returns the clock used by the TestServer.
   319  func (ts *TestServer) Clock() *hlc.Clock {
   320  	if ts != nil {
   321  		return ts.clock
   322  	}
   323  	return nil
   324  }
   325  
   326  // JobRegistry returns the *jobs.Registry as an interface{}.
   327  func (ts *TestServer) JobRegistry() interface{} {
   328  	if ts != nil {
   329  		return ts.sqlServer.jobRegistry
   330  	}
   331  	return nil
   332  }
   333  
   334  // MigrationManager returns the *sqlmigrations.Manager as an interface{}.
   335  func (ts *TestServer) MigrationManager() interface{} {
   336  	if ts != nil {
   337  		return ts.sqlServer.migMgr
   338  	}
   339  	return nil
   340  }
   341  
   342  // RPCContext returns the rpc context used by the TestServer.
   343  func (ts *TestServer) RPCContext() *rpc.Context {
   344  	if ts != nil {
   345  		return ts.rpcContext
   346  	}
   347  	return nil
   348  }
   349  
   350  // TsDB returns the ts.DB instance used by the TestServer.
   351  func (ts *TestServer) TsDB() *ts.DB {
   352  	if ts != nil {
   353  		return ts.tsDB
   354  	}
   355  	return nil
   356  }
   357  
   358  // DB returns the client.DB instance used by the TestServer.
   359  func (ts *TestServer) DB() *kv.DB {
   360  	if ts != nil {
   361  		return ts.db
   362  	}
   363  	return nil
   364  }
   365  
   366  // PGServer returns the pgwire.Server used by the TestServer.
   367  func (ts *TestServer) PGServer() *pgwire.Server {
   368  	if ts != nil {
   369  		return ts.sqlServer.pgServer
   370  	}
   371  	return nil
   372  }
   373  
   374  // RaftTransport returns the RaftTransport used by the TestServer.
   375  func (ts *TestServer) RaftTransport() *kvserver.RaftTransport {
   376  	if ts != nil {
   377  		return ts.raftTransport
   378  	}
   379  	return nil
   380  }
   381  
   382  // Start starts the TestServer by bootstrapping an in-memory store
   383  // (defaults to maximum of 100M). The server is started, launching the
   384  // node RPC server and all HTTP endpoints. Use the value of
   385  // TestServer.ServingRPCAddr() after Start() for client connections.
   386  // Use TestServer.Stopper().Stop() to shutdown the server after the test
   387  // completes.
   388  func (ts *TestServer) Start(params base.TestServerArgs) error {
   389  	if ts.Cfg == nil {
   390  		panic("Cfg not set")
   391  	}
   392  
   393  	if params.Stopper == nil {
   394  		params.Stopper = stop.NewStopper()
   395  	}
   396  
   397  	if !params.PartOfCluster {
   398  		ts.Cfg.DefaultZoneConfig.NumReplicas = proto.Int32(1)
   399  	}
   400  
   401  	ctx := context.Background()
   402  
   403  	// Needs to be called before NewServer to ensure resolvers are initialized.
   404  	if err := ts.Cfg.InitNode(ctx); err != nil {
   405  		return err
   406  	}
   407  
   408  	var err error
   409  	ts.Server, err = NewServer(*ts.Cfg, params.Stopper)
   410  	if err != nil {
   411  		return err
   412  	}
   413  
   414  	// Create a breaker which never trips and never backs off to avoid
   415  	// introducing timing-based flakes.
   416  	ts.rpcContext.BreakerFactory = func() *circuit.Breaker {
   417  		return circuit.NewBreakerWithOptions(&circuit.Options{
   418  			BackOff: &backoff.ZeroBackOff{},
   419  		})
   420  	}
   421  
   422  	// Our context must be shared with our server.
   423  	ts.Cfg = &ts.Server.cfg
   424  
   425  	return ts.Server.Start(ctx)
   426  }
   427  
   428  type dummyProtectedTSProvider struct {
   429  	protectedts.Provider
   430  }
   431  
   432  func (d dummyProtectedTSProvider) Protect(context.Context, *kv.Txn, *ptpb.Record) error {
   433  	return errors.New("fake protectedts.Provider")
   434  }
   435  
   436  // TODO(asubiotto): Jobs don't play well with a weird node ID in a multitenant
   437  //  environment, so a node ID of 1 is used here to get tests to pass. Fixing
   438  //  this is tracked in https://github.com/cockroachdb/cockroach/issues/47892.
   439  const fakeNodeID = roachpb.NodeID(1)
   440  
   441  func makeSQLServerArgs(
   442  	stopper *stop.Stopper, kvClusterName string, baseCfg BaseConfig, sqlCfg SQLConfig,
   443  ) sqlServerArgs {
   444  	st := baseCfg.Settings
   445  	baseCfg.AmbientCtx.AddLogTag("sql", nil)
   446  	// TODO(tbg): this is needed so that the RPC heartbeats between the testcluster
   447  	// and this tenant work.
   448  	//
   449  	// TODO(tbg): address this when we introduce the real tenant RPCs in:
   450  	// https://github.com/cockroachdb/cockroach/issues/47898
   451  	baseCfg.ClusterName = kvClusterName
   452  
   453  	clock := hlc.NewClock(hlc.UnixNano, time.Duration(baseCfg.MaxOffset))
   454  
   455  	var rpcTestingKnobs rpc.ContextTestingKnobs
   456  	if p, ok := baseCfg.TestingKnobs.Server.(*TestingKnobs); ok {
   457  		rpcTestingKnobs = p.ContextTestingKnobs
   458  	}
   459  	rpcContext := rpc.NewContextWithTestingKnobs(
   460  		baseCfg.AmbientCtx,
   461  		baseCfg.Config,
   462  		clock,
   463  		stopper,
   464  		st,
   465  		rpcTestingKnobs,
   466  	)
   467  
   468  	// TODO(tbg): expose this registry via prometheus. See:
   469  	// https://github.com/cockroachdb/cockroach/issues/47905
   470  	registry := metric.NewRegistry()
   471  
   472  	var dsKnobs kvcoord.ClientTestingKnobs
   473  	if dsKnobsP, ok := baseCfg.TestingKnobs.DistSQL.(*kvcoord.ClientTestingKnobs); ok {
   474  		dsKnobs = *dsKnobsP
   475  	}
   476  	rpcRetryOptions := base.DefaultRetryOptions()
   477  
   478  	// TODO(nvb): this use of Gossip needs to go. Tracked in:
   479  	// https://github.com/cockroachdb/cockroach/issues/47909
   480  	var g *gossip.Gossip
   481  	{
   482  		var nodeID base.NodeIDContainer
   483  		nodeID.Set(context.Background(), fakeNodeID)
   484  		var clusterID base.ClusterIDContainer
   485  		dummyGossipGRPC := rpc.NewServer(rpcContext) // never Serve()s anything
   486  		g = gossip.New(
   487  			baseCfg.AmbientCtx,
   488  			&clusterID,
   489  			&nodeID,
   490  			rpcContext,
   491  			dummyGossipGRPC,
   492  			stopper,
   493  			registry,
   494  			baseCfg.Locality,
   495  			&baseCfg.DefaultZoneConfig,
   496  		)
   497  	}
   498  
   499  	nodeDialer := nodedialer.New(
   500  		rpcContext,
   501  		gossip.AddressResolver(g), // TODO(nvb): break gossip dep
   502  	)
   503  	dsCfg := kvcoord.DistSenderConfig{
   504  		AmbientCtx:        baseCfg.AmbientCtx,
   505  		Settings:          st,
   506  		Clock:             clock,
   507  		RPCRetryOptions:   &rpcRetryOptions,
   508  		RPCContext:        rpcContext,
   509  		RangeDescriptorDB: nil, // use DistSender itself
   510  		NodeDialer:        nodeDialer,
   511  		TestingKnobs:      dsKnobs,
   512  	}
   513  	ds := kvcoord.NewDistSender(dsCfg, g)
   514  
   515  	var clientKnobs kvcoord.ClientTestingKnobs
   516  	if p, ok := baseCfg.TestingKnobs.KVClient.(*kvcoord.ClientTestingKnobs); ok {
   517  		clientKnobs = *p
   518  	}
   519  
   520  	txnMetrics := kvcoord.MakeTxnMetrics(baseCfg.HistogramWindowInterval())
   521  	registry.AddMetricStruct(txnMetrics)
   522  	tcsFactory := kvcoord.NewTxnCoordSenderFactory(
   523  		kvcoord.TxnCoordSenderFactoryConfig{
   524  			AmbientCtx:        baseCfg.AmbientCtx,
   525  			Settings:          st,
   526  			Clock:             clock,
   527  			Stopper:           stopper,
   528  			HeartbeatInterval: base.DefaultTxnHeartbeatInterval,
   529  			Linearizable:      false,
   530  			Metrics:           txnMetrics,
   531  			TestingKnobs:      clientKnobs,
   532  		},
   533  		ds,
   534  	)
   535  	db := kv.NewDB(
   536  		baseCfg.AmbientCtx,
   537  		tcsFactory,
   538  		clock,
   539  	)
   540  
   541  	circularInternalExecutor := &sql.InternalExecutor{}
   542  	// Protected timestamps won't be available (at first) in multi-tenant
   543  	// clusters.
   544  	var protectedTSProvider protectedts.Provider
   545  	{
   546  		pp, err := ptprovider.New(ptprovider.Config{
   547  			DB:               db,
   548  			InternalExecutor: circularInternalExecutor,
   549  			Settings:         st,
   550  		})
   551  		if err != nil {
   552  			panic(err)
   553  		}
   554  		protectedTSProvider = dummyProtectedTSProvider{pp}
   555  	}
   556  
   557  	dummyRecorder := &status.MetricsRecorder{}
   558  
   559  	var c base.NodeIDContainer
   560  	c.Set(context.Background(), fakeNodeID)
   561  	const sqlInstanceID = base.SQLInstanceID(10001)
   562  	idContainer := base.NewSQLIDContainer(sqlInstanceID, &c, false /* exposed */)
   563  
   564  	// We don't need this for anything except some services that want a gRPC
   565  	// server to register against (but they'll never get RPCs at the time of
   566  	// writing): the blob service and DistSQL.
   567  	dummyRPCServer := rpc.NewServer(rpcContext)
   568  	noStatusServer := serverpb.MakeOptionalStatusServer(nil)
   569  	return sqlServerArgs{
   570  		sqlServerOptionalArgs: sqlServerOptionalArgs{
   571  			rpcContext:   rpcContext,
   572  			distSender:   ds,
   573  			statusServer: noStatusServer,
   574  			nodeLiveness: sqlbase.MakeOptionalNodeLiveness(nil),
   575  			gossip:       gossip.MakeUnexposedGossip(g),
   576  			nodeDialer:   nodeDialer,
   577  			grpcServer:   dummyRPCServer,
   578  			recorder:     dummyRecorder,
   579  			isMeta1Leaseholder: func(timestamp hlc.Timestamp) (bool, error) {
   580  				return false, errors.New("isMeta1Leaseholder is not available to secondary tenants")
   581  			},
   582  			nodeIDContainer: idContainer,
   583  			externalStorage: func(ctx context.Context, dest roachpb.ExternalStorage) (cloud.ExternalStorage, error) {
   584  				return nil, errors.New("external storage is not available to secondary tenants")
   585  			},
   586  			externalStorageFromURI: func(ctx context.Context, uri string) (cloud.ExternalStorage, error) {
   587  				return nil, errors.New("external uri storage is not available to secondary tenants")
   588  			},
   589  		},
   590  		SQLConfig:                &sqlCfg,
   591  		BaseConfig:               &baseCfg,
   592  		stopper:                  stopper,
   593  		clock:                    clock,
   594  		runtime:                  status.NewRuntimeStatSampler(context.Background(), clock),
   595  		db:                       db,
   596  		registry:                 registry,
   597  		sessionRegistry:          sql.NewSessionRegistry(),
   598  		circularInternalExecutor: circularInternalExecutor,
   599  		circularJobRegistry:      &jobs.Registry{},
   600  		protectedtsProvider:      protectedTSProvider,
   601  	}
   602  }
   603  
   604  // StartTenant starts a SQL tenant communicating with this TestServer.
   605  func (ts *TestServer) StartTenant(params base.TestTenantArgs) (pgAddr string, _ error) {
   606  	ctx := context.Background()
   607  
   608  	if _, err := ts.InternalExecutor().(*sql.InternalExecutor).Exec(
   609  		ctx, "testserver-create-tenant", nil /* txn */, fmt.Sprintf("SELECT crdb_internal.create_tenant(%d)", params.TenantID.ToUint64()),
   610  	); err != nil {
   611  		return "", err
   612  	}
   613  
   614  	st := cluster.MakeTestingClusterSettings()
   615  	sqlCfg := makeTestSQLConfig(st, params.TenantID)
   616  	baseCfg := makeTestBaseConfig(st)
   617  	if params.AllowSettingClusterSettings {
   618  		baseCfg.TestingKnobs.TenantTestingKnobs = &sql.TenantTestingKnobs{
   619  			ClusterSettingsUpdater: st.MakeUpdater(),
   620  		}
   621  	}
   622  	return startTenant(
   623  		ctx,
   624  		ts.Stopper(),
   625  		ts.Cfg.ClusterName,
   626  		ts.RPCAddr(),
   627  		baseCfg,
   628  		sqlCfg,
   629  	)
   630  }
   631  
   632  func startTenant(
   633  	ctx context.Context,
   634  	stopper *stop.Stopper,
   635  	kvClusterName string, // NB: gone after https://github.com/cockroachdb/cockroach/issues/42519
   636  	tsRPCAddr string,
   637  	baseCfg BaseConfig,
   638  	sqlCfg SQLConfig,
   639  ) (pgAddr string, _ error) {
   640  	args := makeSQLServerArgs(stopper, kvClusterName, baseCfg, sqlCfg)
   641  	s, err := newSQLServer(ctx, args)
   642  	if err != nil {
   643  		return "", err
   644  	}
   645  
   646  	// NB: this should no longer be necessary after #47902. Right now it keeps
   647  	// the tenant from crashing.
   648  	//
   649  	// NB: this NodeID is actually used by the DistSQL planner.
   650  	s.execCfg.DistSQLPlanner.SetNodeDesc(roachpb.NodeDescriptor{NodeID: fakeNodeID})
   651  
   652  	connManager := netutil.MakeServer(
   653  		args.stopper,
   654  		// The SQL server only uses connManager.ServeWith. The both below
   655  		// are unused.
   656  		nil, // tlsConfig
   657  		nil, // handler
   658  	)
   659  
   660  	pgL, err := net.Listen("tcp", args.Config.SQLAddr)
   661  	if err != nil {
   662  		return "", err
   663  	}
   664  	args.stopper.RunWorker(ctx, func(ctx context.Context) {
   665  		<-args.stopper.ShouldQuiesce()
   666  		// NB: we can't do this as a Closer because (*Server).ServeWith is
   667  		// running in a worker and usually sits on accept(pgL) which unblocks
   668  		// only when pgL closes. In other words, pgL needs to close when
   669  		// quiescing starts to allow that worker to shut down.
   670  		_ = pgL.Close()
   671  	})
   672  
   673  	const (
   674  		socketFile = "" // no unix socket
   675  	)
   676  	orphanedLeasesTimeThresholdNanos := args.clock.Now().WallTime
   677  
   678  	{
   679  		rsvlr, err := resolver.NewResolver(tsRPCAddr)
   680  		if err != nil {
   681  			return "", err
   682  		}
   683  		// NB: gossip server is not bound to any address, so the advertise addr does
   684  		// not matter.
   685  		args.gossip.Start(pgL.Addr(), []resolver.Resolver{rsvlr})
   686  	}
   687  
   688  	if err := s.start(ctx,
   689  		args.stopper,
   690  		args.TestingKnobs,
   691  		connManager,
   692  		pgL,
   693  		socketFile,
   694  		orphanedLeasesTimeThresholdNanos,
   695  	); err != nil {
   696  		return "", err
   697  	}
   698  	return pgL.Addr().String(), nil
   699  }
   700  
   701  // ExpectedInitialRangeCount returns the expected number of ranges that should
   702  // be on the server after initial (asynchronous) splits have been completed,
   703  // assuming no additional information is added outside of the normal bootstrap
   704  // process.
   705  func (ts *TestServer) ExpectedInitialRangeCount() (int, error) {
   706  	return ExpectedInitialRangeCount(ts.DB(), &ts.cfg.DefaultZoneConfig, &ts.cfg.DefaultSystemZoneConfig)
   707  }
   708  
   709  // ExpectedInitialRangeCount returns the expected number of ranges that should
   710  // be on the server after bootstrap.
   711  func ExpectedInitialRangeCount(
   712  	db *kv.DB, defaultZoneConfig *zonepb.ZoneConfig, defaultSystemZoneConfig *zonepb.ZoneConfig,
   713  ) (int, error) {
   714  	descriptorIDs, err := sqlmigrations.ExpectedDescriptorIDs(
   715  		context.Background(), db, keys.SystemSQLCodec, defaultZoneConfig, defaultSystemZoneConfig,
   716  	)
   717  	if err != nil {
   718  		return 0, err
   719  	}
   720  
   721  	// System table splits occur at every possible table boundary between the end
   722  	// of the system config ID space (keys.MaxSystemConfigDescID) and the system
   723  	// table with the maximum ID (maxSystemDescriptorID), even when an ID within
   724  	// the span does not have an associated descriptor.
   725  	maxSystemDescriptorID := descriptorIDs[0]
   726  	for _, descID := range descriptorIDs {
   727  		if descID > maxSystemDescriptorID && descID <= keys.MaxReservedDescID {
   728  			maxSystemDescriptorID = descID
   729  		}
   730  	}
   731  	systemTableSplits := int(maxSystemDescriptorID - keys.MaxSystemConfigDescID)
   732  
   733  	// `n` splits create `n+1` ranges.
   734  	return len(config.StaticSplits()) + systemTableSplits + 1, nil
   735  }
   736  
   737  // Stores returns the collection of stores from this TestServer's node.
   738  func (ts *TestServer) Stores() *kvserver.Stores {
   739  	return ts.node.stores
   740  }
   741  
   742  // GetStores is part of TestServerInterface.
   743  func (ts *TestServer) GetStores() interface{} {
   744  	return ts.node.stores
   745  }
   746  
   747  // ClusterSettings returns the ClusterSettings.
   748  func (ts *TestServer) ClusterSettings() *cluster.Settings {
   749  	return ts.Cfg.Settings
   750  }
   751  
   752  // Engines returns the TestServer's engines.
   753  func (ts *TestServer) Engines() []storage.Engine {
   754  	return ts.engines
   755  }
   756  
   757  // ServingRPCAddr returns the server's RPC address. Should be used by clients.
   758  func (ts *TestServer) ServingRPCAddr() string {
   759  	return ts.cfg.AdvertiseAddr
   760  }
   761  
   762  // ServingSQLAddr returns the server's SQL address. Should be used by clients.
   763  func (ts *TestServer) ServingSQLAddr() string {
   764  	return ts.cfg.SQLAdvertiseAddr
   765  }
   766  
   767  // HTTPAddr returns the server's HTTP address. Should be used by clients.
   768  func (ts *TestServer) HTTPAddr() string {
   769  	return ts.cfg.HTTPAddr
   770  }
   771  
   772  // RPCAddr returns the server's listening RPC address.
   773  // Note: use ServingRPCAddr() instead unless there is a specific reason not to.
   774  func (ts *TestServer) RPCAddr() string {
   775  	return ts.cfg.Addr
   776  }
   777  
   778  // DrainClients exports the drainClients() method for use by tests.
   779  func (ts *TestServer) DrainClients(ctx context.Context) error {
   780  	return ts.drainClients(ctx, nil /* reporter */)
   781  }
   782  
   783  // SQLAddr returns the server's listening SQL address.
   784  // Note: use ServingSQLAddr() instead unless there is a specific reason not to.
   785  func (ts *TestServer) SQLAddr() string {
   786  	return ts.cfg.SQLAddr
   787  }
   788  
   789  // WriteSummaries implements TestServerInterface.
   790  func (ts *TestServer) WriteSummaries() error {
   791  	return ts.node.writeNodeStatus(context.TODO(), time.Hour)
   792  }
   793  
   794  // AdminURL implements TestServerInterface.
   795  func (ts *TestServer) AdminURL() string {
   796  	return ts.Cfg.AdminURL().String()
   797  }
   798  
   799  // GetHTTPClient implements TestServerInterface.
   800  func (ts *TestServer) GetHTTPClient() (http.Client, error) {
   801  	return ts.Cfg.GetHTTPClient()
   802  }
   803  
   804  const authenticatedUserName = "authentic_user"
   805  const authenticatedUserNameNoAdmin = "authentic_user_noadmin"
   806  
   807  // GetAdminAuthenticatedHTTPClient implements the TestServerInterface.
   808  func (ts *TestServer) GetAdminAuthenticatedHTTPClient() (http.Client, error) {
   809  	httpClient, _, err := ts.getAuthenticatedHTTPClientAndCookie(authenticatedUserName, true)
   810  	return httpClient, err
   811  }
   812  
   813  // GetAuthenticatedHTTPClient implements the TestServerInterface.
   814  func (ts *TestServer) GetAuthenticatedHTTPClient(isAdmin bool) (http.Client, error) {
   815  	authUser := authenticatedUserName
   816  	if !isAdmin {
   817  		authUser = authenticatedUserNameNoAdmin
   818  	}
   819  	httpClient, _, err := ts.getAuthenticatedHTTPClientAndCookie(authUser, isAdmin)
   820  	return httpClient, err
   821  }
   822  
   823  func (ts *TestServer) getAuthenticatedHTTPClientAndCookie(
   824  	authUser string, isAdmin bool,
   825  ) (http.Client, *serverpb.SessionCookie, error) {
   826  	authIdx := 0
   827  	if isAdmin {
   828  		authIdx = 1
   829  	}
   830  	authClient := &ts.authClient[authIdx]
   831  	authClient.once.Do(func() {
   832  		// Create an authentication session for an arbitrary admin user.
   833  		authClient.err = func() error {
   834  			// The user needs to exist as the admin endpoints will check its role.
   835  			if err := ts.createAuthUser(authUser, isAdmin); err != nil {
   836  				return err
   837  			}
   838  
   839  			id, secret, err := ts.authentication.newAuthSession(context.TODO(), authUser)
   840  			if err != nil {
   841  				return err
   842  			}
   843  			rawCookie := &serverpb.SessionCookie{
   844  				ID:     id,
   845  				Secret: secret,
   846  			}
   847  			// Encode a session cookie and store it in a cookie jar.
   848  			cookie, err := EncodeSessionCookie(rawCookie, false /* forHTTPSOnly */)
   849  			if err != nil {
   850  				return err
   851  			}
   852  			cookieJar, err := cookiejar.New(nil)
   853  			if err != nil {
   854  				return err
   855  			}
   856  			url, err := url.Parse(ts.AdminURL())
   857  			if err != nil {
   858  				return err
   859  			}
   860  			cookieJar.SetCookies(url, []*http.Cookie{cookie})
   861  			// Create an httpClient and attach the cookie jar to the client.
   862  			authClient.httpClient, err = ts.Cfg.GetHTTPClient()
   863  			if err != nil {
   864  				return err
   865  			}
   866  			authClient.httpClient.Jar = cookieJar
   867  			authClient.cookie = rawCookie
   868  			return nil
   869  		}()
   870  	})
   871  
   872  	return authClient.httpClient, authClient.cookie, authClient.err
   873  }
   874  
   875  func (ts *TestServer) createAuthUser(userName string, isAdmin bool) error {
   876  	if _, err := ts.Server.sqlServer.internalExecutor.ExecEx(context.TODO(),
   877  		"create-auth-user", nil,
   878  		sqlbase.InternalExecutorSessionDataOverride{User: security.RootUser},
   879  		"CREATE USER $1", userName,
   880  	); err != nil {
   881  		return err
   882  	}
   883  	if isAdmin {
   884  		// We can't use the GRANT statement here because we don't want
   885  		// to rely on CCL code.
   886  		if _, err := ts.Server.sqlServer.internalExecutor.ExecEx(context.TODO(),
   887  			"grant-admin", nil,
   888  			sqlbase.InternalExecutorSessionDataOverride{User: security.RootUser},
   889  			"INSERT INTO system.role_members (role, member, \"isAdmin\") VALUES ('admin', $1, true)", userName,
   890  		); err != nil {
   891  			return err
   892  		}
   893  	}
   894  	return nil
   895  }
   896  
   897  // MustGetSQLCounter implements TestServerInterface.
   898  func (ts *TestServer) MustGetSQLCounter(name string) int64 {
   899  	var c int64
   900  	var found bool
   901  
   902  	ts.registry.Each(func(n string, v interface{}) {
   903  		if name == n {
   904  			switch t := v.(type) {
   905  			case *metric.Counter:
   906  				c = t.Count()
   907  				found = true
   908  			case *metric.Gauge:
   909  				c = t.Value()
   910  				found = true
   911  			}
   912  		}
   913  	})
   914  	if !found {
   915  		panic(fmt.Sprintf("couldn't find metric %s", name))
   916  	}
   917  	return c
   918  }
   919  
   920  // MustGetSQLNetworkCounter implements TestServerInterface.
   921  func (ts *TestServer) MustGetSQLNetworkCounter(name string) int64 {
   922  	var c int64
   923  	var found bool
   924  
   925  	reg := metric.NewRegistry()
   926  	for _, m := range ts.sqlServer.pgServer.Metrics() {
   927  		reg.AddMetricStruct(m)
   928  	}
   929  	reg.Each(func(n string, v interface{}) {
   930  		if name == n {
   931  			switch t := v.(type) {
   932  			case *metric.Counter:
   933  				c = t.Count()
   934  				found = true
   935  			case *metric.Gauge:
   936  				c = t.Value()
   937  				found = true
   938  			}
   939  		}
   940  	})
   941  	if !found {
   942  		panic(fmt.Sprintf("couldn't find metric %s", name))
   943  	}
   944  	return c
   945  }
   946  
   947  // LeaseManager is part of TestServerInterface.
   948  func (ts *TestServer) LeaseManager() interface{} {
   949  	return ts.sqlServer.leaseMgr
   950  }
   951  
   952  // InternalExecutor is part of TestServerInterface.
   953  func (ts *TestServer) InternalExecutor() interface{} {
   954  	return ts.sqlServer.internalExecutor
   955  }
   956  
   957  // GetNode exposes the Server's Node.
   958  func (ts *TestServer) GetNode() *Node {
   959  	return ts.node
   960  }
   961  
   962  // DistSenderI is part of DistSendeInterface.
   963  func (ts *TestServer) DistSenderI() interface{} {
   964  	return ts.distSender
   965  }
   966  
   967  // DistSender is like DistSenderI(), but returns the real type instead of
   968  // interface{}.
   969  func (ts *TestServer) DistSender() *kvcoord.DistSender {
   970  	return ts.DistSenderI().(*kvcoord.DistSender)
   971  }
   972  
   973  // SQLServer is part of TestServerInterface.
   974  func (ts *TestServer) SQLServer() interface{} {
   975  	return ts.PGServer().SQLServer
   976  }
   977  
   978  // DistSQLServer is part of TestServerInterface.
   979  func (ts *TestServer) DistSQLServer() interface{} {
   980  	return ts.sqlServer.distSQLServer
   981  }
   982  
   983  // SetDistSQLSpanResolver is part of TestServerInterface.
   984  func (s *Server) SetDistSQLSpanResolver(spanResolver interface{}) {
   985  	s.sqlServer.execCfg.DistSQLPlanner.SetSpanResolver(spanResolver.(physicalplan.SpanResolver))
   986  }
   987  
   988  // GetFirstStoreID is part of TestServerInterface.
   989  func (ts *TestServer) GetFirstStoreID() roachpb.StoreID {
   990  	firstStoreID := roachpb.StoreID(-1)
   991  	err := ts.Stores().VisitStores(func(s *kvserver.Store) error {
   992  		if firstStoreID == -1 {
   993  			firstStoreID = s.Ident.StoreID
   994  		}
   995  		return nil
   996  	})
   997  	if err != nil {
   998  		panic(err)
   999  	}
  1000  	return firstStoreID
  1001  }
  1002  
  1003  // LookupRange returns the descriptor of the range containing key.
  1004  func (ts *TestServer) LookupRange(key roachpb.Key) (roachpb.RangeDescriptor, error) {
  1005  	rs, _, err := kv.RangeLookup(context.Background(), ts.DB().NonTransactionalSender(),
  1006  		key, roachpb.CONSISTENT, 0 /* prefetchNum */, false /* reverse */)
  1007  	if err != nil {
  1008  		return roachpb.RangeDescriptor{}, errors.Errorf(
  1009  			"%q: lookup range unexpected error: %s", key, err)
  1010  	}
  1011  	return rs[0], nil
  1012  }
  1013  
  1014  // MergeRanges merges the range containing leftKey with the range to its right.
  1015  func (ts *TestServer) MergeRanges(leftKey roachpb.Key) (roachpb.RangeDescriptor, error) {
  1016  
  1017  	ctx := context.Background()
  1018  	mergeReq := roachpb.AdminMergeRequest{
  1019  		RequestHeader: roachpb.RequestHeader{
  1020  			Key: leftKey,
  1021  		},
  1022  	}
  1023  	_, pErr := kv.SendWrapped(ctx, ts.DB().NonTransactionalSender(), &mergeReq)
  1024  	if pErr != nil {
  1025  		return roachpb.RangeDescriptor{},
  1026  			errors.Errorf(
  1027  				"%q: merge unexpected error: %s", leftKey, pErr)
  1028  	}
  1029  	return ts.LookupRange(leftKey)
  1030  }
  1031  
  1032  // SplitRange splits the range containing splitKey.
  1033  // The right range created by the split starts at the split key and extends to the
  1034  // original range's end key.
  1035  // Returns the new descriptors of the left and right ranges.
  1036  //
  1037  // splitKey must correspond to a SQL table key (it must end with a family ID /
  1038  // col ID).
  1039  func (ts *TestServer) SplitRange(
  1040  	splitKey roachpb.Key,
  1041  ) (roachpb.RangeDescriptor, roachpb.RangeDescriptor, error) {
  1042  	ctx := context.Background()
  1043  	splitRKey, err := keys.Addr(splitKey)
  1044  	if err != nil {
  1045  		return roachpb.RangeDescriptor{}, roachpb.RangeDescriptor{}, err
  1046  	}
  1047  	splitReq := roachpb.AdminSplitRequest{
  1048  		RequestHeader: roachpb.RequestHeader{
  1049  			Key: splitKey,
  1050  		},
  1051  		SplitKey:       splitKey,
  1052  		ExpirationTime: hlc.MaxTimestamp,
  1053  	}
  1054  	_, pErr := kv.SendWrapped(ctx, ts.DB().NonTransactionalSender(), &splitReq)
  1055  	if pErr != nil {
  1056  		return roachpb.RangeDescriptor{}, roachpb.RangeDescriptor{},
  1057  			errors.Errorf(
  1058  				"%q: split unexpected error: %s", splitReq.SplitKey, pErr)
  1059  	}
  1060  
  1061  	// The split point may not be exactly at the key we requested (we request
  1062  	// splits at valid table keys, and the split point corresponds to the row's
  1063  	// prefix). We scan for the range that includes the key we requested and the
  1064  	// one that precedes it.
  1065  
  1066  	// We use a transaction so that we get consistent results between the two
  1067  	// scans (in case there are other splits happening).
  1068  	var leftRangeDesc, rightRangeDesc roachpb.RangeDescriptor
  1069  
  1070  	// Errors returned from scanMeta cannot be wrapped or retryable errors won't
  1071  	// be retried. Instead, the message to wrap is stored in case of
  1072  	// non-retryable failures and then wrapped when the full transaction fails.
  1073  	var wrappedMsg string
  1074  	if err := ts.DB().Txn(ctx, func(ctx context.Context, txn *kv.Txn) error {
  1075  		scanMeta := func(key roachpb.RKey, reverse bool) (desc roachpb.RangeDescriptor, err error) {
  1076  			var kvs []kv.KeyValue
  1077  			if reverse {
  1078  				// Find the last range that ends at or before key.
  1079  				kvs, err = txn.ReverseScan(
  1080  					ctx, keys.Meta2Prefix, keys.RangeMetaKey(key.Next()), 1, /* one result */
  1081  				)
  1082  			} else {
  1083  				// Find the first range that ends after key.
  1084  				kvs, err = txn.Scan(
  1085  					ctx, keys.RangeMetaKey(key.Next()), keys.Meta2Prefix.PrefixEnd(), 1, /* one result */
  1086  				)
  1087  			}
  1088  			if err != nil {
  1089  				return desc, err
  1090  			}
  1091  			if len(kvs) != 1 {
  1092  				return desc, fmt.Errorf("expected 1 result, got %d", len(kvs))
  1093  			}
  1094  			err = kvs[0].ValueProto(&desc)
  1095  			return desc, err
  1096  		}
  1097  
  1098  		rightRangeDesc, err = scanMeta(splitRKey, false /* reverse */)
  1099  		if err != nil {
  1100  			wrappedMsg = "could not look up right-hand side descriptor"
  1101  			return err
  1102  		}
  1103  
  1104  		leftRangeDesc, err = scanMeta(splitRKey, true /* reverse */)
  1105  		if err != nil {
  1106  			wrappedMsg = "could not look up left-hand side descriptor"
  1107  			return err
  1108  		}
  1109  
  1110  		if !leftRangeDesc.EndKey.Equal(rightRangeDesc.StartKey) {
  1111  			return errors.Errorf(
  1112  				"inconsistent left (%v) and right (%v) descriptors", leftRangeDesc, rightRangeDesc,
  1113  			)
  1114  		}
  1115  		return nil
  1116  	}); err != nil {
  1117  		if len(wrappedMsg) > 0 {
  1118  			err = errors.Wrapf(err, "%s", wrappedMsg)
  1119  		}
  1120  		return roachpb.RangeDescriptor{}, roachpb.RangeDescriptor{}, err
  1121  	}
  1122  
  1123  	return leftRangeDesc, rightRangeDesc, nil
  1124  }
  1125  
  1126  // GetRangeLease returns the current lease for the range containing key, and a
  1127  // timestamp taken from the node.
  1128  //
  1129  // The lease is returned regardless of its status.
  1130  func (ts *TestServer) GetRangeLease(
  1131  	ctx context.Context, key roachpb.Key,
  1132  ) (_ roachpb.Lease, now hlc.Timestamp, _ error) {
  1133  	leaseReq := roachpb.LeaseInfoRequest{
  1134  		RequestHeader: roachpb.RequestHeader{
  1135  			Key: key,
  1136  		},
  1137  	}
  1138  	leaseResp, pErr := kv.SendWrappedWith(
  1139  		ctx,
  1140  		ts.DB().NonTransactionalSender(),
  1141  		roachpb.Header{
  1142  			// INCONSISTENT read, since we want to make sure that the node used to
  1143  			// send this is the one that processes the command, for the hint to
  1144  			// matter.
  1145  			ReadConsistency: roachpb.INCONSISTENT,
  1146  		},
  1147  		&leaseReq,
  1148  	)
  1149  	if pErr != nil {
  1150  		return roachpb.Lease{}, hlc.Timestamp{}, pErr.GoError()
  1151  	}
  1152  	return leaseResp.(*roachpb.LeaseInfoResponse).Lease, ts.Clock().Now(), nil
  1153  
  1154  }
  1155  
  1156  // ExecutorConfig is part of the TestServerInterface.
  1157  func (ts *TestServer) ExecutorConfig() interface{} {
  1158  	return *ts.sqlServer.execCfg
  1159  }
  1160  
  1161  // GCSystemLog deletes entries in the given system log table between
  1162  // timestamp and timestampUpperBound if the server is the lease holder
  1163  // for range 1.
  1164  // Leaseholder constraint is present so that only one node in the cluster
  1165  // performs gc.
  1166  // The system log table is expected to have a "timestamp" column.
  1167  // It returns the timestampLowerBound to be used in the next iteration, number
  1168  // of rows affected and error (if any).
  1169  func (ts *TestServer) GCSystemLog(
  1170  	ctx context.Context, table string, timestampLowerBound, timestampUpperBound time.Time,
  1171  ) (time.Time, int64, error) {
  1172  	return ts.gcSystemLog(ctx, table, timestampLowerBound, timestampUpperBound)
  1173  }
  1174  
  1175  // ForceTableGC is part of TestServerInterface.
  1176  func (ts *TestServer) ForceTableGC(
  1177  	ctx context.Context, database, table string, timestamp hlc.Timestamp,
  1178  ) error {
  1179  	tableIDQuery := `
  1180   SELECT tables.id FROM system.namespace tables
  1181     JOIN system.namespace dbs ON dbs.id = tables."parentID"
  1182     WHERE dbs.name = $1 AND tables.name = $2
  1183   `
  1184  	row, err := ts.sqlServer.internalExecutor.QueryRowEx(
  1185  		ctx, "resolve-table-id", nil, /* txn */
  1186  		sqlbase.InternalExecutorSessionDataOverride{User: security.RootUser},
  1187  		tableIDQuery, database, table)
  1188  	if err != nil {
  1189  		return err
  1190  	}
  1191  	if row == nil {
  1192  		return errors.Errorf("table not found")
  1193  	}
  1194  	if len(row) != 1 {
  1195  		return errors.AssertionFailedf("expected 1 column from internal query")
  1196  	}
  1197  	tableID := uint32(*row[0].(*tree.DInt))
  1198  	tblKey := keys.SystemSQLCodec.TablePrefix(tableID)
  1199  	gcr := roachpb.GCRequest{
  1200  		RequestHeader: roachpb.RequestHeader{
  1201  			Key:    tblKey,
  1202  			EndKey: tblKey.PrefixEnd(),
  1203  		},
  1204  		Threshold: timestamp,
  1205  	}
  1206  	_, pErr := kv.SendWrapped(ctx, ts.distSender, &gcr)
  1207  	return pErr.GoError()
  1208  }
  1209  
  1210  type testServerFactoryImpl struct{}
  1211  
  1212  // TestServerFactory can be passed to serverutils.InitTestServerFactory
  1213  var TestServerFactory = testServerFactoryImpl{}
  1214  
  1215  // New is part of TestServerFactory interface.
  1216  func (testServerFactoryImpl) New(params base.TestServerArgs) interface{} {
  1217  	cfg := makeTestConfigFromParams(params)
  1218  	return &TestServer{Cfg: &cfg}
  1219  }