Skip to content

Commit

Permalink
Fix: Fix Redis script arguments handling and add unit tests
Browse files Browse the repository at this point in the history
Corrected the handling of arguments in Redis script execution by adjusting the evaluation arguments assignment. Added unit tests to ensure the proper execution and error handling of Redis scripts.

Signed-off-by: Christian Roessner <c@roessner.co>
  • Loading branch information
Christian Roessner committed Oct 24, 2024
1 parent 490053a commit 6921e37
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 8 deletions.
2 changes: 1 addition & 1 deletion server/lua-plugins.d/actions/haveibeenpwnd.lua
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ function nauthilus_call_action(request)
end
]]

local script_result, err_run_script = nauthilus_redis.redis_run_script(script, { redis_key })
local script_result, err_run_script = nauthilus_redis.redis_run_script(script, { redis_key }, {})
nauthilus_util.if_error_raise(err_run_script)

if script_result[1] == "send_mail" then
Expand Down
10 changes: 3 additions & 7 deletions server/lualib/redislib/scripts.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ import (

// executeRedisScript executes a given Lua script on the Redis server with specified keys and arguments.
func executeRedisScript(script string, keys []string, args ...any) (any, error) {
evalArgs := make([]any, len(keys)+len(args))

for i, key := range keys {
evalArgs[i] = key
}
evalArgs := make([]any, len(args))

for i, arg := range args {
evalArgs[len(keys)+i] = arg
Expand All @@ -35,8 +31,8 @@ func RedisRunScript(L *lua.LState) int {
)

script := L.CheckString(1)
keys := L.ToTable(2)
args := L.ToTable(3)
keys := L.CheckTable(2)
args := L.CheckTable(3)

keys.ForEach(func(k, v lua.LValue) {
keyList = append(keyList, v.String())
Expand Down
98 changes: 98 additions & 0 deletions server/lualib/redislib/scripts_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package redislib

import (
"errors"
"testing"

"github.com/croessner/nauthilus/server/rediscli"
"github.com/go-redis/redismock/v9"
"github.com/stretchr/testify/assert"
lua "github.com/yuin/gopher-lua"
)

func TestRedisRunScript(t *testing.T) {
testCases := []struct {
name string
script string
keys []string
args []any
expectErr bool
expectRes string
prepareMockRedis func(mock redismock.ClientMock)
}{
{
name: "ValidScript",
script: "return redis.call('set',KEYS[1],'bar')",
keys: []string{"foo"},
args: []any{},
expectErr: false,
expectRes: "mock result",
prepareMockRedis: func(mock redismock.ClientMock) {
mock.ExpectEval("return redis.call('set',KEYS[1],'bar')", []string{"foo"}).SetVal("mock result")
},
},
{
name: "InvalidScript",
script: "return redis.call('set',KEYS[1])", // missing value for 'set'
keys: []string{"foo"},
args: []any{},
expectErr: true,
expectRes: "",
prepareMockRedis: func(mock redismock.ClientMock) {
mock.ExpectEval("return redis.call('set',KEYS[1])", []string{"foo"}).SetErr(errors.New("missing value for 'set'"))
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
db, mock := redismock.NewClientMock()
if db == nil || mock == nil {
t.Fatalf("Failed to create Redis mock client.")
}

tc.prepareMockRedis(mock)
rediscli.WriteHandle = db

L := lua.NewState()

defer L.Close()

// Set up script
L.Push(lua.LString(tc.script))

// Set up keys
keys := L.CreateTable(len(tc.keys), 0)
for _, k := range tc.keys {
keys.Append(lua.LString(k))
}

L.Push(keys)

// Set up args
args := L.CreateTable(len(tc.args), 0)
for _, a := range tc.args {
args.Append(lua.LString(a.(string))) // Annahme, dass args vom Typ string sind
}

L.Push(args)

// Call function and check error
numReturned := RedisRunScript(L)
errReturned := L.Get(-2).String() != "nil"

assert.Equal(t, tc.expectErr, errReturned, "")
assert.Equal(t, 2, numReturned, "")

// Check result if no error
if !tc.expectErr && numReturned > 0 {
resReturned := L.Get(-1).String()

assert.Equal(t, tc.expectRes, resReturned, "")
}

// Check if everything expected was done
assert.NoError(t, mock.ExpectationsWereMet())
})
}
}

0 comments on commit 6921e37

Please sign in to comment.