package vm

import (
	"os"
	"sort"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/pingcap-inc/clinic/pkg/ngm/topsql/api"
)

func TestExtractTopK(t *testing.T) {
	body, err := os.ReadFile("testdata/response-topk.json")
	require.NoError(t, err)

	topk, err := extractTopk(body)
	require.NoError(t, err)

	require.Equal(t, topk, []string{"D9E855C725C2395CC09E14C2B85329D88B3D0EA5CDA0450244CDDD2642C15B91", "EA4709893FFB8EDC8D58191CCBD93C4C4FDFC1D20EBBCC7F48707DF328D6DBB2", "DD8E923753C67EE00941D41C2200E15983D39A18BC80A7C73FCE4CA35596CEE9", "708208881EC34B5A3DC00B47D8CD139478174F50BA6B528E347F8808B130833F", "3FC273F5BE63150DD81D9B509FC4F6DD0E1CB73DD146BF6663D4A7FE3CBA5D3B"})
}

func TestExtractCPUTime(t *testing.T) {
	body, err := os.ReadFile("testdata/response-cputime.json")
	require.NoError(t, err)

	got, err := extractCPUTime(body)
	require.NoError(t, err)

	expected := cpuTimesMap{
		{Digest: "D9E855C725C2395CC09E14C2B85329D88B3D0EA5CDA0450244CDDD2642C15B91"}: map[planDigest]cpuTimes{
			"C02D2E5F27CBCC1AF73C0DC9A15E45DB0F2603342215B12DDFA2BFF448BCCE2F": {
				TimestampSec: []uint64{1664269812, 1664269821, 1664269830, 1664269839, 1664269848, 1664269857, 1664269866, 1664269875, 1664269884, 1664269893, 1664269902, 1664269911, 1664269920, 1664269929, 1664269938, 1664269947, 1664269956, 1664269965, 1664269974, 1664269983, 1664269992, 1664270001, 1664270010, 1664270019, 1664270028, 1664270037, 1664270046, 1664270055, 1664270064, 1664270073, 1664270082, 1664270091, 1664270100, 1664270109, 1664270118, 1664270127, 1664270136, 1664270145, 1664270154, 1664270163, 1664270172, 1664270181, 1664270190, 1664270199, 1664270208, 1664270217, 1664270226, 1664270235, 1664270244, 1664270253, 1664270262, 1664270271, 1664270280, 1664270289, 1664270298, 1664270307, 1664270316, 1664270325, 1664270334, 1664270343, 1664270352, 1664270361, 1664270370, 1664270379, 1664270388, 1664270397, 1664270406, 1664270415, 1664270424, 1664270433, 1664270442, 1664270451, 1664270460, 1664270469, 1664270478, 1664270487, 1664270496, 1664270505, 1664270514, 1664270523, 1664270532, 1664270541, 1664270550, 1664270559, 1664270568, 1664270577, 1664270586, 1664270595, 1664270604, 1664270613, 1664270622, 1664270631, 1664270640, 1664270649, 1664270658, 1664270667, 1664270676, 1664270685, 1664270694, 1664270703, 1664270712, 1664270721, 1664270730, 1664270739, 1664270748, 1664270757, 1664270766, 1664270775, 1664270784, 1664270793, 1664270802, 1664270811, 1664270820, 1664270829, 1664270838, 1664270847, 1664270856, 1664270865, 1664270874, 1664270883, 1664270892, 1664270901, 1664270910, 1664270919, 1664270928, 1664270937, 1664270946, 1664270955, 1664270964, 1664270973, 1664270982, 1664270991, 1664271000, 1664271009, 1664271018, 1664271027, 1664271036, 1664271045, 1664271054, 1664271063, 1664271072, 1664271081, 1664271090, 1664271099, 1664271108, 1664271117, 1664271126, 1664271135, 1664271144, 1664271153, 1664271162, 1664271171, 1664271180, 1664271189, 1664271198, 1664271207, 1664271216, 1664271225, 1664271234, 1664271243, 1664271252, 1664271261, 1664271270, 1664271279, 1664271288, 1664271297, 1664271306, 1664271315, 1664271324, 1664271333, 1664271342, 1664271351, 1664271360, 1664271369, 1664271378, 1664271387, 1664271396, 1664271414, 1664271423, 1664271432, 1664271441, 1664271450, 1664271459, 1664271468, 1664271477, 1664271486, 1664271495, 1664271504, 1664271513, 1664271522, 1664271531, 1664271540, 1664271549, 1664271558, 1664271567, 1664271576, 1664271585, 1664271594, 1664271603, 1664271612},
				CPUTimeMs:    []uint64{50, 10, 90, 10, 60, 60, 60, 80, 40, 80, 50, 60, 20, 50, 100, 60, 30, 70, 20, 40, 30, 70, 50, 110, 50, 40, 30, 50, 70, 30, 30, 30, 80, 50, 60, 50, 50, 80, 60, 60, 30, 40, 30, 10, 50, 30, 60, 40, 40, 40, 60, 40, 60, 80, 10, 60, 30, 60, 40, 80, 80, 20, 60, 60, 30, 30, 100, 50, 20, 80, 80, 60, 60, 50, 40, 70, 90, 70, 40, 60, 60, 50, 50, 120, 30, 50, 20, 30, 50, 60, 90, 20, 40, 80, 90, 60, 60, 100, 70, 50, 50, 30, 30, 70, 20, 100, 60, 60, 90, 80, 50, 50, 20, 50, 40, 60, 50, 40, 20, 40, 50, 50, 100, 20, 90, 40, 80, 40, 70, 90, 40, 50, 20, 30, 80, 90, 80, 60, 40, 50, 80, 20, 50, 70, 40, 80, 40, 60, 60, 40, 70, 60, 20, 30, 60, 60, 40, 50, 20, 60, 40, 60, 30, 30, 40, 70, 50, 70, 60, 100, 90, 40, 70, 30, 30, 60, 50, 40, 20, 20, 50, 50, 50, 40, 40, 30, 40, 40, 40, 30, 70, 50, 30, 70, 30, 50, 30, 70, 30, 30},
			},
		},
		{Digest: "EA4709893FFB8EDC8D58191CCBD93C4C4FDFC1D20EBBCC7F48707DF328D6DBB2"}: map[planDigest]cpuTimes{
			"42D48B331DFE53300DDEA68D4217DC467244BD898F80F10A913F2104D26D4989": {
				TimestampSec: []uint64{1664269812, 1664269821, 1664269839, 1664269866, 1664269875, 1664269884, 1664269893, 1664269902, 1664269911, 1664269929, 1664269938, 1664269956, 1664269965, 1664269974, 1664269983, 1664270001, 1664270010, 1664270019, 1664270028, 1664270037, 1664270046, 1664270055, 1664270073, 1664270091, 1664270100, 1664270118, 1664270127, 1664270163, 1664270181, 1664270208, 1664270217, 1664270226, 1664270244, 1664270280, 1664270289, 1664270307, 1664270325, 1664270343, 1664270361, 1664270370, 1664270406, 1664270442, 1664270451, 1664270460, 1664270478, 1664270514, 1664270550, 1664270559, 1664270568, 1664270577, 1664270604, 1664270613, 1664270622, 1664270640, 1664270676, 1664270703, 1664270739, 1664270748, 1664270757, 1664270766, 1664270775, 1664270793, 1664270802, 1664270811, 1664270829, 1664270838, 1664270856, 1664270865, 1664270883, 1664270991, 1664271000, 1664271009, 1664271063, 1664271081, 1664271099, 1664271108, 1664271126, 1664271135, 1664271144, 1664271153, 1664271162, 1664271243, 1664271270, 1664271279, 1664271288, 1664271315, 1664271324, 1664271387, 1664271396, 1664271423, 1664271432, 1664271441, 1664271450, 1664271459, 1664271468, 1664271486, 1664271513, 1664271522, 1664271531, 1664271540, 1664271549, 1664271603},
				CPUTimeMs:    []uint64{30, 10, 20, 10, 20, 10, 10, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 10, 10, 10, 10, 10, 10, 20, 10, 10, 20, 20, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 20, 10, 10, 20, 10, 10, 30, 10, 10, 10, 10, 20, 20, 20, 10, 10, 20, 30, 20, 30, 10, 20, 20, 10, 10, 20, 10, 20, 20, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 10, 20, 10, 10, 20, 10, 10, 10, 10, 10, 20, 10, 10},
			},
		},
		{Digest: "DD8E923753C67EE00941D41C2200E15983D39A18BC80A7C73FCE4CA35596CEE9"}: map[planDigest]cpuTimes{
			"8DC92F66553B89E526DDC08A9B977F48FE8F0FD8ED97985C97DD509BDDE75049": {
				TimestampSec: []uint64{1664269821, 1664269848, 1664269857, 1664269866, 1664269920, 1664269929, 1664269938, 1664269965, 1664270028, 1664270037, 1664270055, 1664270073, 1664270091, 1664270118, 1664270127, 1664270136, 1664270163, 1664270181, 1664270271, 1664270280, 1664270298, 1664270334, 1664270343, 1664270361, 1664270370, 1664270397, 1664270424, 1664270433, 1664270442, 1664270451, 1664270469, 1664270505, 1664270514, 1664270523, 1664270532, 1664270559, 1664270568, 1664270577, 1664270586, 1664270604, 1664270622, 1664270640, 1664270694, 1664270712, 1664270721, 1664270748, 1664270766, 1664270802, 1664270811, 1664270820, 1664270829, 1664270847, 1664270856, 1664270874, 1664270883, 1664270928, 1664270937, 1664270964, 1664270982, 1664271009, 1664271027, 1664271036, 1664271072, 1664271090, 1664271099, 1664271108, 1664271126, 1664271144, 1664271162, 1664271171, 1664271180, 1664271189, 1664271216, 1664271225, 1664271261, 1664271279, 1664271306, 1664271360, 1664271369, 1664271387, 1664271405, 1664271414, 1664271432, 1664271459, 1664271468, 1664271495, 1664271504, 1664271540, 1664271558, 1664271585},
				CPUTimeMs:    []uint64{20, 20, 10, 20, 20, 10, 20, 10, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 10, 50, 10, 20, 10, 10, 10, 20, 20, 10, 20, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 20, 10, 20, 10, 30, 10, 10, 10, 10, 10, 20, 10, 20, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 10, 30, 10},
			},
		},
		{Digest: "3FC273F5BE63150DD81D9B509FC4F6DD0E1CB73DD146BF6663D4A7FE3CBA5D3B"}: map[planDigest]cpuTimes{
			"91FB53C50082C3177F52A6DD73D9890DDB67C8952EEF1939651B232B17C0F2EB": {
				TimestampSec: []uint64{1664269857, 1664269920, 1664269929, 1664269947, 1664269965, 1664269974, 1664269992, 1664270001, 1664270019, 1664270064, 1664270091, 1664270109, 1664270127, 1664270136, 1664270154, 1664270163, 1664270190, 1664270199, 1664270208, 1664270217, 1664270226, 1664270253, 1664270262, 1664270271, 1664270298, 1664270307, 1664270325, 1664270334, 1664270361, 1664270370, 1664270379, 1664270388, 1664270397, 1664270433, 1664270442, 1664270478, 1664270487, 1664270505, 1664270523, 1664270532, 1664270550, 1664270559, 1664270568, 1664270577, 1664270586, 1664270604, 1664270613, 1664270649, 1664270703, 1664270739, 1664270766, 1664270802, 1664270820, 1664270829, 1664270865, 1664270874, 1664270883, 1664270901, 1664270928, 1664270937, 1664270982, 1664271009, 1664271027, 1664271036, 1664271054, 1664271063, 1664271081, 1664271090, 1664271117, 1664271126, 1664271144, 1664271162, 1664271198, 1664271216, 1664271225, 1664271234, 1664271243, 1664271297, 1664271315, 1664271324, 1664271342, 1664271387, 1664271396, 1664271441, 1664271486, 1664271495, 1664271504, 1664271513, 1664271522, 1664271531, 1664271576, 1664271594, 1664271603, 1664271612},
				CPUTimeMs:    []uint64{10, 20, 10, 20, 10, 10, 10, 20, 10, 10, 10, 10, 10, 40, 30, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 30, 20, 10, 10, 10, 20, 20, 10, 10, 20, 10, 10, 10, 10, 10, 20, 20, 10, 10, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 20, 10, 10, 10, 10, 20, 20},
			},
		},
		{Digest: "708208881EC34B5A3DC00B47D8CD139478174F50BA6B528E347F8808B130833F"}: map[planDigest]cpuTimes{
			"4948D22A38ACD0D938C850E21C30E240687D1FF74ADB8DA96495B001C48E6B88": {
				TimestampSec: []uint64{1664269821, 1664269830, 1664269848, 1664269857, 1664269875, 1664269884, 1664269893, 1664269902, 1664269911, 1664269929, 1664269947, 1664269956, 1664269974, 1664269983, 1664269992, 1664270001, 1664270019, 1664270046, 1664270109, 1664270118, 1664270172, 1664270181, 1664270208, 1664270262, 1664270271, 1664270280, 1664270316, 1664270325, 1664270352, 1664270370, 1664270388, 1664270397, 1664270415, 1664270424, 1664270433, 1664270460, 1664270505, 1664270559, 1664270577, 1664270586, 1664270595, 1664270613, 1664270658, 1664270667, 1664270676, 1664270694, 1664270721, 1664270730, 1664270748, 1664270757, 1664270766, 1664270784, 1664270829, 1664270847, 1664270910, 1664270919, 1664270955, 1664270973, 1664271000, 1664271009, 1664271018, 1664271036, 1664271054, 1664271063, 1664271072, 1664271081, 1664271099, 1664271135, 1664271144, 1664271162, 1664271171, 1664271189, 1664271198, 1664271225, 1664271234, 1664271270, 1664271279, 1664271297, 1664271306, 1664271333, 1664271396, 1664271441, 1664271468, 1664271486, 1664271522, 1664271558, 1664271594, 1664271603},
				CPUTimeMs:    []uint64{10, 20, 10, 10, 10, 10, 30, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 10, 10, 30, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 10, 10, 20, 10, 10, 10, 20, 20, 10, 10, 20, 50, 20, 10, 10, 10, 20, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 10, 10, 10, 20, 30, 20, 10, 10, 20, 10, 20, 10, 10, 10, 20, 10, 10, 10, 10, 10, 20, 10, 10, 40, 20, 10, 20},
			},
		},
		{IsOther: true}: map[planDigest]cpuTimes{
			"": {
				TimestampSec: []uint64{1664269812, 1664269821, 1664269830, 1664269839, 1664269848, 1664269857, 1664269866, 1664269875, 1664269884, 1664269893, 1664269902, 1664269911, 1664269920, 1664269929, 1664269938, 1664269947, 1664269956, 1664269965, 1664269974, 1664269983, 1664269992, 1664270001, 1664270010, 1664270019, 1664270028, 1664270037, 1664270046, 1664270055, 1664270064, 1664270073, 1664270082, 1664270091, 1664270100, 1664270109, 1664270118, 1664270127, 1664270136, 1664270145, 1664270154, 1664270163, 1664270172, 1664270181, 1664270190, 1664270199, 1664270208, 1664270217, 1664270226, 1664270235, 1664270244, 1664270253, 1664270262, 1664270271, 1664270280, 1664270289, 1664270298, 1664270307, 1664270316, 1664270325, 1664270334, 1664270343, 1664270352, 1664270361, 1664270370, 1664270379, 1664270388, 1664270397, 1664270406, 1664270415, 1664270424, 1664270433, 1664270442, 1664270451, 1664270460, 1664270469, 1664270478, 1664270487, 1664270496, 1664270505, 1664270514, 1664270523, 1664270532, 1664270541, 1664270550, 1664270559, 1664270568, 1664270577, 1664270586, 1664270595, 1664270604, 1664270613, 1664270622, 1664270631, 1664270640, 1664270649, 1664270658, 1664270667, 1664270676, 1664270685, 1664270694, 1664270703, 1664270712, 1664270721, 1664270730, 1664270739, 1664270748, 1664270757, 1664270766, 1664270775, 1664270784, 1664270793, 1664270802, 1664270811, 1664270820, 1664270829, 1664270838, 1664270847, 1664270856, 1664270865, 1664270874, 1664270883, 1664270892, 1664270901, 1664270910, 1664270919, 1664270928, 1664270937, 1664270946, 1664270955, 1664270964, 1664270973, 1664270982, 1664270991, 1664271000, 1664271009, 1664271018, 1664271027, 1664271036, 1664271045, 1664271054, 1664271063, 1664271072, 1664271081, 1664271090, 1664271099, 1664271108, 1664271117, 1664271126, 1664271135, 1664271144, 1664271153, 1664271162, 1664271171, 1664271180, 1664271189, 1664271198, 1664271207, 1664271216, 1664271225, 1664271234, 1664271243, 1664271252, 1664271261, 1664271270, 1664271279, 1664271288, 1664271297, 1664271306, 1664271315, 1664271324, 1664271333, 1664271342, 1664271351, 1664271360, 1664271369, 1664271378, 1664271387, 1664271396, 1664271405, 1664271414, 1664271423, 1664271432, 1664271441, 1664271450, 1664271459, 1664271468, 1664271477, 1664271486, 1664271495, 1664271504, 1664271513, 1664271522, 1664271531, 1664271540, 1664271549, 1664271558, 1664271567, 1664271576, 1664271585, 1664271594, 1664271603, 1664271612},
				CPUTimeMs:    []uint64{70, 30, 60, 100, 90, 60, 50, 50, 60, 30, 70, 60, 60, 50, 20, 50, 60, 80, 50, 30, 80, 50, 80, 30, 40, 40, 40, 50, 90, 80, 50, 60, 10, 20, 40, 60, 40, 50, 60, 40, 50, 40, 30, 60, 30, 40, 20, 60, 20, 80, 60, 30, 30, 40, 70, 130, 60, 60, 70, 20, 60, 70, 30, 80, 40, 60, 40, 70, 80, 50, 50, 40, 50, 40, 30, 90, 90, 30, 50, 90, 50, 30, 50, 30, 20, 20, 30, 60, 80, 60, 30, 30, 50, 10, 30, 20, 60, 50, 60, 20, 80, 60, 80, 30, 40, 60, 50, 20, 70, 10, 20, 60, 70, 60, 90, 20, 20, 50, 60, 50, 50, 20, 80, 60, 30, 60, 80, 70, 70, 80, 40, 60, 40, 20, 30, 50, 30, 60, 40, 60, 30, 60, 120, 40, 30, 50, 30, 80, 20, 60, 50, 100, 60, 40, 40, 90, 60, 30, 50, 60, 60, 10, 120, 20, 30, 30, 70, 40, 70, 20, 20, 60, 10, 40, 50, 50, 30, 80, 80, 50, 10, 40, 80, 70, 60, 50, 60, 50, 50, 40, 50, 40, 40, 80, 20, 40, 30, 60, 40, 70, 70},
			},
		},
	}
	require.Equal(t, got, expected)
}

