vitess.io/vitess@v0.16.2/go/test/endtoend/tabletmanager/custom_rule_topo_test.go (about)

     1  /*
     2  Copyright 2019 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  package tabletmanager
    17  
    18  import (
    19  	"context"
    20  	"os"
    21  	"testing"
    22  	"time"
    23  
    24  	"vitess.io/vitess/go/test/endtoend/utils"
    25  
    26  	"github.com/stretchr/testify/require"
    27  
    28  	"github.com/stretchr/testify/assert"
    29  
    30  	"vitess.io/vitess/go/mysql"
    31  	"vitess.io/vitess/go/test/endtoend/cluster"
    32  )
    33  
    34  func TestTopoCustomRule(t *testing.T) {
    35  
    36  	defer cluster.PanicHandler(t)
    37  	ctx := context.Background()
    38  	conn, err := mysql.Connect(ctx, &primaryTabletParams)
    39  	require.NoError(t, err)
    40  	defer conn.Close()
    41  	replicaConn, err := mysql.Connect(ctx, &replicaTabletParams)
    42  	require.NoError(t, err)
    43  	defer replicaConn.Close()
    44  
    45  	// Insert data for sanity checks
    46  	utils.Exec(t, conn, "delete from t1")
    47  	utils.Exec(t, conn, "insert into t1(id, value) values(11,'r'), (12,'s')")
    48  	checkDataOnReplica(t, replicaConn, `[[VARCHAR("r")] [VARCHAR("s")]]`)
    49  
    50  	// create empty topoCustomRuleFile.
    51  	topoCustomRuleFile := "/tmp/rules.json"
    52  	topoCustomRulePath := "/keyspaces/ks/configs/CustomRules"
    53  	data := []byte("[]\n")
    54  	err = os.WriteFile(topoCustomRuleFile, data, 0777)
    55  	require.NoError(t, err)
    56  
    57  	// Copy config file into topo.
    58  	err = clusterInstance.VtctlclientProcess.ExecuteCommand("TopoCp", "--", "--to_topo", topoCustomRuleFile, topoCustomRulePath)
    59  	require.Nil(t, err, "error should be Nil")
    60  
    61  	// Set extra tablet args for topo custom rule
    62  	clusterInstance.VtTabletExtraArgs = []string{
    63  		"--topocustomrule_path", topoCustomRulePath,
    64  	}
    65  
    66  	// Start a new Tablet
    67  	rTablet := clusterInstance.NewVttabletInstance("replica", 0, "")
    68  
    69  	// Start Mysql Processes
    70  	err = cluster.StartMySQL(ctx, rTablet, username, clusterInstance.TmpDirectory)
    71  	require.Nil(t, err, "error should be Nil")
    72  
    73  	// Start Vttablet
    74  	err = clusterInstance.StartVttablet(rTablet, "SERVING", false, cell, keyspaceName, hostname, shardName)
    75  	require.Nil(t, err, "error should be Nil")
    76  
    77  	err = clusterInstance.VtctlclientProcess.ExecuteCommand("Validate")
    78  	require.Nil(t, err, "error should be Nil")
    79  
    80  	// And wait until the query is working.
    81  	// We need a wait here because the instance we have created is a replica
    82  	// It might take a while to replicate the two rows.
    83  	timeout := time.Now().Add(10 * time.Second)
    84  	for time.Now().Before(timeout) {
    85  		qr, err := clusterInstance.ExecOnTablet(context.Background(), rTablet, "select id, value from t1", nil, nil)
    86  		if err == nil {
    87  			if len(qr.Rows) == 2 {
    88  				break
    89  			}
    90  		}
    91  		time.Sleep(300 * time.Millisecond)
    92  	}
    93  
    94  	// Now update the topocustomrule file.
    95  	data = []byte(`[{
    96  		"Name": "rule1",
    97  		"Description": "disallow select on table t1",
    98  		"TableNames" : ["t1"],
    99  		"Query" : "(select)|(SELECT)"
   100  	  }]`)
   101  	err = os.WriteFile(topoCustomRuleFile, data, 0777)
   102  	require.NoError(t, err)
   103  
   104  	err = clusterInstance.VtctlclientProcess.ExecuteCommand("TopoCp", "--", "--to_topo", topoCustomRuleFile, topoCustomRulePath)
   105  	require.Nil(t, err, "error should be Nil")
   106  
   107  	// And wait until the query fails with the right error.
   108  	timeout = time.Now().Add(10 * time.Second)
   109  	for time.Now().Before(timeout) {
   110  		if _, err := clusterInstance.ExecOnTablet(context.Background(), rTablet, "select id, value from t1", nil, nil); err != nil {
   111  			assert.Contains(t, err.Error(), "disallow select on table t1")
   112  			break
   113  		}
   114  		time.Sleep(300 * time.Millisecond)
   115  	}
   116  
   117  	// Empty the table
   118  	utils.Exec(t, conn, "delete from t1")
   119  	// Reset the VtTabletExtraArgs
   120  	clusterInstance.VtTabletExtraArgs = []string{}
   121  	// Tear down custom processes
   122  	killTablets(t, rTablet)
   123  }