github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/soliton/execdetails/execdetails_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     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  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package execdetails
    15  
    16  import (
    17  	"fmt"
    18  	"strconv"
    19  	"sync"
    20  	"testing"
    21  	"time"
    22  
    23  	. "github.com/whtcorpsinc/check"
    24  	"github.com/whtcorpsinc/milevadb/soliton/stringutil"
    25  	"github.com/whtcorpsinc/fidelpb/go-fidelpb"
    26  )
    27  
    28  func TestT(t *testing.T) {
    29  	TestingT(t)
    30  }
    31  
    32  func TestString(t *testing.T) {
    33  	detail := &InterDircDetails{
    34  		CopTime:       time.Second + 3*time.Millisecond,
    35  		ProcessTime:   2*time.Second + 5*time.Millisecond,
    36  		WaitTime:      time.Second,
    37  		BackoffTime:   time.Second,
    38  		RequestCount:  1,
    39  		TotalKeys:     100,
    40  		ProcessedKeys: 10,
    41  		CommitDetail: &CommitDetails{
    42  			GetCommitTsTime:   time.Second,
    43  			PrewriteTime:      time.Second,
    44  			CommitTime:        time.Second,
    45  			LocalLatchTime:    time.Second,
    46  			CommitBackoffTime: int64(time.Second),
    47  			Mu: struct {
    48  				sync.Mutex
    49  				BackoffTypes []fmt.Stringer
    50  			}{BackoffTypes: []fmt.Stringer{
    51  				stringutil.MemoizeStr(func() string {
    52  					return "backoff1"
    53  				}),
    54  				stringutil.MemoizeStr(func() string {
    55  					return "backoff2"
    56  				}),
    57  			}},
    58  			ResolveLockTime:   1000000000, // 10^9 ns = 1s
    59  			WriteKeys:         1,
    60  			WriteSize:         1,
    61  			PrewriteRegionNum: 1,
    62  			TxnRetry:          1,
    63  		},
    64  	}
    65  	expected := "Cop_time: 1.003 Process_time: 2.005 Wait_time: 1 Backoff_time: 1 Request_count: 1 Total_keys: 100 Process_keys: 10 Prewrite_time: 1 Commit_time: 1 " +
    66  		"Get_commit_ts_time: 1 Commit_backoff_time: 1 Backoff_types: [backoff1 backoff2] Resolve_lock_time: 1 Local_latch_wait_time: 1 Write_keys: 1 Write_size: 1 Prewrite_region: 1 Txn_retry: 1"
    67  	if str := detail.String(); str != expected {
    68  		t.Errorf("got:\n%s\nexpected:\n%s", str, expected)
    69  	}
    70  	detail = &InterDircDetails{}
    71  	if str := detail.String(); str != "" {
    72  		t.Errorf("got:\n%s\nexpected:\n", str)
    73  	}
    74  }
    75  
    76  func mockInterlockingDirectorateInterDircutionSummary(TimeProcessedNs, NumProducedRows, NumIterations uint64) *fidelpb.InterlockingDirectorateInterDircutionSummary {
    77  	return &fidelpb.InterlockingDirectorateInterDircutionSummary{TimeProcessedNs: &TimeProcessedNs, NumProducedRows: &NumProducedRows,
    78  		NumIterations: &NumIterations, XXX_unrecognized: nil}
    79  }
    80  
    81  func mockInterlockingDirectorateInterDircutionSummaryForTiFlash(TimeProcessedNs, NumProducedRows, NumIterations uint64, InterlockingDirectorateID string) *fidelpb.InterlockingDirectorateInterDircutionSummary {
    82  	return &fidelpb.InterlockingDirectorateInterDircutionSummary{TimeProcessedNs: &TimeProcessedNs, NumProducedRows: &NumProducedRows,
    83  		NumIterations: &NumIterations, InterlockingDirectorateId: &InterlockingDirectorateID, XXX_unrecognized: nil}
    84  }
    85  
    86  func TestCopRuntimeStats(t *testing.T) {
    87  	stats := NewRuntimeStatsDefCausl()
    88  	blockScanID := 1
    89  	aggID := 2
    90  	blockReaderID := 3
    91  	stats.RecordOneCopTask(blockScanID, "8.8.8.8", mockInterlockingDirectorateInterDircutionSummary(1, 1, 1))
    92  	stats.RecordOneCopTask(blockScanID, "8.8.8.9", mockInterlockingDirectorateInterDircutionSummary(2, 2, 2))
    93  	stats.RecordOneCopTask(aggID, "8.8.8.8", mockInterlockingDirectorateInterDircutionSummary(3, 3, 3))
    94  	stats.RecordOneCopTask(aggID, "8.8.8.9", mockInterlockingDirectorateInterDircutionSummary(4, 4, 4))
    95  	if stats.ExistsCopStats(blockScanID) != true {
    96  		t.Fatal("exist")
    97  	}
    98  	cop := stats.GetCopStats(blockScanID)
    99  	if cop.String() != "proc max:2ns, min:1ns, p80:2ns, p95:2ns, iters:3, tasks:2" {
   100  		t.Fatal("block_scan")
   101  	}
   102  	copStats := cop.stats["8.8.8.8"]
   103  	if copStats == nil {
   104  		t.Fatal("cop stats is nil")
   105  	}
   106  	copStats[0].SetRowNum(10)
   107  	copStats[0].Record(time.Second, 10)
   108  	if copStats[0].String() != "time:1.000000001s, loops:2" {
   109  		t.Fatalf("cop stats string is not expect, got: %v", copStats[0].String())
   110  	}
   111  
   112  	if stats.GetCopStats(aggID).String() != "proc max:4ns, min:3ns, p80:4ns, p95:4ns, iters:7, tasks:2" {
   113  		t.Fatal("agg")
   114  	}
   115  	rootStats := stats.GetRootStats(blockReaderID)
   116  	if rootStats == nil {
   117  		t.Fatal("block_reader")
   118  	}
   119  	if stats.ExistsRootStats(blockReaderID) == false {
   120  		t.Fatal("block_reader not exists")
   121  	}
   122  }
   123  
   124  func TestCopRuntimeStatsForTiFlash(t *testing.T) {
   125  	stats := NewRuntimeStatsDefCausl()
   126  	blockScanID := 1
   127  	aggID := 2
   128  	blockReaderID := 3
   129  	stats.RecordOneCopTask(aggID, "8.8.8.8", mockInterlockingDirectorateInterDircutionSummaryForTiFlash(1, 1, 1, "blockscan_"+strconv.Itoa(blockScanID)))
   130  	stats.RecordOneCopTask(aggID, "8.8.8.9", mockInterlockingDirectorateInterDircutionSummaryForTiFlash(2, 2, 2, "blockscan_"+strconv.Itoa(blockScanID)))
   131  	stats.RecordOneCopTask(blockScanID, "8.8.8.8", mockInterlockingDirectorateInterDircutionSummaryForTiFlash(3, 3, 3, "aggregation_"+strconv.Itoa(aggID)))
   132  	stats.RecordOneCopTask(blockScanID, "8.8.8.9", mockInterlockingDirectorateInterDircutionSummaryForTiFlash(4, 4, 4, "aggregation_"+strconv.Itoa(aggID)))
   133  	if stats.ExistsCopStats(blockScanID) != true {
   134  		t.Fatal("exist")
   135  	}
   136  	cop := stats.GetCopStats(blockScanID)
   137  	if cop.String() != "proc max:2ns, min:1ns, p80:2ns, p95:2ns, iters:3, tasks:2" {
   138  		t.Fatal("block_scan")
   139  	}
   140  	copStats := cop.stats["8.8.8.8"]
   141  	if copStats == nil {
   142  		t.Fatal("cop stats is nil")
   143  	}
   144  	copStats[0].SetRowNum(10)
   145  	copStats[0].Record(time.Second, 10)
   146  	if copStats[0].String() != "time:1.000000001s, loops:2" {
   147  		t.Fatalf("cop stats string is not expect, got: %v", copStats[0].String())
   148  	}
   149  
   150  	if stats.GetCopStats(aggID).String() != "proc max:4ns, min:3ns, p80:4ns, p95:4ns, iters:7, tasks:2" {
   151  		t.Fatal("agg")
   152  	}
   153  	rootStats := stats.GetRootStats(blockReaderID)
   154  	if rootStats == nil {
   155  		t.Fatal("block_reader")
   156  	}
   157  	if stats.ExistsRootStats(blockReaderID) == false {
   158  		t.Fatal("block_reader not exists")
   159  	}
   160  }
   161  func TestRuntimeStatsWithCommit(t *testing.T) {
   162  	commitDetail := &CommitDetails{
   163  		GetCommitTsTime:   time.Second,
   164  		PrewriteTime:      time.Second,
   165  		CommitTime:        time.Second,
   166  		CommitBackoffTime: int64(time.Second),
   167  		Mu: struct {
   168  			sync.Mutex
   169  			BackoffTypes []fmt.Stringer
   170  		}{BackoffTypes: []fmt.Stringer{
   171  			stringutil.MemoizeStr(func() string {
   172  				return "backoff1"
   173  			}),
   174  			stringutil.MemoizeStr(func() string {
   175  				return "backoff2"
   176  			}),
   177  			stringutil.MemoizeStr(func() string {
   178  				return "backoff1"
   179  			}),
   180  		}},
   181  		ResolveLockTime:   int64(time.Second),
   182  		WriteKeys:         3,
   183  		WriteSize:         66,
   184  		PrewriteRegionNum: 5,
   185  		TxnRetry:          2,
   186  	}
   187  	stats := &RuntimeStatsWithCommit{
   188  		Commit: commitDetail,
   189  	}
   190  	expect := "commit_txn: {prewrite:1s, get_commit_ts:1s, commit:1s, backoff: {time: 1s, type: [backoff1 backoff2]}, resolve_lock: 1s, region_num:5, write_keys:3, write_byte:66, txn_retry:2}"
   191  	if stats.String() != expect {
   192  		t.Fatalf("%v != %v", stats.String(), expect)
   193  	}
   194  	lockDetail := &LockKeysDetails{
   195  		TotalTime:       time.Second,
   196  		RegionNum:       2,
   197  		LockKeys:        10,
   198  		ResolveLockTime: int64(time.Second * 2),
   199  		BackoffTime:     int64(time.Second * 3),
   200  		Mu: struct {
   201  			sync.Mutex
   202  			BackoffTypes []fmt.Stringer
   203  		}{BackoffTypes: []fmt.Stringer{
   204  			stringutil.MemoizeStr(func() string {
   205  				return "backoff4"
   206  			}),
   207  			stringutil.MemoizeStr(func() string {
   208  				return "backoff5"
   209  			}),
   210  			stringutil.MemoizeStr(func() string {
   211  				return "backoff5"
   212  			}),
   213  		}},
   214  		LockRPCTime:  int64(time.Second * 5),
   215  		LockRPCCount: 50,
   216  		RetryCount:   2,
   217  	}
   218  	stats = &RuntimeStatsWithCommit{
   219  		LockKeys: lockDetail,
   220  	}
   221  	expect = "lock_keys: {time:1s, region:2, keys:10, resolve_lock:2s, backoff: {time: 3s, type: [backoff4 backoff5]}, lock_rpc:5s, rpc_count:50, retry_count:2}"
   222  	if stats.String() != expect {
   223  		t.Fatalf("%v != %v", stats.String(), expect)
   224  	}
   225  }
   226  
   227  func TestRootRuntimeStats(t *testing.T) {
   228  	basic1 := &BasicRuntimeStats{}
   229  	basic2 := &BasicRuntimeStats{}
   230  	basic1.Record(time.Second, 20)
   231  	basic2.Record(time.Second*2, 30)
   232  	pid := 1
   233  	stmtStats := NewRuntimeStatsDefCausl()
   234  	stmtStats.RegisterStats(pid, basic1)
   235  	stmtStats.RegisterStats(pid, basic2)
   236  	concurrency := &RuntimeStatsWithConcurrencyInfo{}
   237  	concurrency.SetConcurrencyInfo(NewConcurrencyInfo("worker", 15))
   238  	stmtStats.RegisterStats(pid, concurrency)
   239  	commitDetail := &CommitDetails{
   240  		GetCommitTsTime:   time.Second,
   241  		PrewriteTime:      time.Second,
   242  		CommitTime:        time.Second,
   243  		WriteKeys:         3,
   244  		WriteSize:         66,
   245  		PrewriteRegionNum: 5,
   246  		TxnRetry:          2,
   247  	}
   248  	stmtStats.RegisterStats(pid, &RuntimeStatsWithCommit{
   249  		Commit: commitDetail,
   250  	})
   251  	concurrency = &RuntimeStatsWithConcurrencyInfo{}
   252  	concurrency.SetConcurrencyInfo(NewConcurrencyInfo("concurrent", 0))
   253  	stmtStats.RegisterStats(pid, concurrency)
   254  	stats := stmtStats.GetRootStats(1)
   255  	expect := "time:3s, loops:2, worker:15, concurrent:OFF, commit_txn: {prewrite:1s, get_commit_ts:1s, commit:1s, region_num:5, write_keys:3, write_byte:66, txn_retry:2}"
   256  	if stats.String() != expect {
   257  		t.Fatalf("%v != %v", stats.String(), expect)
   258  	}
   259  }