func TestExtractSummary(t *testing.T) {
	body, err := os.ReadFile("testdata/response-summary.json")
	require.NoError(t, err)

	got, err := extractSummary(body)
	require.NoError(t, err)

	expected := summaryMap{
		{Digest: "D9E855C725C2395CC09E14C2B85329D88B3D0EA5CDA0450244CDDD2642C15B91"}: {
			CPUTimeMs:         10400,
			ExecCountPerSec:   0.0016666666666666668,
			DurationPerExecMs: 2.5118483333333335,
			PlanSummaryMap: map[planDigest]planSummary{
				"C02D2E5F27CBCC1AF73C0DC9A15E45DB0F2603342215B12DDFA2BFF448BCCE2F": {
					ExecCountPerSec:   0.0016666666666666668,
					DurationPerExecMs: 2.5118483333333335,
				},
			},
		},
		{Digest: "EA4709893FFB8EDC8D58191CCBD93C4C4FDFC1D20EBBCC7F48707DF328D6DBB2"}: {
			CPUTimeMs:         1360,
			ExecCountPerSec:   0.335,
			DurationPerExecMs: 8.666877470978442,
			PlanSummaryMap: map[planDigest]planSummary{
				"42D48B331DFE53300DDEA68D4217DC467244BD898F80F10A913F2104D26D4989": {
					ExecCountPerSec:   0.335,
					DurationPerExecMs: 8.666877470978442,
				},
			},
		},
		{Digest: "DD8E923753C67EE00941D41C2200E15983D39A18BC80A7C73FCE4CA35596CEE9"}: {
			CPUTimeMs:         1240,
			ExecCountPerSec:   2.1016666666666666,
			DurationPerExecMs: 2.2403764134284962,
			PlanSummaryMap: map[planDigest]planSummary{
				"8DC92F66553B89E526DDC08A9B977F48FE8F0FD8ED97985C97DD509BDDE75049": {
					ExecCountPerSec:   2.1016666666666666,
					DurationPerExecMs: 2.2403764134284962,
				},
			},
		},
		{Digest: "3FC273F5BE63150DD81D9B509FC4F6DD0E1CB73DD146BF6663D4A7FE3CBA5D3B"}: {
			CPUTimeMs:         1170,
			ExecCountPerSec:   2.152222222222222,
			DurationPerExecMs: 1.2170220647909138,
			PlanSummaryMap: map[planDigest]planSummary{
				"91FB53C50082C3177F52A6DD73D9890DDB67C8952EEF1939651B232B17C0F2EB": {
					ExecCountPerSec:   2.152222222222222,
					DurationPerExecMs: 1.2170220647909138,
				},
			},
		},
		{Digest: "708208881EC34B5A3DC00B47D8CD139478174F50BA6B528E347F8808B130833F"}: {
			CPUTimeMs:         1200,
			ExecCountPerSec:   2.1622222222222223,
			DurationPerExecMs: 1.2172117589928058,
			PlanSummaryMap: map[planDigest]planSummary{
				"4948D22A38ACD0D938C850E21C30E240687D1FF74ADB8DA96495B001C48E6B88": {
					ExecCountPerSec:   2.1622222222222223,
					DurationPerExecMs: 1.2172117589928058,
				},
			},
		},
		{IsOther: true}: {
			CPUTimeMs:         10190,
			ExecCountPerSec:   16.817777777777778,
			DurationPerExecMs: 1.5163012283298096,
			PlanSummaryMap: map[planDigest]planSummary{
				"": {
					ExecCountPerSec:   16.817777777777778,
					DurationPerExecMs: 1.5163012283298096,
				},
			},
		},
	}

	require.Equal(t, got, expected)
}

