Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,8 @@ type Cmdable interface {
GeoHash(ctx context.Context, key string, members ...string) *StringSliceCmd

ACLDryRun(ctx context.Context, username string, command ...interface{}) *StringCmd

ModuleLoadex(ctx context.Context, conf *ModuleLoadexConfig) *StringCmd
}

type StatefulCmdable interface {
Expand Down Expand Up @@ -3888,3 +3890,32 @@ func (c cmdable) ACLDryRun(ctx context.Context, username string, command ...inte
_ = c(ctx, cmd)
return cmd
}

// ModuleLoadexConfig struct is used to specify the arguments for the MODULE LOADEX command of redis.
// `MODULE LOADEX path [CONFIG name value [CONFIG name value ...]] [ARGS args [args ...]]`
type ModuleLoadexConfig struct {
Path string
Conf map[string]interface{}
Args []interface{}
}

func (c *ModuleLoadexConfig) toArgs() []interface{} {
args := make([]interface{}, 3, 3+len(c.Conf)*3+len(c.Args)*2)
args[0] = "MODULE"
args[1] = "LOADEX"
args[2] = c.Path
for k, v := range c.Conf {
args = append(args, "CONFIG", k, v)
}
for _, arg := range c.Args {
args = append(args, "ARGS", arg)
}
return args
}

// ModuleLoadex Redis `MODULE LOADEX path [CONFIG name value [CONFIG name value ...]] [ARGS args [args ...]]` command.
func (c cmdable) ModuleLoadex(ctx context.Context, conf *ModuleLoadexConfig) *StringCmd {
cmd := NewStringCmd(ctx, conf.toArgs()...)
_ = c(ctx, cmd)
return cmd
}
50 changes: 49 additions & 1 deletion commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1926,11 +1926,59 @@ var _ = Describe("Commands", func() {
Expect(replace.Val()).To(Equal(int64(1)))
})

It("should acl dryryn", func() {
It("should acl dryrun", func() {
dryRun := client.ACLDryRun(ctx, "default", "get", "randomKey")
Expect(dryRun.Err()).NotTo(HaveOccurred())
Expect(dryRun.Val()).To(Equal("OK"))
})

It("should fail module loadex", func() {
dryRun := client.ModuleLoadex(ctx, &redis.ModuleLoadexConfig{
Path: "/path/to/non-existent-library.so",
Conf: map[string]interface{}{
"param1": "value1",
},
Args: []interface{}{
"arg1",
},
})
Expect(dryRun.Err()).To(HaveOccurred())
Expect(dryRun.Err().Error()).To(Equal("ERR Error loading the extension. Please check the server logs."))
})

It("converts the module loadex configuration to a slice of arguments correctly", func() {
conf := &redis.ModuleLoadexConfig{
Path: "/path/to/your/module.so",
Conf: map[string]interface{}{
"param1": "value1",
},
Args: []interface{}{
"arg1",
"arg2",
3,
},
}

args := conf.ToArgs()

// Test if the arguments are in the correct order
expectedArgs := []interface{}{
"MODULE",
"LOADEX",
"/path/to/your/module.so",
"CONFIG",
"param1",
"value1",
"ARGS",
"arg1",
"ARGS",
"arg2",
"ARGS",
3,
}

Expect(args).To(Equal(expectedArgs))
})
})

Describe("hashes", func() {
Expand Down
4 changes: 4 additions & 0 deletions export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,7 @@ func (c *Ring) ShardByName(name string) *ringShard {
shard, _ := c.sharding.GetByName(name)
return shard
}

func (c *ModuleLoadexConfig) ToArgs() []interface{} {
return c.toArgs()
}
2 changes: 1 addition & 1 deletion main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ func startRedis(port string, args ...string) (*redisProcess, error) {
return nil, err
}

baseArgs := []string{filepath.Join(dir, "redis.conf"), "--port", port, "--dir", dir}
baseArgs := []string{filepath.Join(dir, "redis.conf"), "--port", port, "--dir", dir, "--enable-module-command", "yes"}
process, err := execCmd(redisServerBin, append(baseArgs, args...)...)
if err != nil {
return nil, err
Expand Down