Skip to content

Commit b6c874c

Browse files
author
gongna-au
committed
feat:add latency test
1 parent e9e4ef1 commit b6c874c

1 file changed

Lines changed: 194 additions & 0 deletions

File tree

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package latency
21+
22+
import (
23+
"context"
24+
"fmt"
25+
"testing"
26+
27+
"github.com/apache/kvrocks/tests/gocase/util"
28+
"github.com/stretchr/testify/require"
29+
)
30+
31+
func TestLatencyHelp(t *testing.T) {
32+
srv := util.StartServer(t, map[string]string{})
33+
defer srv.Close()
34+
35+
ctx := context.Background()
36+
rdb := srv.NewClient()
37+
defer func() { require.NoError(t, rdb.Close()) }()
38+
39+
t.Run("LATENCY HELP returns help text", func(t *testing.T) {
40+
result, err := rdb.Do(ctx, "LATENCY", "HELP").StringSlice()
41+
require.NoError(t, err)
42+
require.NotEmpty(t, result)
43+
require.Contains(t, result[0], "HELP")
44+
})
45+
46+
t.Run("LATENCY HELP is case-insensitive", func(t *testing.T) {
47+
result, err := rdb.Do(ctx, "latency", "help").StringSlice()
48+
require.NoError(t, err)
49+
require.NotEmpty(t, result)
50+
})
51+
}
52+
53+
func TestLatencyReset(t *testing.T) {
54+
srv := util.StartServer(t, map[string]string{})
55+
defer srv.Close()
56+
57+
ctx := context.Background()
58+
rdb := srv.NewClient()
59+
defer func() { require.NoError(t, rdb.Close()) }()
60+
61+
t.Run("LATENCY RESET always returns 0", func(t *testing.T) {
62+
val, err := rdb.Do(ctx, "LATENCY", "RESET").Int64()
63+
require.NoError(t, err)
64+
require.EqualValues(t, 0, val)
65+
})
66+
67+
t.Run("LATENCY RESET with event arguments still returns 0", func(t *testing.T) {
68+
val, err := rdb.Do(ctx, "LATENCY", "RESET", "event1", "event2").Int64()
69+
require.NoError(t, err)
70+
require.EqualValues(t, 0, val)
71+
})
72+
}
73+
74+
func TestLatencyErrors(t *testing.T) {
75+
srv := util.StartServer(t, map[string]string{})
76+
defer srv.Close()
77+
78+
ctx := context.Background()
79+
rdb := srv.NewClient()
80+
defer func() { require.NoError(t, rdb.Close()) }()
81+
82+
t.Run("LATENCY without subcommand returns error", func(t *testing.T) {
83+
err := rdb.Do(ctx, "LATENCY").Err()
84+
require.Error(t, err)
85+
})
86+
87+
t.Run("LATENCY with unknown subcommand returns error", func(t *testing.T) {
88+
err := rdb.Do(ctx, "LATENCY", "UNKNOWN").Err()
89+
require.Error(t, err)
90+
require.Contains(t, err.Error(), "Unknown LATENCY subcommand")
91+
})
92+
}
93+
94+
func TestLatencyHistogramWithoutBuckets(t *testing.T) {
95+
srv := util.StartServer(t, map[string]string{})
96+
defer srv.Close()
97+
98+
ctx := context.Background()
99+
rdb := srv.NewClient()
100+
defer func() { require.NoError(t, rdb.Close()) }()
101+
102+
t.Run("LATENCY HISTOGRAM returns empty when histogram-bucket-boundaries is not set", func(t *testing.T) {
103+
result, err := rdb.Do(ctx, "LATENCY", "HISTOGRAM").Slice()
104+
require.NoError(t, err)
105+
require.Empty(t, result)
106+
})
107+
}
108+
109+
func TestLatencyHistogram(t *testing.T) {
110+
srv := util.StartServer(t, map[string]string{
111+
"histogram-bucket-boundaries": "10,20,30,50,100,200,500,1000",
112+
})
113+
defer srv.Close()
114+
115+
ctx := context.Background()
116+
rdb := srv.NewClient()
117+
defer func() { require.NoError(t, rdb.Close()) }()
118+
119+
t.Run("LATENCY HISTOGRAM returns data after running commands", func(t *testing.T) {
120+
for i := 0; i < 10; i++ {
121+
require.NoError(t, rdb.Set(ctx, fmt.Sprintf("key-%d", i), "value", 0).Err())
122+
}
123+
for i := 0; i < 10; i++ {
124+
require.NoError(t, rdb.Get(ctx, fmt.Sprintf("key-%d", i)).Err())
125+
}
126+
127+
result, err := rdb.Do(ctx, "LATENCY", "HISTOGRAM").Slice()
128+
require.NoError(t, err)
129+
require.NotEmpty(t, result)
130+
})
131+
132+
t.Run("LATENCY HISTOGRAM filters by command name", func(t *testing.T) {
133+
for i := 0; i < 5; i++ {
134+
require.NoError(t, rdb.Set(ctx, fmt.Sprintf("filter-key-%d", i), "value", 0).Err())
135+
}
136+
137+
result, err := rdb.Do(ctx, "LATENCY", "HISTOGRAM", "set").Slice()
138+
require.NoError(t, err)
139+
require.NotEmpty(t, result)
140+
141+
cmdName, ok := result[0].(string)
142+
require.True(t, ok)
143+
require.Equal(t, "set", cmdName)
144+
})
145+
146+
t.Run("LATENCY HISTOGRAM for nonexistent command returns empty", func(t *testing.T) {
147+
result, err := rdb.Do(ctx, "LATENCY", "HISTOGRAM", "nonexistent_command").Slice()
148+
require.NoError(t, err)
149+
require.Empty(t, result)
150+
})
151+
152+
t.Run("LATENCY HISTOGRAM is case-insensitive for command names", func(t *testing.T) {
153+
resultLower, err := rdb.Do(ctx, "LATENCY", "HISTOGRAM", "set").Slice()
154+
require.NoError(t, err)
155+
156+
resultUpper, err := rdb.Do(ctx, "LATENCY", "HISTOGRAM", "SET").Slice()
157+
require.NoError(t, err)
158+
159+
require.Equal(t, len(resultLower), len(resultUpper))
160+
})
161+
162+
t.Run("LATENCY HISTOGRAM with multiple command filters", func(t *testing.T) {
163+
require.NoError(t, rdb.Set(ctx, "multi-key", "value", 0).Err())
164+
_, err := rdb.Get(ctx, "multi-key").Result()
165+
require.NoError(t, err)
166+
167+
result, err := rdb.Do(ctx, "LATENCY", "HISTOGRAM", "set", "get").Slice()
168+
require.NoError(t, err)
169+
// RESP2 flattened map: [cmd1, data1, cmd2, data2, ...]
170+
require.GreaterOrEqual(t, len(result), 4)
171+
})
172+
173+
t.Run("LATENCY HISTOGRAM contains calls and histogram_usec fields", func(t *testing.T) {
174+
require.NoError(t, rdb.Set(ctx, "field-check-key", "value", 0).Err())
175+
176+
result, err := rdb.Do(ctx, "LATENCY", "HISTOGRAM", "set").Slice()
177+
require.NoError(t, err)
178+
require.GreaterOrEqual(t, len(result), 2)
179+
180+
innerSlice, ok := result[1].([]interface{})
181+
require.True(t, ok, "expected inner result to be a slice")
182+
require.GreaterOrEqual(t, len(innerSlice), 4)
183+
184+
require.Equal(t, "calls", innerSlice[0])
185+
calls, ok := innerSlice[1].(int64)
186+
require.True(t, ok)
187+
require.Greater(t, calls, int64(0))
188+
189+
require.Equal(t, "histogram_usec", innerSlice[2])
190+
histSlice, ok := innerSlice[3].([]interface{})
191+
require.True(t, ok, "expected histogram_usec value to be a slice")
192+
require.NotEmpty(t, histSlice)
193+
})
194+
}

0 commit comments

Comments
 (0)