vitess.io/vitess@v0.16.2/go/vt/wrangler/tablet_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  
    17  package wrangler
    18  
    19  import (
    20  	"context"
    21  	"strings"
    22  	"testing"
    23  
    24  	"vitess.io/vitess/go/vt/logutil"
    25  	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
    26  	"vitess.io/vitess/go/vt/topo"
    27  	"vitess.io/vitess/go/vt/topo/memorytopo"
    28  )
    29  
    30  // TestInitTabletShardConversion makes sure InitTablet converts the
    31  // shard name to lower case when it's a keyrange, and populates
    32  // KeyRange properly.
    33  func TestInitTabletShardConversion(t *testing.T) {
    34  	cell := "cell1"
    35  	ts := memorytopo.NewServer(cell)
    36  	wr := New(logutil.NewConsoleLogger(), ts, nil)
    37  
    38  	tablet := &topodatapb.Tablet{
    39  		Alias: &topodatapb.TabletAlias{
    40  			Cell: cell,
    41  			Uid:  1,
    42  		},
    43  		Shard: "80-C0",
    44  	}
    45  
    46  	if err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil {
    47  		t.Fatalf("InitTablet failed: %v", err)
    48  	}
    49  
    50  	ti, err := ts.GetTablet(context.Background(), tablet.Alias)
    51  	if err != nil {
    52  		t.Fatalf("GetTablet failed: %v", err)
    53  	}
    54  	if ti.Shard != "80-c0" {
    55  		t.Errorf("Got wrong tablet.Shard, got %v expected 80-c0", ti.Shard)
    56  	}
    57  	if string(ti.KeyRange.Start) != "\x80" || string(ti.KeyRange.End) != "\xc0" {
    58  		t.Errorf("Got wrong tablet.KeyRange, got %v expected 80-c0", ti.KeyRange)
    59  	}
    60  }
    61  
    62  // TestDeleteTabletBasic tests delete of non-primary tablet
    63  func TestDeleteTabletBasic(t *testing.T) {
    64  	cell := "cell1"
    65  	ts := memorytopo.NewServer(cell)
    66  	wr := New(logutil.NewConsoleLogger(), ts, nil)
    67  
    68  	tablet := &topodatapb.Tablet{
    69  		Alias: &topodatapb.TabletAlias{
    70  			Cell: cell,
    71  			Uid:  1,
    72  		},
    73  		Shard: "0",
    74  	}
    75  
    76  	if err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil {
    77  		t.Fatalf("InitTablet failed: %v", err)
    78  	}
    79  
    80  	if _, err := ts.GetTablet(context.Background(), tablet.Alias); err != nil {
    81  		t.Fatalf("GetTablet failed: %v", err)
    82  	}
    83  
    84  	if err := wr.DeleteTablet(context.Background(), tablet.Alias, false); err != nil {
    85  		t.Fatalf("DeleteTablet failed: %v", err)
    86  	}
    87  }
    88  
    89  // TestDeleteTabletTruePrimary tests that you can delete a true primary tablet
    90  // only if allowPrimary is set to true
    91  func TestDeleteTabletTruePrimary(t *testing.T) {
    92  	cell := "cell1"
    93  	ts := memorytopo.NewServer(cell)
    94  	wr := New(logutil.NewConsoleLogger(), ts, nil)
    95  
    96  	tablet := &topodatapb.Tablet{
    97  		Alias: &topodatapb.TabletAlias{
    98  			Cell: cell,
    99  			Uid:  1,
   100  		},
   101  		Keyspace: "test",
   102  		Shard:    "0",
   103  		Type:     topodatapb.TabletType_PRIMARY,
   104  	}
   105  
   106  	if err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil {
   107  		t.Fatalf("InitTablet failed: %v", err)
   108  	}
   109  	if _, err := ts.GetTablet(context.Background(), tablet.Alias); err != nil {
   110  		t.Fatalf("GetTablet failed: %v", err)
   111  	}
   112  
   113  	// set PrimaryAlias and PrimaryTermStartTime on shard to match chosen primary tablet
   114  	if _, err := ts.UpdateShardFields(context.Background(), "test", "0", func(si *topo.ShardInfo) error {
   115  		si.PrimaryAlias = tablet.Alias
   116  		si.PrimaryTermStartTime = tablet.PrimaryTermStartTime
   117  		return nil
   118  	}); err != nil {
   119  		t.Fatalf("UpdateShardFields failed: %v", err)
   120  	}
   121  
   122  	err := wr.DeleteTablet(context.Background(), tablet.Alias, false)
   123  	wantError := "as it is a primary, use allow_primary flag"
   124  	if err == nil || !strings.Contains(err.Error(), wantError) {
   125  		t.Fatalf("DeleteTablet on primary: want error = %v, got error = %v", wantError, err)
   126  	}
   127  
   128  	if err := wr.DeleteTablet(context.Background(), tablet.Alias, true); err != nil {
   129  		t.Fatalf("DeleteTablet failed: %v", err)
   130  	}
   131  }
   132  
   133  // TestDeleteTabletFalsePrimary tests that you can delete a false primary tablet
   134  // with allowPrimary set to false
   135  func TestDeleteTabletFalsePrimary(t *testing.T) {
   136  	cell := "cell1"
   137  	ts := memorytopo.NewServer(cell)
   138  	wr := New(logutil.NewConsoleLogger(), ts, nil)
   139  
   140  	tablet1 := &topodatapb.Tablet{
   141  		Alias: &topodatapb.TabletAlias{
   142  			Cell: cell,
   143  			Uid:  1,
   144  		},
   145  		Keyspace: "test",
   146  		Shard:    "0",
   147  		Type:     topodatapb.TabletType_PRIMARY,
   148  	}
   149  
   150  	if err := wr.TopoServer().InitTablet(context.Background(), tablet1, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil {
   151  		t.Fatalf("InitTablet failed: %v", err)
   152  	}
   153  
   154  	tablet2 := &topodatapb.Tablet{
   155  		Alias: &topodatapb.TabletAlias{
   156  			Cell: cell,
   157  			Uid:  2,
   158  		},
   159  		Keyspace: "test",
   160  		Shard:    "0",
   161  		Type:     topodatapb.TabletType_PRIMARY,
   162  	}
   163  	if err := wr.TopoServer().InitTablet(context.Background(), tablet2, true /*allowPrimaryOverride*/, false /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil {
   164  		t.Fatalf("InitTablet failed: %v", err)
   165  	}
   166  
   167  	// set PrimaryAlias and PrimaryTermStartTime on shard to match chosen primary tablet
   168  	if _, err := ts.UpdateShardFields(context.Background(), "test", "0", func(si *topo.ShardInfo) error {
   169  		si.PrimaryAlias = tablet2.Alias
   170  		si.PrimaryTermStartTime = tablet2.PrimaryTermStartTime
   171  		return nil
   172  	}); err != nil {
   173  		t.Fatalf("UpdateShardFields failed: %v", err)
   174  	}
   175  
   176  	// Should be able to delete old (false) primary with allowPrimary = false
   177  	if err := wr.DeleteTablet(context.Background(), tablet1.Alias, false); err != nil {
   178  		t.Fatalf("DeleteTablet failed: %v", err)
   179  	}
   180  }
   181  
   182  // TestDeleteTabletShardNonExisting tests that you can delete a true primary
   183  // tablet if a shard does not exists anymore.
   184  func TestDeleteTabletShardNonExisting(t *testing.T) {
   185  	cell := "cell1"
   186  	ts := memorytopo.NewServer(cell)
   187  	wr := New(logutil.NewConsoleLogger(), ts, nil)
   188  
   189  	tablet := &topodatapb.Tablet{
   190  		Alias: &topodatapb.TabletAlias{
   191  			Cell: cell,
   192  			Uid:  1,
   193  		},
   194  		Keyspace: "test",
   195  		Shard:    "0",
   196  		Type:     topodatapb.TabletType_PRIMARY,
   197  	}
   198  
   199  	if err := wr.TopoServer().InitTablet(context.Background(), tablet, false /*allowPrimaryOverride*/, true /*createShardAndKeyspace*/, false /*allowUpdate*/); err != nil {
   200  		t.Fatalf("InitTablet failed: %v", err)
   201  	}
   202  	if _, err := ts.GetTablet(context.Background(), tablet.Alias); err != nil {
   203  		t.Fatalf("GetTablet failed: %v", err)
   204  	}
   205  
   206  	// set PrimaryAlias and PrimaryTermStartTime on shard to match chosen primary tablet
   207  	if _, err := ts.UpdateShardFields(context.Background(), "test", "0", func(si *topo.ShardInfo) error {
   208  		si.PrimaryAlias = tablet.Alias
   209  		si.PrimaryTermStartTime = tablet.PrimaryTermStartTime
   210  		return nil
   211  	}); err != nil {
   212  		t.Fatalf("UpdateShardFields failed: %v", err)
   213  	}
   214  
   215  	// trigger a shard deletion
   216  	if err := ts.DeleteShard(context.Background(), "test", "0"); err != nil {
   217  		t.Fatalf("DeleteShard failed: %v", err)
   218  	}
   219  
   220  	// DeleteTablet should not fail if a shard no longer exist
   221  	if err := wr.DeleteTablet(context.Background(), tablet.Alias, true); err != nil {
   222  		t.Fatalf("DeleteTablet failed: %v", err)
   223  	}
   224  }