func TestExtractMeta(t *testing.T) {
	body, err := os.ReadFile("testdata/response-meta.json")
	require.NoError(t, err)

	got, err := extractMeta(body)
	require.NoError(t, err)

	expected := metaMap{
		SQLMeta: map[string]string{
			"708208881EC34B5A3DC00B47D8CD139478174F50BA6B528E347F8808B130833F": "select `c` from `sbtest2` where `id` = ?",
			"DD8E923753C67EE00941D41C2200E15983D39A18BC80A7C73FCE4CA35596CEE9": "select `c` from `sbtest4` where `id` = ?",
			"3FC273F5BE63150DD81D9B509FC4F6DD0E1CB73DD146BF6663D4A7FE3CBA5D3B": "select `c` from `sbtest9` where `id` = ?",
			"EA4709893FFB8EDC8D58191CCBD93C4C4FDFC1D20EBBCC7F48707DF328D6DBB2": "select `version` , `table_id` , `modify_count` , `count` from `mysql` . `stats_meta` where `version` > ? order by `version`",
			"D9E855C725C2395CC09E14C2B85329D88B3D0EA5CDA0450244CDDD2642C15B91": "select high_priority `host` , user , `priv` from `mysql` . `global_priv`",
		},
		PlanMeta: map[string]string{
			"4948D22A38ACD0D938C850E21C30E240687D1FF74ADB8DA96495B001C48E6B88": "\tPoint_Get\troot\ttable:sbtest2, handle:?",
			"8DC92F66553B89E526DDC08A9B977F48FE8F0FD8ED97985C97DD509BDDE75049": "\tPoint_Get\troot\ttable:sbtest4, handle:?",
			"91FB53C50082C3177F52A6DD73D9890DDB67C8952EEF1939651B232B17C0F2EB": "\tPoint_Get\troot\ttable:sbtest9, handle:?",
			"42D48B331DFE53300DDEA68D4217DC467244BD898F80F10A913F2104D26D4989": "\tProjection        \troot\tmysql.stats_meta.count, mysql.stats_meta.modify_count, mysql.stats_meta.table_id, mysql.stats_meta.version\n\t└─IndexLookUp     \troot\t\n\t  ├─IndexRangeScan\tcop \ttable:stats_meta, index:idx_ver(version), range:[?,?], keep order:true\n\t  └─TableRowIDScan\tcop \ttable:stats_meta, keep order:false",
			"C02D2E5F27CBCC1AF73C0DC9A15E45DB0F2603342215B12DDFA2BFF448BCCE2F": "\tTableReader    \troot\t\n\t└─TableFullScan\tcop \ttable:global_priv, range:[?,?], keep order:false",
		},
	}
	require.Equal(t, got, expected)
}

