github.com/matrixorigin/matrixone@v1.2.0/pkg/tests/txn/cluster_mo_ctl_test.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package txn 16 17 import ( 18 "context" 19 "database/sql" 20 "fmt" 21 "testing" 22 23 "github.com/lni/goutils/leaktest" 24 "github.com/matrixorigin/matrixone/pkg/pb/timestamp" 25 "github.com/matrixorigin/matrixone/pkg/sql/plan/function/ctl" 26 "github.com/matrixorigin/matrixone/pkg/util/json" 27 "github.com/stretchr/testify/require" 28 ) 29 30 func TestMoCtlGetSnapshot(t *testing.T) { 31 defer leaktest.AfterTest(t)() 32 if testing.Short() { 33 t.Skip("skipping in short mode.") 34 return 35 } 36 ctx := context.Background() 37 38 // this case will start a mo cluster with 1 CNService, 1 DNService and 3 LogService. 39 // A Txn read and write will success. 40 for name, options := range testOptionsSet { 41 t.Run(name, func(t *testing.T) { 42 c, err := NewCluster(ctx, t, 43 getBasicClusterOptions(options...)) 44 require.NoError(t, err) 45 defer c.Stop() 46 c.Start() 47 48 cli := c.NewClient() 49 v := mustGetSnapshot(t, cli) 50 ts, err := timestamp.ParseTimestamp(v) 51 require.NoError(t, err) 52 require.NotEqual(t, timestamp.Timestamp{}, ts) 53 }) 54 } 55 } 56 57 func TestMoCtlUseSnapshot(t *testing.T) { 58 defer leaktest.AfterTest(t)() 59 if testing.Short() { 60 t.Skip("skipping in short mode.") 61 return 62 } 63 ctx := context.Background() 64 65 // this case will start a mo cluster with 1 CNService, 1 DNService and 3 LogService. 66 // A Txn read and write will success. 67 for name, options := range testOptionsSet { 68 t.Run(name, func(t *testing.T) { 69 c, err := NewCluster(ctx, t, 70 getBasicClusterOptions(options...)) 71 require.NoError(t, err) 72 defer c.Stop() 73 c.Start() 74 75 cli := c.NewClient() 76 77 k1 := "k1" 78 checkWrite(t, mustNewTxn(t, cli), k1, "1", nil, true) 79 checkRead(t, mustNewTxn(t, cli), k1, "1", nil, true) 80 81 v := mustGetSnapshot(t, cli) 82 83 checkWrite(t, mustNewTxn(t, cli), k1, "2", nil, true) 84 checkRead(t, mustNewTxn(t, cli), k1, "2", nil, true) 85 86 mustUseSnapshot(t, cli, v) 87 checkRead(t, mustNewTxn(t, cli), k1, "1", nil, true) 88 }) 89 } 90 } 91 92 func mustCloseRows(t *testing.T, rows *sql.Rows) { 93 require.NoError(t, rows.Close()) 94 } 95 96 func mustGetSnapshot(t *testing.T, cli Client) string { 97 txn, err := cli.NewTxn() 98 require.NoError(t, err) 99 sqlTxn := txn.(SQLBasedTxn) 100 defer func() { 101 require.NoError(t, sqlTxn.Commit()) 102 }() 103 104 rows, err := sqlTxn.ExecSQLQuery("select mo_ctl('cn', 'GetSnapshot', '')") 105 require.NoError(t, err) 106 defer func() { 107 err := rows.Close() 108 require.NoError(t, err) 109 err = rows.Err() 110 require.NoError(t, err) 111 }() 112 113 defer mustCloseRows(t, rows) 114 require.True(t, rows.Next()) 115 116 var result ctl.Result 117 value := "" 118 require.NoError(t, rows.Scan(&value)) 119 json.MustUnmarshal([]byte(value), &result) 120 return result.Data.(string) 121 } 122 123 func mustUseSnapshot(t *testing.T, cli Client, ts string) { 124 txn, err := cli.NewTxn() 125 require.NoError(t, err) 126 sqlTxn := txn.(SQLBasedTxn) 127 defer func() { 128 require.NoError(t, sqlTxn.Commit()) 129 }() 130 131 rows, err := sqlTxn.ExecSQLQuery(fmt.Sprintf("select mo_ctl('cn', 'UseSnapshot', '%s')", ts)) 132 require.NoError(t, err) 133 mustCloseRows(t, rows) 134 }