Exemplo n.º 1
0
// NewServer starts a new unregistered TabletServer.
// You have to end it with StopService once testing is done.
func NewServer(config tabletserver.Config, connParams sqldb.ConnParams, enableRowcache bool) (*tabletserver.TabletServer, error) {
	dbcfgs := dbconfigs.DBConfigs{
		App: dbconfigs.DBConfig{
			ConnParams:        connParams,
			Keyspace:          "vttest",
			Shard:             "0",
			EnableRowcache:    enableRowcache,
			EnableInvalidator: false,
		},
	}

	mysqld := mysqlctl.NewMysqld(
		"Dba",
		"App",
		&mysqlctl.Mycnf{},
		&dbcfgs.Dba,
		&dbcfgs.App.ConnParams,
		&dbcfgs.Repl)

	Target = query.Target{
		Keyspace:   "vttest",
		Shard:      "0",
		TabletType: topodata.TabletType_MASTER,
	}

	server := tabletserver.NewTabletServer(config)
	err := server.StartService(&Target, &dbcfgs, nil, mysqld)
	if err != nil {
		return nil, err
	}
	return server, nil
}
Exemplo n.º 2
0
// StartDefaultServer starts the default server and initializes
// all the global variables. This function should only be called
// once at the beginning of the test.
func StartDefaultServer(connParams sqldb.ConnParams, schemaOverrides []tabletserver.SchemaOverride) error {
	dbcfgs := dbconfigs.DBConfigs{
		App: dbconfigs.DBConfig{
			ConnParams:        connParams,
			Keyspace:          "vttest",
			Shard:             "0",
			EnableRowcache:    true,
			EnableInvalidator: false,
		},
	}

	mysqld := mysqlctl.NewMysqld(
		"Dba",
		"App",
		&mysqlctl.Mycnf{},
		&dbcfgs.Dba,
		&dbcfgs.App.ConnParams,
		&dbcfgs.Repl)

	BaseConfig = tabletserver.DefaultQsConfig
	BaseConfig.RowCache.Binary = vttest.MemcachedPath()
	BaseConfig.RowCache.Socket = path.Join(os.TempDir(), "memcache.sock")
	BaseConfig.RowCache.Connections = 100
	BaseConfig.EnableAutoCommit = true
	BaseConfig.StrictTableAcl = true

	Target = query.Target{
		Keyspace:   "vttest",
		Shard:      "0",
		TabletType: topodata.TabletType_MASTER,
	}

	DefaultServer = tabletserver.NewTabletServer(BaseConfig)
	DefaultServer.Register()
	err := DefaultServer.StartService(&Target, &dbcfgs, schemaOverrides, mysqld)
	if err != nil {
		return fmt.Errorf("could not start service: %v\n", err)
	}

	// Start http service.
	ln, err := net.Listen("tcp", ":0")
	if err != nil {
		return fmt.Errorf("could not start listener: %v\n", err)
	}
	ServerAddress = fmt.Sprintf("http://%s", ln.Addr().String())
	go http.Serve(ln, nil)
	for {
		time.Sleep(10 * time.Millisecond)
		response, err := http.Get(fmt.Sprintf("%s/debug/vars", ServerAddress))
		if err == nil {
			response.Body.Close()
			break
		}
	}
	return nil
}
Exemplo n.º 3
0
// StartServer starts the server and initializes
// all the global variables. This function should only be called
// once at the beginning of the test.
func StartServer(connParams sqldb.ConnParams) error {
	dbcfgs := dbconfigs.DBConfigs{
		App: dbconfigs.DBConfig{
			ConnParams: connParams,
			Keyspace:   "vttest",
			Shard:      "0",
		},
	}

	mysqld := mysqlctl.NewMysqld(
		"Dba",
		"App",
		&mysqlctl.Mycnf{},
		&dbcfgs.Dba,
		&dbcfgs.App.ConnParams,
		&dbcfgs.Repl)

	BaseConfig = tabletserver.DefaultQsConfig
	BaseConfig.EnableAutoCommit = true
	BaseConfig.StrictTableAcl = true

	Target = querypb.Target{
		Keyspace:   "vttest",
		Shard:      "0",
		TabletType: topodatapb.TabletType_MASTER,
	}

	Server = tabletserver.NewTabletServer(BaseConfig)
	Server.Register()
	err := Server.StartService(Target, dbcfgs, mysqld)
	if err != nil {
		return fmt.Errorf("could not start service: %v\n", err)
	}

	// Start http service.
	ln, err := net.Listen("tcp", ":0")
	if err != nil {
		return fmt.Errorf("could not start listener: %v\n", err)
	}
	ServerAddress = fmt.Sprintf("http://%s", ln.Addr().String())
	go http.Serve(ln, nil)
	for {
		time.Sleep(10 * time.Millisecond)
		response, err := http.Get(fmt.Sprintf("%s/debug/vars", ServerAddress))
		if err == nil {
			response.Body.Close()
			break
		}
	}
	return nil
}
func waitForFilteredReplication(t *testing.T, expectedErr string, initialStats *pbq.RealtimeStats, broadcastStatsFunc func() *pbq.RealtimeStats) {
	ts := zktopo.NewTestServer(t, []string{"cell1", "cell2"})
	wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient(), time.Second)
	vp := NewVtctlPipe(t, ts)
	defer vp.Close()

	// source of the filtered replication. We don't start its loop because we don't connect to it.
	source := NewFakeTablet(t, wr, "cell1", 0, pbt.TabletType_MASTER,
		TabletKeyspaceShard(t, keyspace, "0"))
	// dest is the master of the dest shard which receives filtered replication events.
	dest := NewFakeTablet(t, wr, "cell1", 1, pbt.TabletType_MASTER,
		TabletKeyspaceShard(t, keyspace, destShard))
	dest.StartActionLoop(t, wr)
	defer dest.StopActionLoop(t)

	// Build topology state as we would expect it when filtered replication is enabled.
	ctx := context.Background()
	wr.SetSourceShards(ctx, keyspace, destShard, []*pbt.TabletAlias{source.Tablet.GetAlias()}, nil)

	// Set a BinlogPlayerMap to avoid a nil panic when the explicit RunHealthCheck
	// is called by WaitForFilteredReplication.
	// Note that for this test we don't mock the BinlogPlayerMap i.e. although
	// its state says no filtered replication is running, the code under test will
	// observe otherwise because we call TabletServer.BroadcastHealth() directly and
	// skip going through the tabletmanager's agent.
	dest.Agent.BinlogPlayerMap = tabletmanager.NewBinlogPlayerMap(ts, nil, nil)

	// Use real, but trimmed down QueryService.
	testConfig := tabletserver.DefaultQsConfig
	testConfig.EnablePublishStats = false
	testConfig.DebugURLPrefix = fmt.Sprintf("TestWaitForFilteredReplication-%d-", rand.Int63())
	qs := tabletserver.NewTabletServer(testConfig)
	grpcqueryservice.RegisterForTest(dest.RPCServer, qs)

	qs.BroadcastHealth(42, initialStats)

	// run vtctl WaitForFilteredReplication
	stopBroadcasting := make(chan struct{})
	go func() {
		defer close(stopBroadcasting)
		err := vp.Run([]string{"WaitForFilteredReplication", "-max_delay", "10s", dest.Tablet.Keyspace + "/" + dest.Tablet.Shard})
		if expectedErr == "" {
			if err != nil {
				t.Fatalf("WaitForFilteredReplication must not fail: %v", err)
			}
		} else {
			if err == nil || !strings.Contains(err.Error(), expectedErr) {
				t.Fatalf("WaitForFilteredReplication wrong error. got: %v want substring: %v", err, expectedErr)
			}
		}
	}()

	// Broadcast health record as long as vtctl is running.
	for {
		// Give vtctl a head start to consume the initial stats.
		// (We do this because there's unfortunately no way to explicitly
		//  synchronize with the point where conn.StreamHealth() has started.)
		// (Tests won't break if vtctl misses the initial stats. Only coverage
		//  will be impacted.)
		timer := time.NewTimer(1 * time.Millisecond)

		select {
		case <-stopBroadcasting:
			timer.Stop()
			return
		case <-timer.C:
			qs.BroadcastHealth(42, broadcastStatsFunc())
			// Pace the flooding broadcasting to waste less CPU.
			timer.Reset(1 * time.Millisecond)
		}
	}

	// vtctl WaitForFilteredReplication returned.
}