vitess.io/vitess@v0.16.2/go/vt/vtorc/logic/keyspace_discovery_test.go (about)

     1  /*
     2  Copyright 2022 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 logic
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	"github.com/stretchr/testify/assert"
    24  	"github.com/stretchr/testify/require"
    25  	_ "modernc.org/sqlite"
    26  
    27  	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
    28  	"vitess.io/vitess/go/vt/topo"
    29  	"vitess.io/vitess/go/vt/topo/memorytopo"
    30  	"vitess.io/vitess/go/vt/topotools"
    31  	"vitess.io/vitess/go/vt/vtctl/reparentutil/reparenttestutil"
    32  	"vitess.io/vitess/go/vt/vtorc/db"
    33  	"vitess.io/vitess/go/vt/vtorc/inst"
    34  )
    35  
    36  var (
    37  	keyspaceDurabilityNone = &topodatapb.Keyspace{
    38  		KeyspaceType:     topodatapb.KeyspaceType_NORMAL,
    39  		DurabilityPolicy: "none",
    40  	}
    41  	keyspaceDurabilitySemiSync = &topodatapb.Keyspace{
    42  		KeyspaceType:     topodatapb.KeyspaceType_NORMAL,
    43  		DurabilityPolicy: "semi_sync",
    44  	}
    45  	keyspaceDurabilityTest = &topodatapb.Keyspace{
    46  		KeyspaceType:     topodatapb.KeyspaceType_NORMAL,
    47  		DurabilityPolicy: "test",
    48  	}
    49  	keyspaceSnapshot = &topodatapb.Keyspace{
    50  		KeyspaceType: topodatapb.KeyspaceType_SNAPSHOT,
    51  	}
    52  )
    53  
    54  func TestRefreshAllKeyspaces(t *testing.T) {
    55  	// Store the old flags and restore on test completion
    56  	oldTs := ts
    57  	oldClustersToWatch := clustersToWatch
    58  	defer func() {
    59  		ts = oldTs
    60  		clustersToWatch = oldClustersToWatch
    61  	}()
    62  
    63  	// Open the vtorc
    64  	// After the test completes delete everything from the vitess_keyspace table
    65  	orcDb, err := db.OpenVTOrc()
    66  	require.NoError(t, err)
    67  	defer func() {
    68  		_, err = orcDb.Exec("delete from vitess_keyspace")
    69  		require.NoError(t, err)
    70  	}()
    71  
    72  	ts = memorytopo.NewServer("zone1")
    73  	keyspaceNames := []string{"ks1", "ks2", "ks3", "ks4"}
    74  	keyspaces := []*topodatapb.Keyspace{keyspaceDurabilityNone, keyspaceDurabilitySemiSync, keyspaceSnapshot, keyspaceDurabilityTest}
    75  
    76  	// Create 4 keyspaces
    77  	for i, keyspace := range keyspaces {
    78  		err := ts.CreateKeyspace(context.Background(), keyspaceNames[i], keyspace)
    79  		require.NoError(t, err)
    80  	}
    81  
    82  	// Set clusters to watch to only watch ks1 and ks3
    83  	onlyKs1and3 := []string{"ks1/-", "ks3/-80", "ks3/80-"}
    84  	clustersToWatch = onlyKs1and3
    85  	RefreshAllKeyspaces()
    86  
    87  	// Verify that we only have ks1 and ks3 in vtorc's db.
    88  	verifyKeyspaceInfo(t, "ks1", keyspaceDurabilityNone, "")
    89  	verifyKeyspaceInfo(t, "ks2", nil, "keyspace not found")
    90  	verifyKeyspaceInfo(t, "ks3", keyspaceSnapshot, "")
    91  	verifyKeyspaceInfo(t, "ks4", nil, "keyspace not found")
    92  
    93  	// Set clusters to watch to watch all keyspaces
    94  	clustersToWatch = nil
    95  	// Change the durability policy of ks1
    96  	reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "ks1", "semi_sync")
    97  	RefreshAllKeyspaces()
    98  
    99  	// Verify that all the keyspaces are correctly reloaded
   100  	verifyKeyspaceInfo(t, "ks1", keyspaceDurabilitySemiSync, "")
   101  	verifyKeyspaceInfo(t, "ks2", keyspaceDurabilitySemiSync, "")
   102  	verifyKeyspaceInfo(t, "ks3", keyspaceSnapshot, "")
   103  	verifyKeyspaceInfo(t, "ks4", keyspaceDurabilityTest, "")
   104  }
   105  
   106  func TestRefreshKeyspace(t *testing.T) {
   107  	// Store the old flags and restore on test completion
   108  	oldTs := ts
   109  	defer func() {
   110  		ts = oldTs
   111  	}()
   112  
   113  	// Open the vtorc
   114  	// After the test completes delete everything from the vitess_keyspace table
   115  	orcDb, err := db.OpenVTOrc()
   116  	require.NoError(t, err)
   117  	defer func() {
   118  		_, err = orcDb.Exec("delete from vitess_keyspace")
   119  		require.NoError(t, err)
   120  	}()
   121  
   122  	tests := []struct {
   123  		name           string
   124  		keyspaceName   string
   125  		keyspace       *topodatapb.Keyspace
   126  		ts             *topo.Server
   127  		keyspaceWanted *topodatapb.Keyspace
   128  		err            string
   129  	}{
   130  		{
   131  			name:         "Success with keyspaceType and durability",
   132  			keyspaceName: "ks1",
   133  			ts:           memorytopo.NewServer("zone1"),
   134  			keyspace: &topodatapb.Keyspace{
   135  				KeyspaceType:     topodatapb.KeyspaceType_NORMAL,
   136  				DurabilityPolicy: "semi_sync",
   137  			},
   138  			keyspaceWanted: nil,
   139  			err:            "",
   140  		}, {
   141  			name:         "Success with keyspaceType and no durability",
   142  			keyspaceName: "ks2",
   143  			ts:           memorytopo.NewServer("zone1"),
   144  			keyspace: &topodatapb.Keyspace{
   145  				KeyspaceType: topodatapb.KeyspaceType_NORMAL,
   146  			},
   147  			keyspaceWanted: nil,
   148  			err:            "",
   149  		}, {
   150  			name:         "Success with snapshot keyspaceType",
   151  			keyspaceName: "ks3",
   152  			ts:           memorytopo.NewServer("zone1"),
   153  			keyspace: &topodatapb.Keyspace{
   154  				KeyspaceType: topodatapb.KeyspaceType_SNAPSHOT,
   155  			},
   156  			keyspaceWanted: nil,
   157  			err:            "",
   158  		}, {
   159  			name:         "Success with fields that are not stored",
   160  			keyspaceName: "ks4",
   161  			ts:           memorytopo.NewServer("zone1"),
   162  			keyspace: &topodatapb.Keyspace{
   163  				KeyspaceType:     topodatapb.KeyspaceType_NORMAL,
   164  				DurabilityPolicy: "none",
   165  				BaseKeyspace:     "baseKeyspace",
   166  			},
   167  			keyspaceWanted: &topodatapb.Keyspace{
   168  				KeyspaceType:     topodatapb.KeyspaceType_NORMAL,
   169  				DurabilityPolicy: "none",
   170  			},
   171  			err: "",
   172  		}, {
   173  			name:           "No keyspace found",
   174  			keyspaceName:   "ks5",
   175  			ts:             memorytopo.NewServer("zone1"),
   176  			keyspace:       nil,
   177  			keyspaceWanted: nil,
   178  			err:            "node doesn't exist: keyspaces/ks5/Keyspace",
   179  		},
   180  	}
   181  	for _, tt := range tests {
   182  		t.Run(tt.name, func(t *testing.T) {
   183  			if tt.keyspaceWanted == nil {
   184  				tt.keyspaceWanted = tt.keyspace
   185  			}
   186  
   187  			ts = tt.ts
   188  			if tt.keyspace != nil {
   189  				err := ts.CreateKeyspace(context.Background(), tt.keyspaceName, tt.keyspace)
   190  				require.NoError(t, err)
   191  			}
   192  
   193  			err := RefreshKeyspace(tt.keyspaceName)
   194  			if tt.err != "" {
   195  				require.EqualError(t, err, tt.err)
   196  			} else {
   197  				require.NoError(t, err)
   198  				verifyKeyspaceInfo(t, tt.keyspaceName, tt.keyspaceWanted, "")
   199  			}
   200  		})
   201  	}
   202  }
   203  
   204  // verifyKeyspaceInfo verifies that the keyspace information read from the vtorc database
   205  // is the same as the one provided or reading it gives the same error as expected
   206  func verifyKeyspaceInfo(t *testing.T, keyspaceName string, keyspace *topodatapb.Keyspace, errString string) {
   207  	t.Helper()
   208  	ksInfo, err := inst.ReadKeyspace(keyspaceName)
   209  	if errString != "" {
   210  		assert.EqualError(t, err, errString)
   211  	} else {
   212  		assert.Equal(t, keyspaceName, ksInfo.KeyspaceName())
   213  		assert.True(t, topotools.KeyspaceEquality(keyspace, ksInfo.Keyspace))
   214  	}
   215  }