vitess.io/vitess@v0.16.2/go/vt/vtctl/grpcvtctldserver/endtoend/init_shard_primary_test.go (about)

     1  /*
     2  Copyright 2020 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package endtoend
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"testing"
    23  
    24  	"vitess.io/vitess/go/vt/mysqlctl"
    25  
    26  	"github.com/stretchr/testify/assert"
    27  	"github.com/stretchr/testify/require"
    28  
    29  	"vitess.io/vitess/go/mysql/fakesqldb"
    30  	"vitess.io/vitess/go/sqltypes"
    31  	"vitess.io/vitess/go/vt/logutil"
    32  	"vitess.io/vitess/go/vt/topo/memorytopo"
    33  	"vitess.io/vitess/go/vt/vtctl/grpcvtctldserver"
    34  	"vitess.io/vitess/go/vt/vttablet/tabletservermock"
    35  	"vitess.io/vitess/go/vt/vttablet/tmclient"
    36  	"vitess.io/vitess/go/vt/wrangler"
    37  	"vitess.io/vitess/go/vt/wrangler/testlib"
    38  
    39  	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
    40  	vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata"
    41  )
    42  
    43  func TestInitShardPrimary(t *testing.T) {
    44  	ts := memorytopo.NewServer("cell1")
    45  	tmc := tmclient.NewTabletManagerClient()
    46  	wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmc)
    47  
    48  	primaryDb := fakesqldb.New(t)
    49  	primaryDb.AddQuery("create database if not exists `vt_test_keyspace`", &sqltypes.Result{InsertID: 0, RowsAffected: 0})
    50  
    51  	tablet1 := testlib.NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_PRIMARY, primaryDb)
    52  	tablet2 := testlib.NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil)
    53  	tablet3 := testlib.NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil)
    54  
    55  	tablet1.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{
    56  		"FAKE RESET ALL REPLICATION",
    57  		mysqlctl.GenerateInitialBinlogEntry(),
    58  		"SUBINSERT INTO _vt.reparent_journal (time_created_ns, action_name, primary_alias, replication_position) VALUES",
    59  	}
    60  
    61  	tablet2.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{
    62  		// These come from tablet startup
    63  		"STOP SLAVE",
    64  		"RESET SLAVE ALL",
    65  		"FAKE SET MASTER",
    66  		"START SLAVE",
    67  		// These come from InitShardPrimary
    68  		"FAKE RESET ALL REPLICATION",
    69  		"FAKE SET SLAVE POSITION",
    70  		"RESET SLAVE ALL",
    71  		"FAKE SET MASTER",
    72  		"START SLAVE",
    73  	}
    74  	tablet2.FakeMysqlDaemon.SetReplicationSourceInputs = append(tablet2.FakeMysqlDaemon.SetReplicationSourceInputs, fmt.Sprintf("%v:%v", tablet1.Tablet.Hostname, tablet1.Tablet.MysqlPort))
    75  
    76  	tablet3.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{
    77  		"STOP SLAVE",
    78  		"RESET SLAVE ALL",
    79  		"FAKE SET MASTER",
    80  		"START SLAVE",
    81  		"FAKE RESET ALL REPLICATION",
    82  		"FAKE SET SLAVE POSITION",
    83  		"RESET SLAVE ALL",
    84  		"FAKE SET MASTER",
    85  		"START SLAVE",
    86  	}
    87  	tablet3.FakeMysqlDaemon.SetReplicationSourceInputs = append(tablet3.FakeMysqlDaemon.SetReplicationSourceInputs, fmt.Sprintf("%v:%v", tablet1.Tablet.Hostname, tablet1.Tablet.MysqlPort))
    88  
    89  	for _, tablet := range []*testlib.FakeTablet{tablet1, tablet2, tablet3} {
    90  		tablet.StartActionLoop(t, wr)
    91  		defer tablet.StopActionLoop(t)
    92  
    93  		tablet.TM.QueryServiceControl.(*tabletservermock.Controller).SetQueryServiceEnabledForTests(true)
    94  	}
    95  
    96  	vtctld := grpcvtctldserver.NewVtctldServer(ts)
    97  	resp, err := vtctld.InitShardPrimary(context.Background(), &vtctldatapb.InitShardPrimaryRequest{
    98  		Keyspace:                tablet1.Tablet.Keyspace,
    99  		Shard:                   tablet1.Tablet.Shard,
   100  		PrimaryElectTabletAlias: tablet1.Tablet.Alias,
   101  	})
   102  
   103  	assert.NoError(t, err)
   104  	assert.NotNil(t, resp)
   105  }
   106  
   107  func TestInitShardPrimaryNoFormerPrimary(t *testing.T) {
   108  	ts := memorytopo.NewServer("cell1")
   109  	tmc := tmclient.NewTabletManagerClient()
   110  	wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmc)
   111  
   112  	primaryDb := fakesqldb.New(t)
   113  	primaryDb.AddQuery("create database if not exists `vt_test_keyspace`", &sqltypes.Result{InsertID: 0, RowsAffected: 0})
   114  
   115  	tablet1 := testlib.NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_REPLICA, primaryDb)
   116  	tablet2 := testlib.NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil)
   117  	tablet3 := testlib.NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil)
   118  
   119  	tablet1.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{
   120  		"FAKE RESET ALL REPLICATION",
   121  		mysqlctl.GenerateInitialBinlogEntry(),
   122  		"SUBINSERT INTO _vt.reparent_journal (time_created_ns, action_name, primary_alias, replication_position) VALUES",
   123  	}
   124  
   125  	tablet2.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{
   126  		"FAKE RESET ALL REPLICATION",
   127  		"FAKE SET SLAVE POSITION",
   128  		"RESET SLAVE ALL",
   129  		"FAKE SET MASTER",
   130  		"START SLAVE",
   131  	}
   132  	tablet2.FakeMysqlDaemon.SetReplicationSourceInputs = append(tablet2.FakeMysqlDaemon.SetReplicationSourceInputs, fmt.Sprintf("%v:%v", tablet1.Tablet.Hostname, tablet1.Tablet.MysqlPort))
   133  
   134  	tablet3.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{
   135  		"FAKE RESET ALL REPLICATION",
   136  		"FAKE SET SLAVE POSITION",
   137  		"RESET SLAVE ALL",
   138  		"FAKE SET MASTER",
   139  		"START SLAVE",
   140  	}
   141  	tablet3.FakeMysqlDaemon.SetReplicationSourceInputs = append(tablet3.FakeMysqlDaemon.SetReplicationSourceInputs, fmt.Sprintf("%v:%v", tablet1.Tablet.Hostname, tablet1.Tablet.MysqlPort))
   142  
   143  	for _, tablet := range []*testlib.FakeTablet{tablet1, tablet2, tablet3} {
   144  		tablet.StartActionLoop(t, wr)
   145  		defer tablet.StopActionLoop(t)
   146  
   147  		tablet.TM.QueryServiceControl.(*tabletservermock.Controller).SetQueryServiceEnabledForTests(true)
   148  	}
   149  
   150  	vtctld := grpcvtctldserver.NewVtctldServer(ts)
   151  	_, err := vtctld.InitShardPrimary(context.Background(), &vtctldatapb.InitShardPrimaryRequest{
   152  		Keyspace:                tablet1.Tablet.Keyspace,
   153  		Shard:                   tablet1.Tablet.Shard,
   154  		PrimaryElectTabletAlias: tablet1.Tablet.Alias,
   155  	})
   156  
   157  	assert.Error(t, err)
   158  
   159  	resp, err := vtctld.InitShardPrimary(context.Background(), &vtctldatapb.InitShardPrimaryRequest{
   160  		Keyspace:                tablet1.Tablet.Keyspace,
   161  		Shard:                   tablet1.Tablet.Shard,
   162  		PrimaryElectTabletAlias: tablet1.Tablet.Alias,
   163  		Force:                   true,
   164  	})
   165  	assert.NoError(t, err)
   166  	assert.NotNil(t, resp)
   167  	tablet1PostInit, err := ts.GetTablet(context.Background(), tablet1.Tablet.Alias)
   168  	require.NoError(t, err)
   169  	assert.Equal(t, topodatapb.TabletType_PRIMARY, tablet1PostInit.Type)
   170  }