vitess.io/vitess@v0.16.2/go/vt/topotools/shard_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 topotools 18 19 import ( 20 "fmt" 21 "math/rand" 22 "sync" 23 "testing" 24 "time" 25 26 "context" 27 28 topodatapb "vitess.io/vitess/go/vt/proto/topodata" 29 "vitess.io/vitess/go/vt/topo/memorytopo" 30 ) 31 32 // TestCreateShard tests a few cases for topo.CreateShard 33 func TestCreateShard(t *testing.T) { 34 ctx := context.Background() 35 36 // Set up topology. 37 ts := memorytopo.NewServer("test_cell") 38 39 keyspace := "test_keyspace" 40 shard := "0" 41 42 // create shard in a non-existing keyspace 43 if err := ts.CreateShard(ctx, keyspace, shard); err == nil { 44 t.Fatalf("CreateShard(invalid keyspace) didn't fail") 45 } 46 47 // create keyspace 48 if err := ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{}); err != nil { 49 t.Fatalf("CreateKeyspace failed: %v", err) 50 } 51 52 // create shard should now work 53 if err := ts.CreateShard(ctx, keyspace, shard); err != nil { 54 t.Fatalf("CreateShard failed: %v", err) 55 } 56 } 57 58 // TestCreateShardMultiUnsharded checks ServedTypes is set 59 // only for the first created shard. 60 // TODO(sougou): we should eventually disallow multiple shards 61 // for unsharded keyspaces. 62 func TestCreateShardMultiUnsharded(t *testing.T) { 63 ctx := context.Background() 64 65 // Set up topology. 66 ts := memorytopo.NewServer("test_cell") 67 68 // create keyspace 69 keyspace := "test_keyspace" 70 if err := ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{}); err != nil { 71 t.Fatalf("CreateKeyspace failed: %v", err) 72 } 73 74 // create first shard in keyspace 75 shard0 := "0" 76 if err := ts.CreateShard(ctx, keyspace, shard0); err != nil { 77 t.Fatalf("CreateShard(shard0) failed: %v", err) 78 } 79 if si, err := ts.GetShard(ctx, keyspace, shard0); err != nil { 80 t.Fatalf("GetShard(shard0) failed: %v", err) 81 } else { 82 if !si.IsPrimaryServing { 83 t.Fatalf("shard0 should have all 3 served types") 84 } 85 } 86 87 // create second shard in keyspace 88 shard1 := "1" 89 if err := ts.CreateShard(ctx, keyspace, shard1); err != nil { 90 t.Fatalf("CreateShard(shard1) failed: %v", err) 91 } 92 if si, err := ts.GetShard(ctx, keyspace, shard1); err != nil { 93 t.Fatalf("GetShard(shard1) failed: %v", err) 94 } else { 95 if si.IsPrimaryServing { 96 t.Fatalf("shard1 should have all 3 served types") 97 } 98 } 99 } 100 101 // TestGetOrCreateShard will create / get 100 shards in a keyspace 102 // for a long time in parallel, making sure the locking and everything 103 // works correctly. 104 func TestGetOrCreateShard(t *testing.T) { 105 ctx := context.Background() 106 107 // Set up topology. 108 cell := "test_cell" 109 ts := memorytopo.NewServer(cell) 110 111 // and do massive parallel GetOrCreateShard 112 keyspace := "test_keyspace" 113 wg := sync.WaitGroup{} 114 rand.Seed(time.Now().UnixNano()) 115 for i := 0; i < 100; i++ { 116 wg.Add(1) 117 go func(i int) { 118 defer wg.Done() 119 120 for j := 0; j < 100; j++ { 121 index := rand.Intn(10) 122 shard := fmt.Sprintf("%v", index) 123 si, err := ts.GetOrCreateShard(ctx, keyspace, shard) 124 if err != nil { 125 t.Errorf("GetOrCreateShard(%v, %v) failed: %v", i, shard, err) 126 } 127 if si.ShardName() != shard { 128 t.Errorf("si.ShardName() is wrong, got %v expected %v", si.ShardName(), shard) 129 } 130 } 131 }(i) 132 } 133 wg.Wait() 134 }