Skip to content

Commit

Permalink
DiceDB#740 Add HTTP integration tests (DiceDB#873)
Browse files Browse the repository at this point in the history
  • Loading branch information
hgupta12 authored Oct 5, 2024
1 parent ab639d6 commit b74dc8f
Show file tree
Hide file tree
Showing 6 changed files with 665 additions and 6 deletions.
6 changes: 0 additions & 6 deletions integration_tests/commands/async/hyperloglog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ func TestHyperLogLogCommands(t *testing.T) {
"PFMERGE NON_EXISTING_SRC_KEY", "PFCOUNT NON_EXISTING_SRC_KEY"},
expected: []interface{}{"OK", int64(0)},
},
{
name: "PFMERGE with srcKey non-existing",
commands: []string{
"PFMERGE NON_EXISTING_SRC_KEY", "PFCOUNT NON_EXISTING_SRC_KEY"},
expected: []interface{}{"OK", int64(0)},
},
{
name: "PFMERGE with destKey non-existing",
commands: []string{
Expand Down
73 changes: 73 additions & 0 deletions integration_tests/commands/http/hsetnx_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package http

import (
"testing"
"time"

"gotest.tools/v3/assert"
)

func TestHSetNX(t *testing.T) {
exec := NewHTTPCommandExecutor()

testCases := []struct {
name string
commands []HTTPCommand
expected []interface{}
delays []time.Duration
}{
{
name: "HSetNX returns 0 when field is already set",
commands: []HTTPCommand{
{Command: "HSETNX", Body: map[string]interface{}{"key": "key_nx_t1", "field": "field", "value": "value"}},
{Command: "HSETNX", Body: map[string]interface{}{"key": "key_nx_t1", "field": "field", "value": "value_new"}},
},
expected: []interface{}{float64(1), float64(0)},
delays: []time.Duration{0, 0},
},
{
name: "HSetNX with new field",
commands: []HTTPCommand{
{Command: "HSETNX", Body: map[string]interface{}{"key": "key_nx_t2", "field": "field", "value": "value"}},
},
expected: []interface{}{float64(1)},
delays: []time.Duration{0},
},
{
name: "HSetNX with wrong number of arguments",
commands: []HTTPCommand{
{Command: "HSETNX", Body: map[string]interface{}{"key": "key_nx_t3", "field": "field", "value": "value"}},
{Command: "HSETNX", Body: map[string]interface{}{"key": "key_nx_t3", "field": "field", "value": "value_new"}},
{Command: "HSETNX", Body: map[string]interface{}{"key": "key_nx_t3"}},
},
expected: []interface{}{float64(1), float64(0), "ERR wrong number of arguments for 'hsetnx' command"},
delays: []time.Duration{0, 0, 0},
},
{
name: "HSetNX with wrong type",
commands: []HTTPCommand{
{Command: "SET", Body: map[string]interface{}{"key": "key_nx_t4", "value": "v"}},
{Command: "HSETNX", Body: map[string]interface{}{"key": "key_nx_t4", "field": "f", "value": "v_new"}},
},
expected: []interface{}{"OK", "WRONGTYPE Operation against a key holding the wrong kind of value"},
delays: []time.Duration{0, 0},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
for i, cmd := range tc.commands {
if tc.delays[i] > 0 {
time.Sleep(tc.delays[i])
}
result, err := exec.FireCommand(cmd)
if err != nil {
// Check if the error message matches the expected result
assert.Equal(t, tc.expected[i], err.Error(), "Error message mismatch for cmd %s", cmd)
} else {
assert.Equal(t, tc.expected[i], result, "Value mismatch for cmd %s, expected %v, got %v", cmd, tc.expected[i], result)
}
}
})
}
}
88 changes: 88 additions & 0 deletions integration_tests/commands/http/hstrlen_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package http

import (
"log"
"testing"
"time"

"gotest.tools/v3/assert"
)

func TestHStrLen(t *testing.T) {
exec := NewHTTPCommandExecutor()

testCases := []struct {
name string
commands []HTTPCommand
expected []interface{}
delays []time.Duration
}{
{
name: "HSTRLEN with wrong number of arguments",
commands: []HTTPCommand{
{Command: "HSTRLEN", Body: map[string]interface{}{"key": "KEY"}},
{Command: "HSTRLEN", Body: map[string]interface{}{"key": "KEY", "field": "field", "another_field": "another_field"}},
},
expected: []interface{}{
"ERR wrong number of arguments for 'hstrlen' command",
"ERR wrong number of arguments for 'hstrlen' command"},
delays: []time.Duration{0, 0},
},
{
name: "HSTRLEN with wrong key",
commands: []HTTPCommand{
{Command: "HSET", Body: map[string]interface{}{"key": "key_hStrLen1", "field": "field", "value": "value"}},
{Command: "HSTRLEN", Body: map[string]interface{}{"key": "wrong_key_hStrLen", "field": "field"}},
},
expected: []interface{}{float64(1), float64(0)},
delays: []time.Duration{0, 0},
},
{
name: "HSTRLEN with wrong field",
commands: []HTTPCommand{
{Command: "HSET", Body: map[string]interface{}{"key": "key_hStrLen2", "field": "field", "value": "value"}},
{Command: "HSTRLEN", Body: map[string]interface{}{"key": "key_hStrLen2", "field": "wrong_field"}},
},
expected: []interface{}{float64(1), float64(0)},
delays: []time.Duration{0, 0},
},
{
name: "HSTRLEN",
commands: []HTTPCommand{
{Command: "HSET", Body: map[string]interface{}{"key": "key_hStrLen3", "field": "field", "value": "HelloWorld"}},
{Command: "HSTRLEN", Body: map[string]interface{}{"key": "key_hStrLen3", "field": "field"}},
},
expected: []interface{}{float64(1), float64(10)},
delays: []time.Duration{0, 0},
},
{
name: "HSTRLEN with wrong type",
commands: []HTTPCommand{
{Command: "SET", Body: map[string]interface{}{"key": "key", "value": "value"}},
{Command: "HSTRLEN", Body: map[string]interface{}{"key": "key", "field": "field"}},
},
expected: []interface{}{"OK", "WRONGTYPE Operation against a key holding the wrong kind of value"},
delays: []time.Duration{0, 0},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
defer exec.FireCommand(HTTPCommand{Command: "DEL", Body: map[string]interface{}{"keys": [...]string{"KEY", "key"}}})

for i, cmd := range tc.commands {
if tc.delays[i] > 0 {
time.Sleep(tc.delays[i])
}
result, err := exec.FireCommand(cmd)
if err != nil {
// Check if the error message matches the expected result
log.Println(tc.expected[i])
assert.Equal(t, tc.expected[i], err.Error(), "Error message mismatch for cmd %s", cmd)
} else {
assert.Equal(t, tc.expected[i], result, "Value mismatch for cmd %s, expected %v, got %v", cmd, tc.expected[i], result)
}
}
})
}
}
150 changes: 150 additions & 0 deletions integration_tests/commands/http/hyperloglog_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package http

