vitess.io/vitess@v0.16.2/go/vt/vtctl/vtctlclienttest/client.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 vtctlclienttest contains the testsuite against which each 18 // RPC implementation of the vtctlclient interface must be tested. 19 package vtctlclienttest 20 21 // NOTE: This file is not test-only code because it is referenced by tests in 22 // other packages and therefore it has to be regularly visible. 23 24 // NOTE: This code is in its own package such that its dependencies (e.g. 25 // zookeeper) won't be drawn into production binaries as well. 26 27 import ( 28 "io" 29 "strings" 30 "testing" 31 "time" 32 33 "context" 34 35 "vitess.io/vitess/go/vt/logutil" 36 "vitess.io/vitess/go/vt/topo" 37 "vitess.io/vitess/go/vt/topo/memorytopo" 38 "vitess.io/vitess/go/vt/vtctl/vtctlclient" 39 "vitess.io/vitess/go/vt/vttablet/tmclienttest" 40 41 // import the gRPC client implementation for tablet manager 42 _ "vitess.io/vitess/go/vt/vttablet/grpctmclient" 43 44 topodatapb "vitess.io/vitess/go/vt/proto/topodata" 45 ) 46 47 func init() { 48 // enforce we will use the right protocol (gRPC) (note the 49 // client is unused, but it is initialized, so it needs to exist) 50 tmclienttest.SetProtocol("go.vt.vtctl.vtctlclienttest", "grpc") 51 } 52 53 // CreateTopoServer returns the test topo server properly configured 54 func CreateTopoServer(t *testing.T) *topo.Server { 55 return memorytopo.NewServer("cell1") 56 } 57 58 // TestSuite runs the test suite on the given topo server and client 59 func TestSuite(t *testing.T, ts *topo.Server, client vtctlclient.VtctlClient) { 60 ctx := context.Background() 61 62 // Create a fake tablet 63 tablet := &topodatapb.Tablet{ 64 Alias: &topodatapb.TabletAlias{Cell: "cell1", Uid: 1}, 65 Hostname: "localhost", 66 MysqlHostname: "localhost", 67 PortMap: map[string]int32{ 68 "vt": 3333, 69 }, 70 PrimaryTermStartTime: logutil.TimeToProto(time.Date(1970, 1, 1, 1, 1, 1, 1, time.UTC)), 71 Tags: map[string]string{"tag": "value"}, 72 Keyspace: "test_keyspace", 73 Type: topodatapb.TabletType_PRIMARY, 74 } 75 tablet.MysqlPort = 3334 76 if err := ts.CreateTablet(ctx, tablet); err != nil { 77 t.Errorf("CreateTablet: %v", err) 78 } 79 80 // run a command that's gonna return something on the log channel 81 stream, err := client.ExecuteVtctlCommand(ctx, []string{"ListAllTablets", "cell1"}, 30*time.Second) 82 if err != nil { 83 t.Fatalf("Remote error: %v", err) 84 } 85 86 got, err := stream.Recv() 87 if err != nil { 88 t.Fatalf("failed to get first line: %v", err) 89 } 90 expected := "cell1-0000000001 test_keyspace <null> primary localhost:3333 localhost:3334 [tag: \"value\"] 1970-01-01T01:01:01Z\n" 91 if logutil.EventString(got) != expected { 92 t.Errorf("Got unexpected log line '%v' expected '%v'", got.String(), expected) 93 } 94 95 got, err = stream.Recv() 96 if err != io.EOF { 97 t.Errorf("Didn't get end of log stream: %v %v", got, err) 98 } 99 100 // run a command that's gonna fail 101 stream, err = client.ExecuteVtctlCommand(ctx, []string{"ListAllTablets", "cell2"}, 30*time.Second) 102 if err != nil { 103 t.Fatalf("Remote error: %v", err) 104 } 105 106 _, err = stream.Recv() 107 expected = "node doesn't exist" 108 if err == nil || !strings.Contains(err.Error(), expected) { 109 t.Fatalf("Unexpected remote error, got: '%v' was expecting to find '%v'", err, expected) 110 } 111 112 // run a command that's gonna panic 113 stream, err = client.ExecuteVtctlCommand(ctx, []string{"Panic"}, 30*time.Second) 114 if err != nil { 115 t.Fatalf("Remote error: %v", err) 116 } 117 118 _, err = stream.Recv() 119 expected1 := "this command panics on purpose" 120 expected2 := "uncaught vtctl panic" 121 if err == nil || !strings.Contains(err.Error(), expected1) || !strings.Contains(err.Error(), expected2) { 122 t.Fatalf("Unexpected remote error, got: '%v' was expecting to find '%v' and '%v'", err, expected1, expected2) 123 } 124 125 // and clean up the tablet 126 if err := ts.DeleteTablet(ctx, tablet.Alias); err != nil { 127 t.Errorf("DeleteTablet: %v", err) 128 } 129 }