Skip to content

Commit

Permalink
Add Dice command integration tests (EXISTS, EXPIRE, EXPIREAT, EXPIRET…
Browse files Browse the repository at this point in the history
…IME) and package for validation (#39)
  • Loading branch information
RishabhC-137 authored Oct 16, 2024
1 parent cea7ede commit 9bc7f87
Show file tree
Hide file tree
Showing 8 changed files with 377 additions and 28 deletions.
26 changes: 26 additions & 0 deletions internal/tests/integration/commands/assertions/assertions.go
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")
}
}
75 changes: 75 additions & 0 deletions internal/tests/integration/commands/exists_test.go
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)

}
})
}
}
97 changes: 97 additions & 0 deletions internal/tests/integration/commands/expire_test.go
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)
}

})
}
}
81 changes: 81 additions & 0 deletions internal/tests/integration/commands/expireat_test.go
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)

}
})
}
}
79 changes: 79 additions & 0 deletions internal/tests/integration/commands/expiretime_test.go
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)

}
})
}
}
15 changes: 6 additions & 9 deletions internal/tests/integration/commands/hget_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package commands

import (
"server/internal/tests/integration/commands/assertions"
"testing"

"github.com/stretchr/testify/assert"
)

func TestHGet(t *testing.T) {
Expand Down Expand Up @@ -73,16 +72,14 @@ func TestHGet(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)
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]
if result.ErrorExpected {
assert.NotNil(t, err)
assert.Equal(t, result.Expected, err.Error())
} else {
assert.Equal(t, result.Expected, response)
}
assertions.AssertResult(t, err, response, result.Expected, result.ErrorExpected)

}
})
}
Expand Down
Loading

0 comments on commit 9bc7f87

Please sign in to comment.