Skip to content

Commit b862bf5

Browse files
committed
Merge remote-tracking branch 'origin/master' into ndyakov/state-machine-conn
2 parents 9448059 + f7a8a1c commit b862bf5

File tree

8 files changed

+71
-43
lines changed

8 files changed

+71
-43
lines changed

.github/workflows/spellcheck.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
- name: Checkout
99
uses: actions/checkout@v5
1010
- name: Check Spelling
11-
uses: rojopolis/spellcheck-github-actions@0.52.0
11+
uses: rojopolis/spellcheck-github-actions@0.53.0
1212
with:
1313
config_path: .github/spellcheck-settings.yml
1414
task_name: Markdown

bitmap_commands.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ func (c cmdable) BitPos(ctx context.Context, key string, bit int64, pos ...int64
141141
args[3] = pos[0]
142142
args[4] = pos[1]
143143
default:
144-
panic("too many arguments")
144+
cmd := NewIntCmd(ctx)
145+
cmd.SetErr(errors.New("too many arguments"))
146+
return cmd
145147
}
146148
cmd := NewIntCmd(ctx, args...)
147149
_ = c(ctx, cmd)
@@ -182,7 +184,9 @@ func (c cmdable) BitFieldRO(ctx context.Context, key string, values ...interface
182184
args[0] = "BITFIELD_RO"
183185
args[1] = key
184186
if len(values)%2 != 0 {
185-
panic("BitFieldRO: invalid number of arguments, must be even")
187+
c := NewIntSliceCmd(ctx)
188+
c.SetErr(errors.New("BitFieldRO: invalid number of arguments, must be even"))
189+
return c
186190
}
187191
for i := 0; i < len(values); i += 2 {
188192
args = append(args, "GET", values[i], values[i+1])

commands.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,9 @@ func (c cmdable) MemoryUsage(ctx context.Context, key string, samples ...int) *I
693693
args := []interface{}{"memory", "usage", key}
694694
if len(samples) > 0 {
695695
if len(samples) != 1 {
696-
panic("MemoryUsage expects single sample count")
696+
cmd := NewIntCmd(ctx)
697+
cmd.SetErr(errors.New("MemoryUsage expects single sample count"))
698+
return cmd
697699
}
698700
args = append(args, "SAMPLES", samples[0])
699701
}

commands_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,9 @@ var _ = Describe("Commands", func() {
735735
n, err = client.MemoryUsage(ctx, "foo", 0).Result()
736736
Expect(err).NotTo(HaveOccurred())
737737
Expect(n).NotTo(BeZero())
738+
739+
_, err = client.MemoryUsage(ctx, "foo", 0, 1).Result()
740+
Expect(err).Should(MatchError("MemoryUsage expects single sample count"))
738741
})
739742
})
740743

@@ -1598,6 +1601,9 @@ var _ = Describe("Commands", func() {
15981601
pos, err = client.BitPos(ctx, "mykey", 0, 0, 0).Result()
15991602
Expect(err).NotTo(HaveOccurred())
16001603
Expect(pos).To(Equal(int64(-1)))
1604+
1605+
_, err = client.BitPos(ctx, "mykey", 0, 0, 0, 0, 0).Result()
1606+
Expect(err).Should(MatchError("too many arguments"))
16011607
})
16021608

16031609
It("should BitPosSpan", func() {
@@ -1635,6 +1641,9 @@ var _ = Describe("Commands", func() {
16351641
nn, err = client.BitFieldRO(ctx, "mykey", "u8", 0, "u4", 8, "u4", 12, "u4", 13).Result()
16361642
Expect(err).NotTo(HaveOccurred())
16371643
Expect(nn).To(Equal([]int64{0, 15, 15, 14}))
1644+
1645+
_, err = client.BitFieldRO(ctx, "mykey", "u8", 0, "u4", 8, "u4", 12, "u4").Result()
1646+
Expect(err).Should(MatchError("BitFieldRO: invalid number of arguments, must be even"))
16381647
})
16391648

16401649
It("should Decr", func() {
@@ -5254,6 +5263,9 @@ var _ = Describe("Commands", func() {
52545263
Score: 1,
52555264
Member: "one",
52565265
}}))
5266+
5267+
_, err = client.ZPopMax(ctx, "zset", 10, 11).Result()
5268+
Expect(err).Should(MatchError("too many arguments"))
52575269
})
52585270

52595271
It("should ZPopMin", func() {
@@ -5321,6 +5333,9 @@ var _ = Describe("Commands", func() {
53215333
Score: 3,
53225334
Member: "three",
53235335
}}))
5336+
5337+
_, err = client.ZPopMin(ctx, "zset", 10, 11).Result()
5338+
Expect(err).Should(MatchError("too many arguments"))
53245339
})
53255340

