vitess.io/vitess@v0.16.2/go/test/endtoend/vtgate/createdb_plugin/main_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 unsharded
    18  
    19  import (
    20  	"context"
    21  	"flag"
    22  	"os"
    23  	"sync"
    24  	"testing"
    25  	"time"
    26  
    27  	"vitess.io/vitess/go/test/endtoend/utils"
    28  
    29  	"github.com/stretchr/testify/assert"
    30  
    31  	"github.com/stretchr/testify/require"
    32  
    33  	"vitess.io/vitess/go/mysql"
    34  	"vitess.io/vitess/go/test/endtoend/cluster"
    35  )
    36  
    37  var (
    38  	clusterInstance *cluster.LocalProcessCluster
    39  	vtParams        mysql.ConnParams
    40  	keyspaceName    = "ks"
    41  	cell            = "zone1"
    42  	hostname        = "localhost"
    43  )
    44  
    45  func TestMain(m *testing.M) {
    46  	defer cluster.PanicHandler(nil)
    47  	flag.Parse()
    48  
    49  	exitCode := func() int {
    50  		clusterInstance = cluster.NewCluster(cell, hostname)
    51  		defer clusterInstance.Teardown()
    52  
    53  		// Start topo server
    54  		if err := clusterInstance.StartTopo(); err != nil {
    55  			return 1
    56  		}
    57  
    58  		// Start keyspace
    59  		keyspace := &cluster.Keyspace{
    60  			Name: keyspaceName,
    61  		}
    62  		if err := clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 0, false); err != nil {
    63  			return 1
    64  		}
    65  
    66  		// Start vtgate
    67  		clusterInstance.VtGateExtraArgs = []string{"--dbddl_plugin", "noop", "--mysql_server_query_timeout", "60s"}
    68  		vtgateProcess := clusterInstance.NewVtgateInstance()
    69  		vtgateProcess.SysVarSetEnabled = true
    70  		if err := vtgateProcess.Setup(); err != nil {
    71  			return 1
    72  		}
    73  
    74  		vtParams = mysql.ConnParams{
    75  			Host: clusterInstance.Hostname,
    76  			Port: clusterInstance.VtgateMySQLPort,
    77  		}
    78  		return m.Run()
    79  	}()
    80  	os.Exit(exitCode)
    81  }
    82  
    83  func TestDBDDLPlugin(t *testing.T) {
    84  	defer cluster.PanicHandler(t)
    85  	ctx := context.Background()
    86  	vtParams := mysql.ConnParams{
    87  		Host: "localhost",
    88  		Port: clusterInstance.VtgateMySQLPort,
    89  	}
    90  	conn, err := mysql.Connect(ctx, &vtParams)
    91  	require.NoError(t, err)
    92  	defer conn.Close()
    93  
    94  	createAndDrop := func(t *testing.T) {
    95  		wg := sync.WaitGroup{}
    96  		wg.Add(1)
    97  		go func() {
    98  			defer wg.Done()
    99  			qr := utils.Exec(t, conn, `create database aaa`)
   100  			require.EqualValues(t, 1, qr.RowsAffected)
   101  		}()
   102  		time.Sleep(300 * time.Millisecond)
   103  		start(t, "aaa")
   104  
   105  		// wait until the create database query has returned
   106  		wg.Wait()
   107  
   108  		utils.Exec(t, conn, `use aaa`)
   109  		utils.Exec(t, conn, `create table t (id bigint primary key)`)
   110  		utils.Exec(t, conn, `insert into t(id) values (1),(2),(3),(4),(5)`)
   111  		utils.AssertMatches(t, conn, "select count(*) from t", `[[INT64(5)]]`)
   112  
   113  		wg.Add(1)
   114  		go func() {
   115  			defer wg.Done()
   116  			_ = utils.Exec(t, conn, `drop database aaa`)
   117  		}()
   118  		time.Sleep(300 * time.Millisecond)
   119  		shutdown(t, "aaa")
   120  
   121  		// wait until the drop database query has returned
   122  		wg.Wait()
   123  
   124  		_, err = conn.ExecuteFetch(`select count(*) from t`, 1000, true)
   125  		require.Error(t, err)
   126  	}
   127  	t.Run("first try", func(t *testing.T) {
   128  		createAndDrop(t)
   129  	})
   130  	if !t.Failed() {
   131  		t.Run("second try", func(t *testing.T) {
   132  			createAndDrop(t)
   133  		})
   134  	}
   135  }
   136  
   137  func start(t *testing.T, ksName string) {
   138  	keyspace := &cluster.Keyspace{
   139  		Name: ksName,
   140  	}
   141  	require.NoError(t,
   142  		clusterInstance.StartUnshardedKeyspace(*keyspace, 0, false),
   143  		"new database creation failed")
   144  }
   145  
   146  func shutdown(t *testing.T, ksName string) {
   147  	for _, ks := range clusterInstance.Keyspaces {
   148  		if ks.Name != ksName {
   149  			continue
   150  		}
   151  		for _, shard := range ks.Shards {
   152  			for _, tablet := range shard.Vttablets {
   153  				if tablet.MysqlctlProcess.TabletUID > 0 {
   154  					_, err := tablet.MysqlctlProcess.StopProcess()
   155  					assert.NoError(t, err)
   156  				}
   157  				if tablet.MysqlctldProcess.TabletUID > 0 {
   158  					err := tablet.MysqlctldProcess.Stop()
   159  					assert.NoError(t, err)
   160  				}
   161  				_ = tablet.VttabletProcess.TearDown()
   162  			}
   163  		}
   164  	}
   165  
   166  	require.NoError(t,
   167  		clusterInstance.VtctlclientProcess.ExecuteCommand("DeleteKeyspace", "--", "--recursive", ksName))
   168  
   169  	require.NoError(t,
   170  		clusterInstance.VtctlclientProcess.ExecuteCommand("RebuildVSchemaGraph"))
   171  }