From 4951282c241311d4d8c91cd6be7a4fd4535a2170 Mon Sep 17 00:00:00 2001 From: Anurag Bandyopadhyay Date: Mon, 1 Jul 2024 17:03:23 +0530 Subject: [PATCH] feat: minor increase in rueidiscompat coverage (#583) * feat: 5% increase in command.go coverage * feat: use mock pkg instead of exposing rueidis mock fxn * feat: remove testify/assert from go.mod * feat: add cluster commands tests * feat: cover some more conditions in adapter.go * feat: add local replace directive to go.mod rueidis/mock * feat: run go mod tidy * fix: delete lib2 before creating it again --------- Co-authored-by: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com> --- rueidiscompat/adapter_test.go | 50 +++++++ rueidiscompat/command_test.go | 269 ++++++++++++++++++++++++++++++++++ rueidiscompat/go.mod | 4 + rueidiscompat/go.sum | 2 + 4 files changed, 325 insertions(+) diff --git a/rueidiscompat/adapter_test.go b/rueidiscompat/adapter_test.go index 26f739aa..d11bf281 100644 --- a/rueidiscompat/adapter_test.go +++ b/rueidiscompat/adapter_test.go @@ -162,6 +162,15 @@ func testCluster(resp3 bool) { Expect(err).NotTo(HaveOccurred()) Expect(strings.Split(strings.TrimSpace(nodes), "\n")).To(HaveLen(3)) }) + It("ClusterMeet", func() { + Expect(adapter.ClusterMeet(ctx, "localhost", 8080).Err()).To(MatchError("Invalid node address specified: localhost:8080")) + }) + It("ClusterForget", func() { + Expect(adapter.ClusterForget(ctx, "1").Err()).To(MatchError("Unknown node 1")) + }) + It("ClusterReplicate", func() { + Expect(adapter.ClusterReplicate(ctx, "1").Err()).To(MatchError("Unknown node 1")) + }) It("ClusterInfo", func() { info, err := adapter.ClusterInfo(ctx).Result() Expect(err).NotTo(HaveOccurred()) @@ -8934,6 +8943,11 @@ func testAdapterCache(resp3 bool) { resultAdd, err = adapter.TFunctionLoadArgs(ctx, libCodeWithConfig("lib1"), opt).Result() Expect(err).NotTo(HaveOccurred()) Expect(resultAdd).To(BeEquivalentTo("OK")) + opt.Replace = false + adapter.TFunctionDelete(ctx, libCodeWithConfig("lib2")).Result() + resultAdd, err = adapter.TFunctionLoadArgs(ctx, libCodeWithConfig("lib2"), opt).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(resultAdd).To(BeEquivalentTo("OK")) }) It("should TFunctionList", Label("gears", "tfunctionlist"), func() { resultAdd, err := adapter.TFunctionLoad(ctx, libCode("lib1")).Result() @@ -8946,6 +8960,10 @@ func testAdapterCache(resp3 bool) { resultListArgs, err := adapter.TFunctionListArgs(ctx, opt).Result() Expect(err).NotTo(HaveOccurred()) Expect(resultListArgs[0]["code"]).NotTo(BeEquivalentTo("")) + opt.Library = "VERBOSE" + resultListArgs, err = adapter.TFunctionListArgs(ctx, opt).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(resultListArgs[0]["code"]).NotTo(BeEquivalentTo("")) }) It("should TFCall", Label("gears", "tfcall"), func() { @@ -9156,6 +9174,21 @@ func testAdapterCache(resp3 bool) { Expect(result).To(BeAssignableToTypeOf(BFInfo{})) Expect(result.Capacity).To(BeEquivalentTo(int64(2000))) Expect(result.ExpansionRate).To(BeEquivalentTo(int64(3))) + + options.NonScaling = true + resultInsert, err = adapter.BFInsert(ctx, "testbf2", options, "item1").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(len(resultInsert)).To(BeEquivalentTo(1)) + + exists, err = adapter.BFExists(ctx, "testbf2", "item1").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(exists).To(BeTrue()) + + result, err = adapter.BFInfo(ctx, "testbf2").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(result).To(BeAssignableToTypeOf(BFInfo{})) + Expect(result.Capacity).To(BeEquivalentTo(int64(2000))) + Expect(result.ExpansionRate).To(BeEquivalentTo(int64(0))) }) It("should BFMAdd", Label("bloom", "bfmadd"), func() { @@ -9256,6 +9289,10 @@ func testAdapterCache(resp3 bool) { Expect(result).To(BeAssignableToTypeOf(BFInfo{})) Expect(result.Capacity).To(BeEquivalentTo(int64(2000))) Expect(result.ExpansionRate).To(BeEquivalentTo(int64(3))) + + options.NonScaling = true + err = adapter.BFReserveWithArgs(ctx, "testbf2", options).Err() + Expect(err).To(HaveOccurred()) }) }) @@ -9742,6 +9779,19 @@ func testAdapterCache(resp3 bool) { max, err := adapter.TDigestMax(ctx, "tdigest1").Result() Expect(err).NotTo(HaveOccurred()) Expect(max).To(BeEquivalentTo(float64(140))) + + options.Override = true + err = adapter.TDigestMerge(ctx, "tdigest1", options, "tdigest2", "tdigest3").Err() + Expect(err).NotTo(HaveOccurred()) + + info, err = adapter.TDigestInfo(ctx, "tdigest1").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(info.Observations).To(BeEquivalentTo(int64(20))) + Expect(info.Compression).To(BeEquivalentTo(int64(1000))) + + max, err = adapter.TDigestMax(ctx, "tdigest1").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(max).To(BeEquivalentTo(float64(140))) }) }) }) diff --git a/rueidiscompat/command_test.go b/rueidiscompat/command_test.go index 7d914302..d1a99eb9 100644 --- a/rueidiscompat/command_test.go +++ b/rueidiscompat/command_test.go @@ -34,6 +34,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/redis/rueidis/mock" ) var _ = Describe("Commands", func() { @@ -370,6 +371,14 @@ var _ = Describe("Commands", func() { Expect(cursor).To(Equal(uint64(1))) Expect(cmd.Err()).To(BeNil()) } + { + cmd := &ScanCmd{err: errors.New("invalid error")} + cmd.SetVal([]string{"1"}, 1) + keys, cursor := cmd.Val() + Expect(keys).To(Equal([]string{"1"})) + Expect(cursor).To(Equal(uint64(1))) + Expect(cmd.Err().Error()).To(Equal("invalid error")) + } { cmd := &ZSliceCmd{} cmd.SetVal([]Z{{Score: 1}}) @@ -882,3 +891,263 @@ func TestFormatMs(t *testing.T) { t.Errorf("Test case 2 failed: Expected %d, got %d", expected2, result2) } } + +func TestCommandErrorHandling(t *testing.T) { + mockRes := mock.ErrorResult(errors.New("initial error")) + + tests := []struct { + name string + command func() error + expected string + }{ + { + name: "JSONSliceCmd", + command: func() error { + cmd := newJSONSliceCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "IntPointerSliceCmd", + command: func() error { + cmd := newIntPointerSliceCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "MapStringSliceInterfaceCmd", + command: func() error { + cmd := newMapStringSliceInterfaceCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "TSTimestampValueSliceCmd", + command: func() error { + cmd := newTSTimestampValueSliceCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "MapStringInterfaceCmd", + command: func() error { + cmd := newMapStringInterfaceCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "TSTimestampValueCmd", + command: func() error { + cmd := newTSTimestampValueCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "TDigestInfoCmd", + command: func() error { + cmd := newTDigestInfoCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "MapStringIntCmd", + command: func() error { + cmd := newMapStringIntCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "TopKInfoCmd", + command: func() error { + cmd := newTopKInfoCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "CMSInfoCmd", + command: func() error { + cmd := newCMSInfoCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "CFInfoCmd", + command: func() error { + cmd := newCFInfoCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "ScanDumpCmd", + command: func() error { + cmd := newScanDumpCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "BFInfoCmd", + command: func() error { + cmd := newBFInfoCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "MapStringInterfaceSliceCmd", + command: func() error { + cmd := newMapStringInterfaceSliceCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "FunctionListCmd", + command: func() error { + cmd := newFunctionListCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "CommandsInfoCmd", + command: func() error { + cmd := newCommandsInfoCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "GeoPosCmd", + command: func() error { + cmd := newGeoPosCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "ClusterShardsCmd", + command: func() error { + cmd := newClusterShardsCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "ClusterSlotsCmd", + command: func() error { + cmd := newClusterSlotsCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "TimeCmd", + command: func() error { + cmd := newTimeCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "XInfoConsumersCmd", + command: func() error { + cmd := newXInfoConsumersCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "XInfoStreamFullCmd", + command: func() error { + cmd := newXInfoStreamFullCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "XInfoStreamCmd", + command: func() error { + cmd := newXInfoStreamCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "XInfoGroupsCmd", + command: func() error { + cmd := newXInfoGroupsCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "XAutoClaimCmd", + command: func() error { + cmd := newXAutoClaimCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "XPendingExtCmd", + command: func() error { + cmd := newXPendingExtCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "XPendingCmd", + command: func() error { + cmd := newXPendingCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "StringStructMapCmd", + command: func() error { + cmd := newStringStructMapCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "ZSliceSingleCmd", + command: func() error { + cmd := newZSliceSingleCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + { + name: "ZSliceCmd", + command: func() error { + cmd := newZSliceCmd(mockRes) + return cmd.Err() + }, + expected: "initial error", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.command() + if err == nil || err.Error() != tt.expected { + t.Errorf("Expected error %v, got %v", tt.expected, err) + } + }) + } +} diff --git a/rueidiscompat/go.mod b/rueidiscompat/go.mod index ce121701..27c17d19 100644 --- a/rueidiscompat/go.mod +++ b/rueidiscompat/go.mod @@ -4,10 +4,13 @@ go 1.20 replace github.com/redis/rueidis => ../ +replace github.com/redis/rueidis/mock => ../mock + require ( github.com/onsi/ginkgo/v2 v2.15.0 github.com/onsi/gomega v1.31.1 github.com/redis/rueidis v1.0.40 + github.com/redis/rueidis/mock v1.0.40 ) require ( @@ -15,6 +18,7 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect + go.uber.org/mock v0.3.0 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect diff --git a/rueidiscompat/go.sum b/rueidiscompat/go.sum index fa1bb90c..5bd0f5be 100644 --- a/rueidiscompat/go.sum +++ b/rueidiscompat/go.sum @@ -21,6 +21,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= +go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=