53265341
It("should ZRange", func() {

internal/proto/peek_push_notification_test.go

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func TestPeekPushNotificationName(t *testing.T) {
9595
t.Run("NotPushNotification", func(t *testing.T) {
9696
// Test with regular array instead of push notification
9797
buf := &bytes.Buffer{}
98-
buf.WriteString("*2\r\n$6\r\nMOVING\r\n$4\r\ndata\r\n")
98+
fmt.Fprint(buf, "*2\r\n$6\r\nMOVING\r\n$4\r\ndata\r\n")
9999
reader := NewReader(buf)
100100

101101
_, err := reader.PeekPushNotificationName()
@@ -112,7 +112,7 @@ func TestPeekPushNotificationName(t *testing.T) {
112112
t.Run("InsufficientData", func(t *testing.T) {
113113
// Test with buffer smaller than peek size - this might panic due to bounds checking
114114
buf := &bytes.Buffer{}
115-
buf.WriteString(">")
115+
fmt.Fprint(buf, ">")
116116
reader := NewReader(buf)
117117

118118
func() {
@@ -146,7 +146,7 @@ func TestPeekPushNotificationName(t *testing.T) {
146146
t.Run(fmt.Sprintf("Type_%c", respType), func(t *testing.T) {
147147
buf := &bytes.Buffer{}
148148
buf.WriteByte(respType)
149-
buf.WriteString("test data that fills the buffer completely")
149+
fmt.Fprint(buf, "test data that fills the buffer completely")
150150
reader := NewReader(buf)
151151

152152
_, err := reader.PeekPushNotificationName()
@@ -167,7 +167,7 @@ func TestPeekPushNotificationName(t *testing.T) {
167167
t.Run("ZeroLengthArray", func(t *testing.T) {
168168
// Create push notification with zero elements: >0\r\n
169169
buf := &bytes.Buffer{}
170-
buf.WriteString(">0\r\npadding_data_to_fill_buffer_completely")
170+
fmt.Fprint(buf, ">0\r\npadding_data_to_fill_buffer_completely")
171171
reader := NewReader(buf)
172172

173173
_, err := reader.PeekPushNotificationName()
@@ -209,7 +209,7 @@ func TestPeekPushNotificationName(t *testing.T) {
209209
for _, tc := range corruptedCases {
210210
t.Run(tc.name, func(t *testing.T) {
211211
buf := &bytes.Buffer{}
212-
buf.WriteString(tc.data)
212+
fmt.Fprint(buf, tc.data)
213213
reader := NewReader(buf)
214214

215215
// Some corrupted data might not error but return unexpected results
@@ -230,7 +230,7 @@ func TestPeekPushNotificationName(t *testing.T) {
230230
// Create buffer that is exactly 36 bytes (the peek window size)
231231
buf := &bytes.Buffer{}
232232
// ">1\r\n$4\r\nTEST\r\n" = 14 bytes, need 22 more
233-
buf.WriteString(">1\r\n$4\r\nTEST\r\n1234567890123456789012")
233+
fmt.Fprint(buf, ">1\r\n$4\r\nTEST\r\n1234567890123456789012")
234234
if buf.Len() != 36 {
235235
t.Errorf("Expected buffer length 36, got %d", buf.Len())
236236
}
@@ -295,25 +295,26 @@ func createValidPushNotification(notificationName, data string) *bytes.Buffer {
295295
buf := &bytes.Buffer{}
296296

297297
simpleOrString := rand.Intn(2) == 0
298+
defMsg := fmt.Sprintf("$%d\r\n%s\r\n", len(notificationName), notificationName)
298299

299300
if data == "" {
300301

301302
// Single element notification
302-
buf.WriteString(">1\r\n")
303+
fmt.Fprint(buf, ">1\r\n")
303304
if simpleOrString {
304-
buf.WriteString(fmt.Sprintf("+%s\r\n", notificationName))
305+
fmt.Fprintf(buf, "+%s\r\n", notificationName)
305306
} else {
306-
buf.WriteString(fmt.Sprintf("$%d\r\n%s\r\n", len(notificationName), notificationName))
307+
fmt.Fprint(buf, defMsg)
307308
}
308309
} else {
309310
// Two element notification
310-
buf.WriteString(">2\r\n")
311+
fmt.Fprint(buf, ">2\r\n")
311312
if simpleOrString {
312-
buf.WriteString(fmt.Sprintf("+%s\r\n", notificationName))
313-
buf.WriteString(fmt.Sprintf("+%s\r\n", data))
313+
fmt.Fprintf(buf, "+%s\r\n", notificationName)
314+
fmt.Fprintf(buf, "+%s\r\n", data)
314315
} else {
315-
buf.WriteString(fmt.Sprintf("$%d\r\n%s\r\n", len(notificationName), notificationName))
316-
buf.WriteString(fmt.Sprintf("$%d\r\n%s\r\n", len(notificationName), notificationName))
316+
fmt.Fprint(buf, defMsg)
317+
fmt.Fprint(buf, defMsg)
317318
}
318319
}
319320

@@ -333,14 +334,14 @@ func createPushNotificationWithArgs(notificationName string, args ...string) *by
333334
buf := &bytes.Buffer{}
334335

335336
totalElements := 1 + len(args)
336-
buf.WriteString(fmt.Sprintf(">%d\r\n", totalElements))
337+
fmt.Fprintf(buf, ">%d\r\n", totalElements)
337338

338339
// Write notification name
339-
buf.WriteString(fmt.Sprintf("$%d\r\n%s\r\n", len(notificationName), notificationName))
340+
fmt.Fprintf(buf, "$%d\r\n%s\r\n", len(notificationName), notificationName)
340341

341342
// Write arguments
342343
for _, arg := range args {
343-
buf.WriteString(fmt.Sprintf("$%d\r\n%s\r\n", len(arg), arg))
344+
fmt.Fprintf(buf, "$%d\r\n%s\r\n", len(arg), arg)
344345
}
345346

346347
return buf
@@ -349,8 +350,8 @@ func createPushNotificationWithArgs(notificationName string, args ...string) *by
349350
// createSingleElementPushNotification creates a push notification with single element
350351
func createSingleElementPushNotification(notificationName string) *bytes.Buffer {
351352
buf := &bytes.Buffer{}
352-
buf.WriteString(">1\r\n")
353-
buf.WriteString(fmt.Sprintf("$%d\r\n%s\r\n", len(notificationName), notificationName))
353+
fmt.Fprint(buf, ">1\r\n")
354+
fmt.Fprintf(buf, "$%d\r\n%s\r\n", len(notificationName), notificationName)
354355
return buf
355356
}
356357

internal/proto/reader_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package proto_test
22

33
import (
44
"bytes"
5+
"fmt"
56
"io"
67
"testing"
78

@@ -86,7 +87,7 @@ func TestReader_ReadLine(t *testing.T) {
8687
func benchmarkParseReply(b *testing.B, reply string, wanterr bool) {
8788
buf := new(bytes.Buffer)
8889
for i := 0; i < b.N; i++ {
89-
buf.WriteString(reply)
90+
fmt.Fprint(buf, reply)
9091
}
9192
p := proto.NewReader(buf)
9293
b.ResetTimer()

push/push_test.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -837,14 +837,14 @@ func createFakeRESP3PushNotification(notificationType string, args ...string) *b
837837

838838
// RESP3 Push notification format: ><len>\r\n<elements>\r\n
839839
totalElements := 1 + len(args) // notification type + arguments
840-
buf.WriteString(fmt.Sprintf(">%d\r\n", totalElements))
840+
fmt.Fprintf(buf, ">%d\r\n", totalElements)
841841

842842
// Write notification type as bulk string
843-
buf.WriteString(fmt.Sprintf("$%d\r\n%s\r\n", len(notificationType), notificationType))
843+
fmt.Fprintf(buf, "$%d\r\n%s\r\n", len(notificationType), notificationType)
844844

845845
// Write arguments as bulk strings
846846
for _, arg := range args {
847-
buf.WriteString(fmt.Sprintf("$%d\r\n%s\r\n", len(arg), arg))
847+
fmt.Fprintf(buf, "$%d\r\n%s\r\n", len(arg), arg)
848848
}
849849

850850
return buf
@@ -868,11 +868,11 @@ func createFakeRESP3Array(elements ...string) *bytes.Buffer {
868868
buf := &bytes.Buffer{}
869869

870870
// RESP3 Array format: *<len>\r\n<elements>\r\n
871-
buf.WriteString(fmt.Sprintf("*%d\r\n", len(elements)))
871+
fmt.Fprintf(buf, "*%d\r\n", len(elements))
872872

873873
// Write elements as bulk strings
874874
for _, element := range elements {
875-
buf.WriteString(fmt.Sprintf("$%d\r\n%s\r\n", len(element), element))
875+
fmt.Fprintf(buf, "$%d\r\n%s\r\n", len(element), element)
876876
}
877877

878878
return buf
@@ -881,7 +881,7 @@ func createFakeRESP3Array(elements ...string) *bytes.Buffer {
881881
// createFakeRESP3Error creates a fake RESP3 error
882882
func createFakeRESP3Error(message string) *bytes.Buffer {
883883
buf := &bytes.Buffer{}
884-
buf.WriteString(fmt.Sprintf("-%s\r\n", message))
884+
fmt.Fprintf(buf, "-%s\r\n", message)
885885
return buf
886886
}
887887

@@ -1117,7 +1117,7 @@ func TestProcessorWithFakeBuffer(t *testing.T) {
11171117

11181118
// Create fake RESP3 push notification with no elements
11191119
buf := &bytes.Buffer{}
1120-
buf.WriteString(">0\r\n") // Empty push notification
1120+
fmt.Fprint(buf, ">0\r\n") // Empty push notification
11211121
reader := createReaderWithPrimedBuffer(buf)
11221122

11231123
ctx := context.Background()
@@ -1154,9 +1154,9 @@ func TestProcessorWithFakeBuffer(t *testing.T) {
11541154

11551155
// Create fake RESP3 push notification with integer as first element
11561156
buf := &bytes.Buffer{}
1157-
buf.WriteString(">2\r\n") // 2 elements
1158-
buf.WriteString(":123\r\n") // Integer instead of string
1159-
buf.WriteString("$4\r\ndata\r\n") // String data
1157+
fmt.Fprint(buf, ">2\r\n") // 2 elements
1158+
fmt.Fprint(buf, ":123\r\n") // Integer instead of string
1159+
fmt.Fprint(buf, "$4\r\ndata\r\n") // String data
11601160
reader := proto.NewReader(buf)
11611161

11621162
ctx := context.Background()
@@ -1273,8 +1273,8 @@ func TestVoidProcessorWithFakeBuffer(t *testing.T) {
12731273

12741274
// Create invalid RESP3 data
12751275
buf := &bytes.Buffer{}
1276-
buf.WriteString(">1\r\n") // Push notification with 1 element
1277-
buf.WriteString("invalid\r\n") // Invalid format (should be $<len>\r\n<data>\r\n)
1276+
fmt.Fprint(buf, ">1\r\n") // Push notification with 1 element
1277+
fmt.Fprint(buf, "invalid\r\n") // Invalid format (should be $<len>\r\n<data>\r\n)
12781278
reader := proto.NewReader(buf)
12791279

12801280
ctx := context.Background()
@@ -1332,9 +1332,9 @@ func TestProcessorErrorHandling(t *testing.T) {
13321332

13331333
// Create buffer with corrupted RESP3 data
13341334
buf := &bytes.Buffer{}
1335-
buf.WriteString(">2\r\n") // Says 2 elements
1336-
buf.WriteString("$6\r\nMOVING\r\n") // First element OK
1337-
buf.WriteString("corrupted") // Second element corrupted (no proper format)
1335+
fmt.Fprint(buf, ">2\r\n") // Says 2 elements
1336+
fmt.Fprint(buf, "$6\r\nMOVING\r\n") // First element OK
1337+
fmt.Fprint(buf, "corrupted") // Second element corrupted (no proper format)
13381338
reader := proto.NewReader(buf)
13391339

13401340
ctx := context.Background()
@@ -1360,8 +1360,8 @@ func TestProcessorErrorHandling(t *testing.T) {
13601360

13611361
// Create buffer with partial RESP3 data
13621362
buf := &bytes.Buffer{}
1363-
buf.WriteString(">2\r\n") // Says 2 elements
1364-
buf.WriteString("$6\r\nMOVING\r\n") // First element OK
1363+
fmt.Fprint(buf, ">2\r\n") // Says 2 elements
1364+
fmt.Fprint(buf, "$6\r\nMOVING\r\n") // First element OK
13651365
// Missing second element
13661366
reader := proto.NewReader(buf)
13671367

sortedset_commands.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package redis
22

33
import (
44
"context"
5+
"errors"
56
"strings"
67
"time"
78

@@ -313,7 +314,9 @@ func (c cmdable) ZPopMax(ctx context.Context, key string, count ...int64) *ZSlic
313314
case 1:
314315
args = append(args, count[0])
315316
default:
316-
panic("too many arguments")
317+
cmd := NewZSliceCmd(ctx)
318+
cmd.SetErr(errors.New("too many arguments"))
319+
return cmd
317320
}
318321

319322
cmd := NewZSliceCmd(ctx, args...)
@@ -333,7 +336,9 @@ func (c cmdable) ZPopMin(ctx context.Context, key string, count ...int64) *ZSlic
333336
case 1:
334337
args = append(args, count[0])
335338
default:
336-
panic("too many arguments")
339+
cmd := NewZSliceCmd(ctx)
340+
cmd.SetErr(errors.New("too many arguments"))
341+
return cmd
337342
}
338343

339344
cmd := NewZSliceCmd(ctx, args...)

0 commit comments

Comments
 (0)