-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Dice command integration tests (EXISTS, EXPIRE, EXPIREAT, EXPIRET…
…IME) and package for validation (#39)
- Loading branch information
1 parent
cea7ede
commit 9bc7f87
Showing
8 changed files
with
377 additions
and
28 deletions.
There are no files selected for viewing
26 changes: 26 additions & 0 deletions
26
internal/tests/integration/commands/assertions/assertions.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package assertions | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
// AssertResult checks the result of command execution against expected results. | ||
// Parameters: | ||
// - t: the testing context used for reporting errors. | ||
// - err: the error returned from the command execution. | ||
// - response: the response obtained from the command. | ||
// - expected: the expected response string. | ||
// - errorExpected: a flag indicating whether an error is expected. | ||
func AssertResult(t *testing.T, err error, response, expected string, errorExpected bool) { | ||
if errorExpected { | ||
// Assert that an error occurred and check the error message. | ||
assert.Error(t, err, "Expected an error but got none") | ||
assert.EqualError(t, err, expected, "Error message does not match the expected message") | ||
} else { | ||
// Assert that no error occurred and check the response. | ||
assert.NoError(t, err, "Expected no error but got one") | ||
assert.Equal(t, expected, response, "Response does not match the expected value") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package commands | ||
|
||
import ( | ||
"server/internal/tests/integration/commands/assertions" | ||
"testing" | ||
) | ||
|
||
func TestExists(t *testing.T) { | ||
exec, err := NewHTTPCommandExecutor() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
defer exec.FlushDB() | ||
|
||
testCases := []TestCase{ | ||
{ | ||
Name: "EXISTS with a non-existent key", | ||
Commands: []HTTPCommand{ | ||
{Command: "EXISTS", Body: []string{"non_existent_key"}}, | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "0"}, // Expecting 0 because the key should not exist | ||
}, | ||
}, | ||
{ | ||
Name: "EXISTS with an existing key", | ||
Commands: []HTTPCommand{ | ||
{Command: "SET", Body: []string{"existing_key", "SomeValue"}}, | ||
{Command: "EXISTS", Body: []string{"existing_key"}}, | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "OK"}, // Expecting "OK" from the SET command | ||
{Expected: "1"}, // Expecting 1 because the key should exist | ||
}, | ||
}, | ||
{ | ||
Name: "EXISTS with multiple keys where some exist", | ||
Commands: []HTTPCommand{ | ||
{Command: "SET", Body: []string{"key1", "Value1"}}, | ||
{Command: "SET", Body: []string{"key2", "Value2"}}, | ||
{Command: "EXISTS", Body: []string{"key1", "key2", "non_existent_key"}}, | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "OK"}, | ||
{Expected: "OK"}, | ||
{Expected: "2"}, // Expecting 2 because only key1 and key2 exist | ||
}, | ||
}, | ||
{ | ||
Name: "EXISTS command with invalid number of arguments", | ||
Commands: []HTTPCommand{ | ||
{Command: "EXISTS", Body: []string{}}, // No arguments | ||
}, | ||
Result: []TestCaseResult{ | ||
{ErrorExpected: true, Expected: "(error) ERR wrong number of arguments for 'exists' command"}, | ||
}, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.Name, func(t *testing.T) { | ||
for i, cmd := range tc.Commands { | ||
response, err := exec.FireCommand(cmd) | ||
if err != nil { | ||
t.Logf("error in executing command: %s - %v", cmd.Command, err) | ||
} | ||
|
||
result := tc.Result[i] | ||
assertions.AssertResult(t, err, response, result.Expected, result.ErrorExpected) | ||
|
||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package commands | ||
|
||
import ( | ||
"server/internal/tests/integration/commands/assertions" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestExpire(t *testing.T) { | ||
exec, err := NewHTTPCommandExecutor() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
defer exec.FlushDB() | ||
|
||
testCases := []TestCase{ | ||
{ | ||
Name: "EXPIRE on an existing key", | ||
Commands: []HTTPCommand{ | ||
{Command: "SET", Body: []string{"key_to_expire_1", "SomeValue"}}, | ||
{Command: "EXPIRE", Body: []string{"key_to_expire_1", "1"}}, // 1 second expiration | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "OK"}, | ||
{Expected: "1"}, | ||
}, | ||
}, | ||
{ | ||
Name: "Check expiration after delay", | ||
Commands: []HTTPCommand{ | ||
{Command: "SET", Body: []string{"key_to_expire_2", "SomeValue"}}, | ||
{Command: "EXPIRE", Body: []string{"key_to_expire_2", "1"}}, | ||
{Command: "GET", Body: []string{"key_to_expire_2"}}, // Check if key is still accessible | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "OK"}, | ||
{Expected: "1"}, | ||
{Expected: "SomeValue"}, | ||
}, | ||
}, | ||
{ | ||
Name: "Check key after waiting for expiration", | ||
Commands: []HTTPCommand{ | ||
{Command: "SET", Body: []string{"key_to_expire_3", "SomeValue"}}, | ||
{Command: "EXPIRE", Body: []string{"key_to_expire_3", "3"}}, | ||
{Command: "GET", Body: []string{"key_to_expire_3"}}, // Check if key is still accessible after waiting | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "OK"}, | ||
{Expected: "1"}, | ||
{Expected: "(nil)"}, // Expecting (nil) after waiting | ||
}, | ||
}, | ||
{ | ||
Name: "EXPIRE on a non-existent key", | ||
Commands: []HTTPCommand{ | ||
{Command: "EXPIRE", Body: []string{"non_existent_key", "1"}}, | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "0"}, | ||
}, | ||
}, | ||
{ | ||
Name: "EXPIRE with invalid number of arguments", | ||
Commands: []HTTPCommand{ | ||
{Command: "SET", Body: []string{"key_to_expire_4", "SomeValue"}}, | ||
{Command: "EXPIRE", Body: []string{"key_to_expire_4", "1", "extra_argument"}}, | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "OK"}, | ||
{ErrorExpected: true, Expected: "(error) ERR Unsupported option extra_argument"}, | ||
}, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.Name, func(t *testing.T) { | ||
for i, cmd := range tc.Commands { | ||
if tc.Name == "Check key after waiting for expiration" && cmd.Command == "GET" { // Wait longer for expiration check | ||
time.Sleep(4 * time.Second) // Longer than the expiration time | ||
} | ||
response, err := exec.FireCommand(cmd) | ||
if err != nil { | ||
t.Logf("Error executing command: %s - %v", cmd.Command, err) | ||
} else { | ||
t.Logf("Response for command %s: %s", cmd.Command, response) | ||
} | ||
|
||
result := tc.Result[i] | ||
|
||
assertions.AssertResult(t, err, response, result.Expected, result.ErrorExpected) | ||
} | ||
|
||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package commands | ||
|
||
import ( | ||
"server/internal/tests/integration/commands/assertions" | ||
"strconv" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestExpireAt(t *testing.T) { | ||
exec, err := NewHTTPCommandExecutor() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
defer exec.FlushDB() | ||
|
||
testCases := []TestCase{ | ||
{ | ||
Name: "EXPIREAT on a non-existent key", | ||
Commands: []HTTPCommand{ | ||
{Command: "EXPIREAT", Body: []string{"non_existent_key", "1660000000"}}, // Arbitrary timestamp | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "0"}, // Expecting 0 because the key does not exist | ||
}, | ||
}, | ||
{ | ||
Name: "EXPIREAT on an existing key with future timestamp", | ||
Commands: []HTTPCommand{ | ||
{Command: "SET", Body: []string{"temp_key", "temp_value"}}, | ||
{Command: "EXPIREAT", Body: []string{"temp_key", strconv.FormatInt(time.Now().Add(30*time.Second).Unix(), 10)}}, // Future timestamp | ||
{Command: "EXISTS", Body: []string{"temp_key"}}, // Check if the key exists immediately | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "OK"}, | ||
{Expected: "1"}, // Expecting 1 because EXPIREAT set the expiration successfully | ||
{Expected: "1"}, // Key should still exist as it hasn't expired yet | ||
}, | ||
}, | ||
{ | ||
Name: "EXPIREAT on an existing key with past timestamp", | ||
Commands: []HTTPCommand{ | ||
{Command: "SET", Body: []string{"past_key", "past_value"}}, | ||
{Command: "EXPIREAT", Body: []string{"past_key", "1600000000"}}, // Past timestamp | ||
{Command: "EXISTS", Body: []string{"past_key"}}, // Check if the key exists after expiration | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "OK"}, | ||
{Expected: "1"}, // EXPIREAT should execute successfully | ||
{Expected: "0"}, // Key should not exist as it has already expired | ||
}, | ||
}, | ||
{ | ||
Name: "EXPIREAT with invalid arguments", | ||
Commands: []HTTPCommand{ | ||
{Command: "EXPIREAT", Body: []string{"key_only"}}, // Missing timestamp | ||
}, | ||
Result: []TestCaseResult{ | ||
{ErrorExpected: true, Expected: "(error) ERR wrong number of arguments for 'expireat' command"}, | ||
}, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.Name, func(t *testing.T) { | ||
for i, cmd := range tc.Commands { | ||
response, err := exec.FireCommand(cmd) | ||
if err != nil { | ||
t.Logf("Error executing command: %s - %v", cmd.Command, err) | ||
} else { | ||
t.Logf("Response for command %s: %s", cmd.Command, response) | ||
} | ||
|
||
result := tc.Result[i] | ||
assertions.AssertResult(t, err, response, result.Expected, result.ErrorExpected) | ||
|
||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package commands | ||
|
||
import ( | ||
"server/internal/tests/integration/commands/assertions" | ||
"strconv" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestExpireTime(t *testing.T) { | ||
exec, err := NewHTTPCommandExecutor() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
defer exec.FlushDB() | ||
|
||
testCases := []TestCase{ | ||
{ | ||
Name: "EXPIRETIME on a non-existent key", | ||
Commands: []HTTPCommand{ | ||
{Command: "EXPIRETIME", Body: []string{"non_existent_key"}}, | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "-2"}, // Expecting -2 because the key does not exist | ||
}, | ||
}, | ||
{ | ||
Name: "EXPIRETIME on an existing key with future expiration", | ||
Commands: []HTTPCommand{ | ||
{Command: "SET", Body: []string{"temp_key", "temp_value"}}, | ||
{Command: "EXPIREAT", Body: []string{"temp_key", strconv.FormatInt(time.Now().Add(30*time.Second).Unix(), 10)}}, // Set future expiration | ||
{Command: "EXPIRETIME", Body: []string{"temp_key"}}, // Retrieve expiration time | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "OK"}, | ||
{Expected: "1"}, // Indicating the EXPIREAT command was successful | ||
{Expected: strconv.FormatInt(time.Now().Add(30*time.Second).Unix(), 10)}, // Future timestamp in seconds | ||
}, | ||
}, | ||
{ | ||
Name: "EXPIRETIME on an existing key without expiration", | ||
Commands: []HTTPCommand{ | ||
{Command: "SET", Body: []string{"persist_key", "persistent_value"}}, | ||
{Command: "EXPIRETIME", Body: []string{"persist_key"}}, // Check expiration time | ||
}, | ||
Result: []TestCaseResult{ | ||
{Expected: "OK"}, | ||
{Expected: "-1"}, // Expecting -1 because no expiration is set | ||
}, | ||
}, | ||
{ | ||
Name: "EXPIRETIME with invalid arguments", | ||
Commands: []HTTPCommand{ | ||
{Command: "EXPIRETIME", Body: []string{}}, // Missing key argument | ||
}, | ||
Result: []TestCaseResult{ | ||
{ErrorExpected: true, Expected: "(error) ERR wrong number of arguments for 'expiretime' command"}, | ||
}, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.Name, func(t *testing.T) { | ||
for i, cmd := range tc.Commands { | ||
response, err := exec.FireCommand(cmd) | ||
if err != nil { | ||
t.Logf("Error executing command: %s - %v", cmd.Command, err) | ||
} else { | ||
t.Logf("Response for command %s: %s", cmd.Command, response) | ||
} | ||
|
||
result := tc.Result[i] | ||
assertions.AssertResult(t, err, response, result.Expected, result.ErrorExpected) | ||
|
||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.