func TestBuildResp(t *testing.T) {
	body, err := os.ReadFile("testdata/response-cputime.json")
	require.NoError(t, err)
	cm, err := extractCPUTime(body)
	require.NoError(t, err)

	body, err = os.ReadFile("testdata/response-summary.json")
	require.NoError(t, err)
	sm, err := extractSummary(body)
	require.NoError(t, err)

	planDigestRegex := buildPlanDigestRegex(cm, sm)
	require.Equal(t, planDigestRegex, "C02D2E5F27CBCC1AF73C0DC9A15E45DB0F2603342215B12DDFA2BFF448BCCE2F|42D48B331DFE53300DDEA68D4217DC467244BD898F80F10A913F2104D26D4989|8DC92F66553B89E526DDC08A9B977F48FE8F0FD8ED97985C97DD509BDDE75049|4948D22A38ACD0D938C850E21C30E240687D1FF74ADB8DA96495B001C48E6B88|91FB53C50082C3177F52A6DD73D9890DDB67C8952EEF1939651B232B17C0F2EB")

	body, err = os.ReadFile("testdata/response-meta.json")
	require.NoError(t, err)
	mm, err := extractMeta(body)
	require.NoError(t, err)

	got := buildResp(cm, sm, mm)

	expected := []api.SummaryItem{
		{
			SQLDigest:         "D9E855C725C2395CC09E14C2B85329D88B3D0EA5CDA0450244CDDD2642C15B91",
			SQLText:           "select high_priority `host` , user , `priv` from `mysql` . `global_priv`",
			CPUTimeMs:         10400,
			ExecCountPerSec:   0.0016666666666666668,
			DurationPerExecMs: 2.5118483333333335,
			Plans: []api.SummaryPlanItem{
				{
					ExecCountPerSec:   0.0016666666666666668,
					DurationPerExecMs: 2.5118483333333335,
					PlanDigest:        "C02D2E5F27CBCC1AF73C0DC9A15E45DB0F2603342215B12DDFA2BFF448BCCE2F",
					PlanText:          "\tTableReader    \troot\t\n\t└─TableFullScan\tcop \ttable:global_priv, range:[?,?], keep order:false",
					TimestampSec:      []uint64{1664269812, 1664269821, 1664269830, 1664269839, 1664269848, 1664269857, 1664269866, 1664269875, 1664269884, 1664269893, 1664269902, 1664269911, 1664269920, 1664269929, 1664269938, 1664269947, 1664269956, 1664269965, 1664269974, 1664269983, 1664269992, 1664270001, 1664270010, 1664270019, 1664270028, 1664270037, 1664270046, 1664270055, 1664270064, 1664270073, 1664270082, 1664270091, 1664270100, 1664270109, 1664270118, 1664270127, 1664270136, 1664270145, 1664270154, 1664270163, 1664270172, 1664270181, 1664270190, 1664270199, 1664270208, 1664270217, 1664270226, 1664270235, 1664270244, 1664270253, 1664270262, 1664270271, 1664270280, 1664270289, 1664270298, 1664270307, 1664270316, 1664270325, 1664270334, 1664270343, 1664270352, 1664270361, 1664270370, 1664270379, 1664270388, 1664270397, 1664270406, 1664270415, 1664270424, 1664270433, 1664270442, 1664270451, 1664270460, 1664270469, 1664270478, 1664270487, 1664270496, 1664270505, 1664270514, 1664270523, 1664270532, 1664270541, 1664270550, 1664270559, 1664270568, 1664270577, 1664270586, 1664270595, 1664270604, 1664270613, 1664270622, 1664270631, 1664270640, 1664270649, 1664270658, 1664270667, 1664270676, 1664270685, 1664270694, 1664270703, 1664270712, 1664270721, 1664270730, 1664270739, 1664270748, 1664270757, 1664270766, 1664270775, 1664270784, 1664270793, 1664270802, 1664270811, 1664270820, 1664270829, 1664270838, 1664270847, 1664270856, 1664270865, 1664270874, 1664270883, 1664270892, 1664270901, 1664270910, 1664270919, 1664270928, 1664270937, 1664270946, 1664270955, 1664270964, 1664270973, 1664270982, 1664270991, 1664271000, 1664271009, 1664271018, 1664271027, 1664271036, 1664271045, 1664271054, 1664271063, 1664271072, 1664271081, 1664271090, 1664271099, 1664271108, 1664271117, 1664271126, 1664271135, 1664271144, 1664271153, 1664271162, 1664271171, 1664271180, 1664271189, 1664271198, 1664271207, 1664271216, 1664271225, 1664271234, 1664271243, 1664271252, 1664271261, 1664271270, 1664271279, 1664271288, 1664271297, 1664271306, 1664271315, 1664271324, 1664271333, 1664271342, 1664271351, 1664271360, 1664271369, 1664271378, 1664271387, 1664271396, 1664271414, 1664271423, 1664271432, 1664271441, 1664271450, 1664271459, 1664271468, 1664271477, 1664271486, 1664271495, 1664271504, 1664271513, 1664271522, 1664271531, 1664271540, 1664271549, 1664271558, 1664271567, 1664271576, 1664271585, 1664271594, 1664271603, 1664271612},
					CPUTimeMs:         []uint64{50, 10, 90, 10, 60, 60, 60, 80, 40, 80, 50, 60, 20, 50, 100, 60, 30, 70, 20, 40, 30, 70, 50, 110, 50, 40, 30, 50, 70, 30, 30, 30, 80, 50, 60, 50, 50, 80, 60, 60, 30, 40, 30, 10, 50, 30, 60, 40, 40, 40, 60, 40, 60, 80, 10, 60, 30, 60, 40, 80, 80, 20, 60, 60, 30, 30, 100, 50, 20, 80, 80, 60, 60, 50, 40, 70, 90, 70, 40, 60, 60, 50, 50, 120, 30, 50, 20, 30, 50, 60, 90, 20, 40, 80, 90, 60, 60, 100, 70, 50, 50, 30, 30, 70, 20, 100, 60, 60, 90, 80, 50, 50, 20, 50, 40, 60, 50, 40, 20, 40, 50, 50, 100, 20, 90, 40, 80, 40, 70, 90, 40, 50, 20, 30, 80, 90, 80, 60, 40, 50, 80, 20, 50, 70, 40, 80, 40, 60, 60, 40, 70, 60, 20, 30, 60, 60, 40, 50, 20, 60, 40, 60, 30, 30, 40, 70, 50, 70, 60, 100, 90, 40, 70, 30, 30, 60, 50, 40, 20, 20, 50, 50, 50, 40, 40, 30, 40, 40, 40, 30, 70, 50, 30, 70, 30, 50, 30, 70, 30, 30},
				},
			},
		},
		{
			SQLDigest:         "3FC273F5BE63150DD81D9B509FC4F6DD0E1CB73DD146BF6663D4A7FE3CBA5D3B",
			SQLText:           "select `c` from `sbtest9` where `id` = ?",
			CPUTimeMs:         1170,
			ExecCountPerSec:   2.152222222222222,
			DurationPerExecMs: 1.2170220647909138,
			Plans: []api.SummaryPlanItem{
				{
					ExecCountPerSec:   2.152222222222222,
					DurationPerExecMs: 1.2170220647909138,
					PlanDigest:        "91FB53C50082C3177F52A6DD73D9890DDB67C8952EEF1939651B232B17C0F2EB",
					PlanText:          "\tPoint_Get\troot\ttable:sbtest9, handle:?",
					TimestampSec:      []uint64{1664269857, 1664269920, 1664269929, 1664269947, 1664269965, 1664269974, 1664269992, 1664270001, 1664270019, 1664270064, 1664270091, 1664270109, 1664270127, 1664270136, 1664270154, 1664270163, 1664270190, 1664270199, 1664270208, 1664270217, 1664270226, 1664270253, 1664270262, 1664270271, 1664270298, 1664270307, 1664270325, 1664270334, 1664270361, 1664270370, 1664270379, 1664270388, 1664270397, 1664270433, 1664270442, 1664270478, 1664270487, 1664270505, 1664270523, 1664270532, 1664270550, 1664270559, 1664270568, 1664270577, 1664270586, 1664270604, 1664270613, 1664270649, 1664270703, 1664270739, 1664270766, 1664270802, 1664270820, 1664270829, 1664270865, 1664270874, 1664270883, 1664270901, 1664270928, 1664270937, 1664270982, 1664271009, 1664271027, 1664271036, 1664271054, 1664271063, 1664271081, 1664271090, 1664271117, 1664271126, 1664271144, 1664271162, 1664271198, 1664271216, 1664271225, 1664271234, 1664271243, 1664271297, 1664271315, 1664271324, 1664271342, 1664271387, 1664271396, 1664271441, 1664271486, 1664271495, 1664271504, 1664271513, 1664271522, 1664271531, 1664271576, 1664271594, 1664271603, 1664271612},
					CPUTimeMs:         []uint64{10, 20, 10, 20, 10, 10, 10, 20, 10, 10, 10, 10, 10, 40, 30, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 30, 20, 10, 10, 10, 20, 20, 10, 10, 20, 10, 10, 10, 10, 10, 20, 20, 10, 10, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 20, 10, 10, 10, 10, 20, 20},
				},
			},
		},
		{
			SQLDigest:         "EA4709893FFB8EDC8D58191CCBD93C4C4FDFC1D20EBBCC7F48707DF328D6DBB2",
			SQLText:           "select `version` , `table_id` , `modify_count` , `count` from `mysql` . `stats_meta` where `version` > ? order by `version`",
			CPUTimeMs:         1360,
			ExecCountPerSec:   0.335,
			DurationPerExecMs: 8.666877470978442,
			Plans: []api.SummaryPlanItem{
				{
					ExecCountPerSec:   0.335,
					DurationPerExecMs: 8.666877470978442,
					PlanDigest:        "42D48B331DFE53300DDEA68D4217DC467244BD898F80F10A913F2104D26D4989",
					PlanText:          "\tProjection        \troot\tmysql.stats_meta.count, mysql.stats_meta.modify_count, mysql.stats_meta.table_id, mysql.stats_meta.version\n\t└─IndexLookUp     \troot\t\n\t  ├─IndexRangeScan\tcop \ttable:stats_meta, index:idx_ver(version), range:[?,?], keep order:true\n\t  └─TableRowIDScan\tcop \ttable:stats_meta, keep order:false",
					TimestampSec:      []uint64{1664269812, 1664269821, 1664269839, 1664269866, 1664269875, 1664269884, 1664269893, 1664269902, 1664269911, 1664269929, 1664269938, 1664269956, 1664269965, 1664269974, 1664269983, 1664270001, 1664270010, 1664270019, 1664270028, 1664270037, 1664270046, 1664270055, 1664270073, 1664270091, 1664270100, 1664270118, 1664270127, 1664270163, 1664270181, 1664270208, 1664270217, 1664270226, 1664270244, 1664270280, 1664270289, 1664270307, 1664270325, 1664270343, 1664270361, 1664270370, 1664270406, 1664270442, 1664270451, 1664270460, 1664270478, 1664270514, 1664270550, 1664270559, 1664270568, 1664270577, 1664270604, 1664270613, 1664270622, 1664270640, 1664270676, 1664270703, 1664270739, 1664270748, 1664270757, 1664270766, 1664270775, 1664270793, 1664270802, 1664270811, 1664270829, 1664270838, 1664270856, 1664270865, 1664270883, 1664270991, 1664271000, 1664271009, 1664271063, 1664271081, 1664271099, 1664271108, 1664271126, 1664271135, 1664271144, 1664271153, 1664271162, 1664271243, 1664271270, 1664271279, 1664271288, 1664271315, 1664271324, 1664271387, 1664271396, 1664271423, 1664271432, 1664271441, 1664271450, 1664271459, 1664271468, 1664271486, 1664271513, 1664271522, 1664271531, 1664271540, 1664271549, 1664271603},
					CPUTimeMs:         []uint64{30, 10, 20, 10, 20, 10, 10, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 10, 10, 10, 10, 10, 10, 20, 10, 10, 20, 20, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 20, 10, 10, 20, 10, 10, 30, 10, 10, 10, 10, 20, 20, 20, 10, 10, 20, 30, 20, 30, 10, 20, 20, 10, 10, 20, 10, 20, 20, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 10, 20, 10, 10, 20, 10, 10, 10, 10, 10, 20, 10, 10},
				},
			},
		},
		{
			SQLDigest:         "DD8E923753C67EE00941D41C2200E15983D39A18BC80A7C73FCE4CA35596CEE9",
			SQLText:           "select `c` from `sbtest4` where `id` = ?",
			CPUTimeMs:         1240,
			ExecCountPerSec:   2.1016666666666666,
			DurationPerExecMs: 2.2403764134284962,
			Plans: []api.SummaryPlanItem{
				{
					ExecCountPerSec:   2.1016666666666666,
					DurationPerExecMs: 2.2403764134284962,
					PlanDigest:        "8DC92F66553B89E526DDC08A9B977F48FE8F0FD8ED97985C97DD509BDDE75049",
					PlanText:          "\tPoint_Get\troot\ttable:sbtest4, handle:?",
					TimestampSec:      []uint64{1664269821, 1664269848, 1664269857, 1664269866, 1664269920, 1664269929, 1664269938, 1664269965, 1664270028, 1664270037, 1664270055, 1664270073, 1664270091, 1664270118, 1664270127, 1664270136, 1664270163, 1664270181, 1664270271, 1664270280, 1664270298, 1664270334, 1664270343, 1664270361, 1664270370, 1664270397, 1664270424, 1664270433, 1664270442, 1664270451, 1664270469, 1664270505, 1664270514, 1664270523, 1664270532, 1664270559, 1664270568, 1664270577, 1664270586, 1664270604, 1664270622, 1664270640, 1664270694, 1664270712, 1664270721, 1664270748, 1664270766, 1664270802, 1664270811, 1664270820, 1664270829, 1664270847, 1664270856, 1664270874, 1664270883, 1664270928, 1664270937, 1664270964, 1664270982, 1664271009, 1664271027, 1664271036, 1664271072, 1664271090, 1664271099, 1664271108, 1664271126, 1664271144, 1664271162, 1664271171, 1664271180, 1664271189, 1664271216, 1664271225, 1664271261, 1664271279, 1664271306, 1664271360, 1664271369, 1664271387, 1664271405, 1664271414, 1664271432, 1664271459, 1664271468, 1664271495, 1664271504, 1664271540, 1664271558, 1664271585},
					CPUTimeMs:         []uint64{20, 20, 10, 20, 20, 10, 20, 10, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 10, 50, 10, 20, 10, 10, 10, 20, 20, 10, 20, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 20, 10, 20, 10, 30, 10, 10, 10, 10, 10, 20, 10, 20, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 10, 30, 10},
				},
			},
		},
		{
			SQLDigest:         "708208881EC34B5A3DC00B47D8CD139478174F50BA6B528E347F8808B130833F",
			SQLText:           "select `c` from `sbtest2` where `id` = ?",
			CPUTimeMs:         1200,
			ExecCountPerSec:   2.1622222222222223,
			DurationPerExecMs: 1.2172117589928058,
			Plans: []api.SummaryPlanItem{
				{
					PlanDigest:        "4948D22A38ACD0D938C850E21C30E240687D1FF74ADB8DA96495B001C48E6B88",
					PlanText:          "\tPoint_Get\troot\ttable:sbtest2, handle:?",
					ExecCountPerSec:   2.1622222222222223,
					DurationPerExecMs: 1.2172117589928058,
					TimestampSec:      []uint64{1664269821, 1664269830, 1664269848, 1664269857, 1664269875, 1664269884, 1664269893, 1664269902, 1664269911, 1664269929, 1664269947, 1664269956, 1664269974, 1664269983, 1664269992, 1664270001, 1664270019, 1664270046, 1664270109, 1664270118, 1664270172, 1664270181, 1664270208, 1664270262, 1664270271, 1664270280, 1664270316, 1664270325, 1664270352, 1664270370, 1664270388, 1664270397, 1664270415, 1664270424, 1664270433, 1664270460, 1664270505, 1664270559, 1664270577, 1664270586, 1664270595, 1664270613, 1664270658, 1664270667, 1664270676, 1664270694, 1664270721, 1664270730, 1664270748, 1664270757, 1664270766, 1664270784, 1664270829, 1664270847, 1664270910, 1664270919, 1664270955, 1664270973, 1664271000, 1664271009, 1664271018, 1664271036, 1664271054, 1664271063, 1664271072, 1664271081, 1664271099, 1664271135, 1664271144, 1664271162, 1664271171, 1664271189, 1664271198, 1664271225, 1664271234, 1664271270, 1664271279, 1664271297, 1664271306, 1664271333, 1664271396, 1664271441, 1664271468, 1664271486, 1664271522, 1664271558, 1664271594, 1664271603},
					CPUTimeMs:         []uint64{10, 20, 10, 10, 10, 10, 30, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 10, 10, 30, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 10, 10, 20, 10, 10, 10, 20, 20, 10, 10, 20, 50, 20, 10, 10, 10, 20, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 10, 10, 10, 20, 30, 20, 10, 10, 20, 10, 20, 10, 10, 10, 20, 10, 10, 10, 10, 10, 20, 10, 10, 40, 20, 10, 20},
				},
			},
		},
		{
			IsOther:           true,
			CPUTimeMs:         10190,
			ExecCountPerSec:   16.817777777777778,
			DurationPerExecMs: 1.5163012283298096,
			Plans: []api.SummaryPlanItem{
				{
					ExecCountPerSec:   16.817777777777778,
					DurationPerExecMs: 1.5163012283298096,
					TimestampSec:      []uint64{1664269812, 1664269821, 1664269830, 1664269839, 1664269848, 1664269857, 1664269866, 1664269875, 1664269884, 1664269893, 1664269902, 1664269911, 1664269920, 1664269929, 1664269938, 1664269947, 1664269956, 1664269965, 1664269974, 1664269983, 1664269992, 1664270001, 1664270010, 1664270019, 1664270028, 1664270037, 1664270046, 1664270055, 1664270064, 1664270073, 1664270082, 1664270091, 1664270100, 1664270109, 1664270118, 1664270127, 1664270136, 1664270145, 1664270154, 1664270163, 1664270172, 1664270181, 1664270190, 1664270199, 1664270208, 1664270217, 1664270226, 1664270235, 1664270244, 1664270253, 1664270262, 1664270271, 1664270280, 1664270289, 1664270298, 1664270307, 1664270316, 1664270325, 1664270334, 1664270343, 1664270352, 1664270361, 1664270370, 1664270379, 1664270388, 1664270397, 1664270406, 1664270415, 1664270424, 1664270433, 1664270442, 1664270451, 1664270460, 1664270469, 1664270478, 1664270487, 1664270496, 1664270505, 1664270514, 1664270523, 1664270532, 1664270541, 1664270550, 1664270559, 1664270568, 1664270577, 1664270586, 1664270595, 1664270604, 1664270613, 1664270622, 1664270631, 1664270640, 1664270649, 1664270658, 1664270667, 1664270676, 1664270685, 1664270694, 1664270703, 1664270712, 1664270721, 1664270730, 1664270739, 1664270748, 1664270757, 1664270766, 1664270775, 1664270784, 1664270793, 1664270802, 1664270811, 1664270820, 1664270829, 1664270838, 1664270847, 1664270856, 1664270865, 1664270874, 1664270883, 1664270892, 1664270901, 1664270910, 1664270919, 1664270928, 1664270937, 1664270946, 1664270955, 1664270964, 1664270973, 1664270982, 1664270991, 1664271000, 1664271009, 1664271018, 1664271027, 1664271036, 1664271045, 1664271054, 1664271063, 1664271072, 1664271081, 1664271090, 1664271099, 1664271108, 1664271117, 1664271126, 1664271135, 1664271144, 1664271153, 1664271162, 1664271171, 1664271180, 1664271189, 1664271198, 1664271207, 1664271216, 1664271225, 1664271234, 1664271243, 1664271252, 1664271261, 1664271270, 1664271279, 1664271288, 1664271297, 1664271306, 1664271315, 1664271324, 1664271333, 1664271342, 1664271351, 1664271360, 1664271369, 1664271378, 1664271387, 1664271396, 1664271405, 1664271414, 1664271423, 1664271432, 1664271441, 1664271450, 1664271459, 1664271468, 1664271477, 1664271486, 1664271495, 1664271504, 1664271513, 1664271522, 1664271531, 1664271540, 1664271549, 1664271558, 1664271567, 1664271576, 1664271585, 1664271594, 1664271603, 1664271612},
					CPUTimeMs:         []uint64{70, 30, 60, 100, 90, 60, 50, 50, 60, 30, 70, 60, 60, 50, 20, 50, 60, 80, 50, 30, 80, 50, 80, 30, 40, 40, 40, 50, 90, 80, 50, 60, 10, 20, 40, 60, 40, 50, 60, 40, 50, 40, 30, 60, 30, 40, 20, 60, 20, 80, 60, 30, 30, 40, 70, 130, 60, 60, 70, 20, 60, 70, 30, 80, 40, 60, 40, 70, 80, 50, 50, 40, 50, 40, 30, 90, 90, 30, 50, 90, 50, 30, 50, 30, 20, 20, 30, 60, 80, 60, 30, 30, 50, 10, 30, 20, 60, 50, 60, 20, 80, 60, 80, 30, 40, 60, 50, 20, 70, 10, 20, 60, 70, 60, 90, 20, 20, 50, 60, 50, 50, 20, 80, 60, 30, 60, 80, 70, 70, 80, 40, 60, 40, 20, 30, 50, 30, 60, 40, 60, 30, 60, 120, 40, 30, 50, 30, 80, 20, 60, 50, 100, 60, 40, 40, 90, 60, 30, 50, 60, 60, 10, 120, 20, 30, 30, 70, 40, 70, 20, 20, 60, 10, 40, 50, 50, 30, 80, 80, 50, 10, 40, 80, 70, 60, 50, 60, 50, 50, 40, 50, 40, 40, 80, 20, 40, 30, 60, 40, 70, 70},
				},
			},
		},
	}

	sort.Slice(got, func(i, j int) bool {
		return got[i].SQLDigest < got[j].SQLDigest
	})
	sort.Slice(expected, func(i, j int) bool {
		return expected[i].SQLDigest < expected[j].SQLDigest
	})
	require.Equal(t, got, expected)
}
