vitess.io/vitess@v0.16.2/go/test/endtoend/vtgate/schematracker/sharded_prs/st_sharded_test.go (about)

     1  /*
     2  Copyright 2021 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 shardedprs
    18  
    19  import (
    20  	"context"
    21  	"flag"
    22  	"fmt"
    23  	"os"
    24  	"testing"
    25  	"time"
    26  
    27  	vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
    28  	"vitess.io/vitess/go/vt/vterrors"
    29  
    30  	"vitess.io/vitess/go/test/endtoend/utils"
    31  
    32  	"github.com/stretchr/testify/require"
    33  
    34  	"vitess.io/vitess/go/mysql"
    35  	"vitess.io/vitess/go/test/endtoend/cluster"
    36  )
    37  
    38  var (
    39  	clusterInstance *cluster.LocalProcessCluster
    40  	vtParams        mysql.ConnParams
    41  	KeyspaceName    = "ks"
    42  	Cell            = "test"
    43  	SchemaSQL       = `
    44  create table t2(
    45  	id3 bigint,
    46  	id4 bigint,
    47  	primary key(id3)
    48  ) Engine=InnoDB;
    49  
    50  create table t2_id4_idx(
    51  	id bigint not null auto_increment,
    52  	id4 bigint,
    53  	id3 bigint,
    54  	primary key(id),
    55  	key idx_id4(id4)
    56  ) Engine=InnoDB;
    57  
    58  create table t8(
    59  	id8 bigint,
    60  	testId bigint,
    61  	primary key(id8)
    62  ) Engine=InnoDB;
    63  `
    64  
    65  	VSchema = `
    66  {
    67    "sharded": true,
    68    "vindexes": {
    69      "unicode_loose_xxhash" : {
    70  	  "type": "unicode_loose_xxhash"
    71      },
    72      "unicode_loose_md5" : {
    73  	  "type": "unicode_loose_md5"
    74      },
    75      "hash": {
    76        "type": "hash"
    77      },
    78      "xxhash": {
    79        "type": "xxhash"
    80      },
    81      "t2_id4_idx": {
    82        "type": "lookup_hash",
    83        "params": {
    84          "table": "t2_id4_idx",
    85          "from": "id4",
    86          "to": "id3",
    87          "autocommit": "true"
    88        },
    89        "owner": "t2"
    90      }
    91    },
    92    "tables": {
    93      "t2": {
    94        "column_vindexes": [
    95          {
    96            "column": "id3",
    97            "name": "hash"
    98          },
    99          {
   100            "column": "id4",
   101            "name": "t2_id4_idx"
   102          }
   103        ]
   104      },
   105      "t2_id4_idx": {
   106        "column_vindexes": [
   107          {
   108            "column": "id4",
   109            "name": "hash"
   110          }
   111        ]
   112      },
   113      "t8": {
   114        "column_vindexes": [
   115          {
   116            "column": "id8",
   117            "name": "hash"
   118          }
   119        ]
   120      }
   121    }
   122  }`
   123  )
   124  
   125  func TestMain(m *testing.M) {
   126  	defer cluster.PanicHandler(nil)
   127  	flag.Parse()
   128  
   129  	exitCode := func() int {
   130  		clusterInstance = cluster.NewCluster(Cell, "localhost")
   131  		defer clusterInstance.Teardown()
   132  
   133  		clusterInstance.VtGateExtraArgs = []string{"--schema_change_signal", "--schema_change_signal_user", "userData1"}
   134  		clusterInstance.VtTabletExtraArgs = []string{"--queryserver-config-schema-change-signal", "--queryserver-config-schema-change-signal-interval", "5", "--queryserver-config-strict-table-acl", "--queryserver-config-acl-exempt-acl", "userData1", "--table-acl-config", "dummy.json"}
   135  
   136  		// Start topo server
   137  		err := clusterInstance.StartTopo()
   138  		if err != nil {
   139  			return 1
   140  		}
   141  
   142  		// Start keyspace
   143  		keyspace := &cluster.Keyspace{
   144  			Name:      KeyspaceName,
   145  			SchemaSQL: SchemaSQL,
   146  			VSchema:   VSchema,
   147  		}
   148  		err = clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 2, false)
   149  		if err != nil {
   150  			return 1
   151  		}
   152  
   153  		// Start vtgate
   154  		err = clusterInstance.StartVtgate()
   155  		if err != nil {
   156  			return 1
   157  		}
   158  
   159  		err = waitForVTGateAndVTTablet()
   160  		if err != nil {
   161  			fmt.Println(err)
   162  			return 1
   163  		}
   164  
   165  		// PRS on the second VTTablet of each shard
   166  		// This is supposed to change the primary tablet in the shards, meaning that a different tablet
   167  		// will be responsible for sending schema tracking updates.
   168  		for _, shard := range clusterInstance.Keyspaces[0].Shards {
   169  			err := clusterInstance.VtctlclientProcess.InitializeShard(KeyspaceName, shard.Name, Cell, shard.Vttablets[1].TabletUID)
   170  			if err != nil {
   171  				fmt.Println(err)
   172  				return 1
   173  			}
   174  		}
   175  
   176  		if err := clusterInstance.StartVTOrc(KeyspaceName); err != nil {
   177  			return 1
   178  		}
   179  
   180  		err = waitForVTGateAndVTTablet()
   181  		if err != nil {
   182  			fmt.Println(err)
   183  			return 1
   184  		}
   185  
   186  		vtParams = mysql.ConnParams{
   187  			Host: clusterInstance.Hostname,
   188  			Port: clusterInstance.VtgateMySQLPort,
   189  		}
   190  		return m.Run()
   191  	}()
   192  	os.Exit(exitCode)
   193  }
   194  
   195  func waitForVTGateAndVTTablet() error {
   196  	timeout := time.After(5 * time.Minute)
   197  	for {
   198  		select {
   199  		case <-timeout:
   200  			return vterrors.New(vtrpcpb.Code_INTERNAL, "timeout")
   201  		default:
   202  			err := clusterInstance.WaitForTabletsToHealthyInVtgate()
   203  			if err != nil {
   204  				continue
   205  			}
   206  			return nil
   207  		}
   208  	}
   209  }
   210  
   211  func TestAddColumn(t *testing.T) {
   212  	defer cluster.PanicHandler(t)
   213  	utils.SkipIfBinaryIsBelowVersion(t, 14, "vtgate")
   214  	ctx := context.Background()
   215  	conn, err := mysql.Connect(ctx, &vtParams)
   216  	require.NoError(t, err)
   217  	defer conn.Close()
   218  
   219  	_ = utils.Exec(t, conn, `alter table t2 add column aaa int`)
   220  	time.Sleep(10 * time.Second)
   221  	_ = utils.Exec(t, conn, "select aaa from t2")
   222  }