github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/function/ctl/cmd_tracespan_test.go (about) 1 // Copyright 2023 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 ctl 16 17 import ( 18 "context" 19 "fmt" 20 "sync" 21 "testing" 22 "time" 23 24 uuid2 "github.com/google/uuid" 25 "github.com/matrixorigin/matrixone/pkg/clusterservice" 26 "github.com/matrixorigin/matrixone/pkg/common/moerr" 27 "github.com/matrixorigin/matrixone/pkg/common/morpc" 28 "github.com/matrixorigin/matrixone/pkg/common/runtime" 29 "github.com/matrixorigin/matrixone/pkg/defines" 30 logpb "github.com/matrixorigin/matrixone/pkg/pb/logservice" 31 "github.com/matrixorigin/matrixone/pkg/pb/metadata" 32 "github.com/matrixorigin/matrixone/pkg/pb/query" 33 "github.com/matrixorigin/matrixone/pkg/queryservice" 34 qclient "github.com/matrixorigin/matrixone/pkg/queryservice/client" 35 "github.com/matrixorigin/matrixone/pkg/util/trace" 36 "github.com/matrixorigin/matrixone/pkg/vm/process" 37 "github.com/mohae/deepcopy" 38 "github.com/stretchr/testify/require" 39 ) 40 41 func TestCanHandleServiceAndCmdWrong(t *testing.T) { 42 var a1, a2 struct { 43 proc *process.Process 44 service serviceType 45 parameter string 46 sender requestSender 47 } 48 49 // testing query with wrong serviceType 50 a1.service = serviceType("log") 51 ret, err := handleTraceSpan(a1.proc, a1.service, a1.parameter, a1.sender) 52 require.Equal(t, ret, Result{}) 53 require.Equal(t, err, moerr.NewWrongServiceNoCtx("CN or DN", string(a1.service))) 54 55 // testing query with wrong cmd 56 a2.service = cn 57 a2.parameter = "xxx:open:s3:0" 58 ret, err = handleTraceSpan(a2.proc, a2.service, a2.parameter, a2.sender) 59 require.Equal(t, ret, Result{}) 60 require.Equal(t, err, moerr.NewInternalErrorNoCtx("cmd invalid, expected enable or disable")) 61 } 62 63 func initRuntime(uuids []string, queryAddress []string) { 64 cns := make([]metadata.CNService, len(uuids)) 65 for idx := range uuids { 66 cns[idx] = metadata.CNService{ 67 ServiceID: uuids[idx], 68 QueryAddress: queryAddress[idx], 69 } 70 } 71 72 runtime.SetupProcessLevelRuntime(runtime.DefaultRuntime()) 73 moCluster := clusterservice.NewMOCluster(new(testHAKeeperClient), 74 time.Duration(time.Second), 75 clusterservice.WithDisableRefresh(), 76 clusterservice.WithServices(cns, nil)) 77 runtime.ProcessLevelRuntime().SetGlobalVariables(runtime.ClusterService, moCluster) 78 runtime.ProcessLevelRuntime().SetGlobalVariables(runtime.MOProtocolVersion, defines.MORPCLatestVersion) 79 } 80 81 func TestCanHandleSelfCmd(t *testing.T) { 82 var a1 struct { 83 proc *process.Process 84 service serviceType 85 parameter string 86 sender requestSender 87 } 88 89 trace.InitMOCtledSpan() 90 91 initRuntime(nil, nil) 92 93 uuid := uuid2.New().String() 94 cli, err := qclient.NewQueryClient(uuid, morpc.Config{}) 95 require.Nil(t, err) 96 97 a1.proc = new(process.Process) 98 a1.proc.QueryClient = cli 99 a1.service = cn 100 a1.parameter = fmt.Sprintf("%s:enable:s3,local:10", uuid) 101 102 ret, err := handleTraceSpan(a1.proc, a1.service, a1.parameter, a1.sender) 103 require.Nil(t, err) 104 require.Equal(t, ret, Result{ 105 Method: TraceSpanMethod, 106 Data: fmt.Sprintf("%s:[s3 local] enabled, [] failed; ", uuid), 107 }) 108 109 k1 := trace.MOCtledSpanEnableConfig.NameToKind["s3"] 110 k2 := trace.MOCtledSpanEnableConfig.NameToKind["local"] 111 require.Equal(t, true, trace.MOCtledSpanEnableConfig.KindToState[k1].Enable) 112 require.Equal(t, int64(10), trace.MOCtledSpanEnableConfig.KindToState[k1].Threshold.Milliseconds()) 113 require.Equal(t, true, trace.MOCtledSpanEnableConfig.KindToState[k2].Enable) 114 require.Equal(t, int64(10), trace.MOCtledSpanEnableConfig.KindToState[k2].Threshold.Milliseconds()) 115 116 } 117 118 func TestCanTransferQuery(t *testing.T) { 119 var a1 struct { 120 proc *process.Process 121 service serviceType 122 parameter string 123 sender requestSender 124 } 125 uuids := []string{ 126 uuid2.New().String(), 127 uuid2.New().String(), 128 } 129 addrs := []string{ 130 "127.0.0.1:7777", 131 "127.0.0.1:5555", 132 } 133 134 a1.proc = new(process.Process) 135 a1.service = cn 136 a1.parameter = fmt.Sprintf("%s,%s:enable:s3,local:0", uuids[0], uuids[1]) 137 138 initRuntime(uuids, addrs) 139 trace.InitMOCtledSpan() 140 141 qs1, err := queryservice.NewQueryService(uuids[0], addrs[0], morpc.Config{}) 142 require.Nil(t, err) 143 qs2, err := queryservice.NewQueryService(uuids[1], addrs[1], morpc.Config{}) 144 require.Nil(t, err) 145 qt1, err := qclient.NewQueryClient(uuids[1], morpc.Config{}) 146 require.Nil(t, err) 147 148 qs1.AddHandleFunc(query.CmdMethod_TraceSpan, mockHandleTraceSpan, false) 149 qs2.AddHandleFunc(query.CmdMethod_TraceSpan, mockHandleTraceSpan, false) 150 151 a1.proc.QueryClient = qt1 152 153 err = qs1.Start() 154 require.Nil(t, err) 155 err = qs2.Start() 156 require.Nil(t, err) 157 158 defer func() { 159 qs1.Close() 160 qs2.Close() 161 }() 162 163 ret, err := handleTraceSpan(a1.proc, a1.service, a1.parameter, a1.sender) 164 require.Nil(t, err) 165 166 str1 := fmt.Sprintf("%s:[s3 local] enabled, [] failed; ", uuids[0]) 167 str2 := fmt.Sprintf("%s:[s3 local] enabled, [] failed; ", uuids[1]) 168 169 require.True(t, func() bool { 170 if ret.Data == str1+str2 || 171 ret.Data == str2+str1 { 172 return true 173 } 174 return false 175 }()) 176 } 177 178 type testHAKeeperClient struct { 179 sync.RWMutex 180 value logpb.ClusterDetails 181 err error 182 } 183 184 func (c *testHAKeeperClient) GetClusterDetails(ctx context.Context) (logpb.ClusterDetails, error) { 185 c.RLock() 186 defer c.RUnlock() 187 // deep copy the cluster details to avoid data race. 188 copied := deepcopy.Copy(c.value) 189 return copied.(logpb.ClusterDetails), c.err 190 } 191 192 func mockHandleTraceSpan(ctx context.Context, req *query.Request, resp *query.Response) error { 193 resp.TraceSpanResponse = new(query.TraceSpanResponse) 194 resp.TraceSpanResponse.Resp = SelfProcess( 195 req.TraceSpanRequest.Cmd, req.TraceSpanRequest.Spans, req.TraceSpanRequest.Threshold) 196 return nil 197 }