import (
"testing"
"time"

"gotest.tools/v3/assert"
)

func TestHyperLogLogCommands(t *testing.T) {
exec := NewHTTPCommandExecutor()

testCases := []struct {
name string
commands []HTTPCommand
expected []interface{}
delays []time.Duration
}{
{
name: "PFADD with one key-value pair",
commands: []HTTPCommand{
{Command: "PFADD", Body: map[string]interface{}{"key": "hll0", "value": "v1"}},
{Command: "PFCOUNT", Body: map[string]interface{}{"key": "hll0"}},
},
expected: []interface{}{float64(1), float64(1)},
delays: []time.Duration{0, 0},
},
{
name: "PFADD with multiple key-value pair",
commands: []HTTPCommand{
{Command: "PFADD", Body: map[string]interface{}{"key": "hll", "values": [...]string{"a", "b", "c", "d", "e", "f"}}},
{Command: "PFCOUNT", Body: map[string]interface{}{"key": "hll"}},
},
expected: []interface{}{float64(1), float64(6)},
delays: []time.Duration{0, 0},
},
{
name: "PFADD with duplicate key-value pairs",
commands: []HTTPCommand{
{Command: "PFADD", Body: map[string]interface{}{"key": "hll1", "values": [...]string{"foo", "bar", "zap"}}},
{Command: "PFADD", Body: map[string]interface{}{"key": "hll1", "values": [...]string{"zap", "zap", "zap"}}},
{Command: "PFADD", Body: map[string]interface{}{"key": "hll1", "values": [...]string{"foo", "bar"}}},
{Command: "PFCOUNT", Body: map[string]interface{}{"key": "hll1"}},
},
expected: []interface{}{float64(1), float64(0), float64(0), float64(3)},
delays: []time.Duration{0, 0, 0, 0},
},
{
name: "PFADD with multiple keys",
commands: []HTTPCommand{
{Command: "PFADD", Body: map[string]interface{}{"key": "hll2", "values": [...]string{"foo", "bar", "zap"}}},
{Command: "PFADD", Body: map[string]interface{}{"key": "hll2", "values": [...]string{"zap", "zap", "zap"}}},
{Command: "PFCOUNT", Body: map[string]interface{}{"key": "hll2"}},
{Command: "PFADD", Body: map[string]interface{}{"key": "some-other-hll", "values": [...]string{"1", "2", "3"}}},
{Command: "PFCOUNT", Body: map[string]interface{}{"keys": [...]string{"hll2", "some-other-hll"}}},
},
expected: []interface{}{float64(1), float64(0), float64(3), float64(1), float64(6)},
delays: []time.Duration{0, 0, 0, 0, 0},
},
{
name: "PFADD with non-existing key",
commands: []HTTPCommand{
{Command: "PFADD", Body: map[string]interface{}{"key": "hll3", "values": [...]string{"foo", "bar", "zap"}}},
{Command: "PFADD", Body: map[string]interface{}{"key": "hll3", "values": [...]string{"zap", "zap", "zap"}}},
{Command: "PFCOUNT", Body: map[string]interface{}{"key": "hll3"}},
{Command: "PFCOUNT", Body: map[string]interface{}{"keys": [...]string{"hll3", "non-exist-hll"}}},
{Command: "PFADD", Body: map[string]interface{}{"key": "some-new-hll", "value": "abc"}},
{Command: "PFCOUNT", Body: map[string]interface{}{"keys": [...]string{"hll3", "non-exist-hll", "some-new-hll"}}},
},
expected: []interface{}{float64(1), float64(0), float64(3), float64(3), float64(1), float64(4)},
delays: []time.Duration{0, 0, 0, 0, 0, 0},
},
{
name: "PFMERGE with srcKey non-existing",
commands: []HTTPCommand{
{Command: "PFMERGE", Body: map[string]interface{}{"key": "NON_EXISTING_SRC_KEY"}},
{Command: "PFCOUNT", Body: map[string]interface{}{"key": "NON_EXISTING_SRC_KEY"}},
},
expected: []interface{}{"OK", float64(0)},
delays: []time.Duration{0, 0},
},
{
name: "PFMERGE with destKey non-existing",
commands: []HTTPCommand{
{Command: "PFMERGE", Body: map[string]interface{}{"keys": []string{"EXISTING_SRC_KEY", "NON_EXISTING_SRC_KEY"}}},
{Command: "PFCOUNT", Body: map[string]interface{}{"key": "EXISTING_SRC_KEY"}},
},
expected: []interface{}{"OK", float64(0)},
delays: []time.Duration{0, 0},
},
{
name: "PFMERGE with destKey existing",
commands: []HTTPCommand{
{Command: "PFADD", Body: map[string]interface{}{"key": "DEST_KEY_1", "values": [...]string{"foo", "bar", "zap", "a"}}},
{Command: "PFADD", Body: map[string]interface{}{"key": "DEST_KEY_2", "values": [...]string{"a", "b", "c", "foo"}}},
{Command: "PFMERGE", Body: map[string]interface{}{"keys": [...]string{"SRC_KEY_1", "DEST_KEY_1", "DEST_KEY_2"}}},
{Command: "PFCOUNT", Body: map[string]interface{}{"key": "SRC_KEY_1"}},
},
expected: []interface{}{float64(1), float64(1), "OK", float64(6)},
delays: []time.Duration{0, 0, 0, 0},
},
{
name: "PFMERGE with only one destKey existing",
commands: []HTTPCommand{
{Command: "PFADD", Body: map[string]interface{}{"key": "DEST_KEY_3", "values": [...]string{"foo", "bar", "zap", "a"}}},
{Command: "PFMERGE", Body: map[string]interface{}{"keys": [...]string{"SRC_KEY_2", "DEST_KEY_3", "NON_EXISTING_DEST_KEY"}}},
{Command: "PFCOUNT", Body: map[string]interface{}{"key": "SRC_KEY_2"}},
},
expected: []interface{}{float64(1), "OK", float64(4)},
delays: []time.Duration{0, 0, 0},
},
{
name: "PFMERGE with invalid object",
commands: []HTTPCommand{
{Command: "PFADD", Body: map[string]interface{}{"key": "INVALID_HLL", "values": [...]string{"a", "b", "c"}}},
{Command: "SET", Body: map[string]interface{}{"key": "INVALID_HLL", "value": "1"}},
{Command: "PFMERGE", Body: map[string]interface{}{"key": "INVALID_HLL"}},
},
expected: []interface{}{float64(1), "OK", "WRONGTYPE Key is not a valid HyperLogLog string value."},
delays: []time.Duration{0, 0, 0},
},
{
name: "PFMERGE with invalid src object",
commands: []HTTPCommand{
{Command: "PFADD", Body: map[string]interface{}{"key": "INVALID_SRC_HLL", "values": [...]string{"a", "b", "c"}}},
{Command: "SET", Body: map[string]interface{}{"key": "INVALID_SRC_HLL", "value": "1"}},
{Command: "PFMERGE", Body: map[string]interface{}{"keys": [...]string{"HLL", "INVALID_SRC_HLL"}}},
},
expected: []interface{}{float64(1), "OK", "WRONGTYPE Key is not a valid HyperLogLog string value."},
delays: []time.Duration{0, 0, 0},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
for i, cmd := range tc.commands {
if tc.delays[i] > 0 {
time.Sleep(tc.delays[i])
}
result, err := exec.FireCommand(cmd)
if err != nil {
// Check if the error message matches the expected result
assert.Equal(t, tc.expected[i], err.Error(), "Error message mismatch for cmd %s", cmd)
} else {
assert.Equal(t, tc.expected[i], result, "Value mismatch for cmd %s, expected %v, got %v", cmd, tc.expected[i], result)
}
}
})
}
}
Loading

0 comments on commit b74dc8f

Please sign in to comment.