// StartTestCluster starts up a TestCluster made up of `nodes` in-memory testing // servers. // The cluster should be stopped using cluster.Stop(). func StartTestCluster(t testing.TB, nodes int, args base.TestClusterArgs) *TestCluster { if nodes < 1 { t.Fatal("invalid cluster size: ", nodes) } if args.ServerArgs.JoinAddr != "" { t.Fatal("can't specify a join addr when starting a cluster") } if args.ServerArgs.Stopper != nil { t.Fatal("can't set individual server stoppers when starting a cluster") } storeKnobs := args.ServerArgs.Knobs.Store if storeKnobs != nil && (storeKnobs.(*storage.StoreTestingKnobs).DisableSplitQueue || storeKnobs.(*storage.StoreTestingKnobs).DisableReplicateQueue) { t.Fatal("can't disable an individual server's queues when starting a cluster; " + "the cluster controls replication") } switch args.ReplicationMode { case base.ReplicationAuto: case base.ReplicationManual: if args.ServerArgs.Knobs.Store == nil { args.ServerArgs.Knobs.Store = &storage.StoreTestingKnobs{} } storeKnobs := args.ServerArgs.Knobs.Store.(*storage.StoreTestingKnobs) storeKnobs.DisableSplitQueue = true storeKnobs.DisableReplicateQueue = true default: t.Fatal("unexpected replication mode") } tc := &TestCluster{} tc.stopper = stop.NewStopper() for i := 0; i < nodes; i++ { var serverArgs base.TestServerArgs if perNodeServerArgs, ok := args.ServerArgsPerNode[i]; ok { serverArgs = perNodeServerArgs } else { serverArgs = args.ServerArgs } serverArgs.PartOfCluster = true if i > 0 { serverArgs.JoinAddr = tc.Servers[0].ServingAddr() } tc.AddServer(t, serverArgs) } // Create a closer that will stop the individual server stoppers when the // cluster stopper is stopped. tc.stopper.AddCloser(stop.CloserFn(tc.stopServers)) tc.WaitForStores(t, tc.Servers[0].Gossip()) // TODO(peter): We should replace the hardcoded 3 with the default ZoneConfig // replication factor. if args.ReplicationMode == base.ReplicationAuto && nodes >= 3 { if err := tc.waitForFullReplication(); err != nil { t.Fatal(err) } } return tc }