Refactor tests (#171)

- Refactored tests to improve execution time - @kelvinmwinuka
This commit is contained in:
Kelvin Mwinuka
2025-01-27 01:42:41 +08:00
committed by GitHub
parent ec69e52a5b
commit 63a4652d9f
12 changed files with 12079 additions and 11853 deletions

View File

@@ -14,12 +14,18 @@ build-modules-test:
test: test:
env RACE=false OUT=internal/modules/admin/testdata make build-modules-test && \ env RACE=false OUT=internal/modules/admin/testdata make build-modules-test && \
env RACE=false OUT=sugardb/testdata make build-modules-test && \ env RACE=false OUT=sugardb/testdata make build-modules-test && \
CGO_ENABLED=1 go test ./... -coverprofile coverage/coverage.out CGO_ENABLED=1 go test ./... -coverprofile coverage/coverage.out && \
rm -rf ./internal/modules/admin/testdata && \
rm -rf ./sugardb/testdata && \
rm -rf ./sugardb/aof
test-race: test-race:
env RACE=true OUT=internal/modules/admin/testdata make build-modules-test && \ env RACE=true OUT=internal/modules/admin/testdata make build-modules-test && \
env RACE=true OUT=sugardb/testdata make build-modules-test && \ env RACE=true OUT=sugardb/testdata make build-modules-test && \
CGO_ENABLED=1 go test ./... --race CGO_ENABLED=1 go test ./... --race && \
rm -rf ./internal/modules/admin/testdata && \
rm -rf ./sugardb/testdata && \
rm -rf ./sugardb/aof
testenv-run: testenv-run:
docker-compose -f test_env/run/docker-compose.yaml build docker-compose -f test_env/run/docker-compose.yaml build

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -25,261 +25,272 @@ import (
"testing" "testing"
) )
func TestSugarDB_Hello(t *testing.T) { func TestSugarDB_Connection(t *testing.T) {
t.Parallel() t.Run("TestSugarDB_Hello", func(t *testing.T) {
t.Parallel()
port, err := internal.GetFreePort() port, err := internal.GetFreePort()
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return
} }
conf := DefaultConfig() conf := DefaultConfig()
conf.Port = uint16(port) conf.Port = uint16(port)
conf.RequirePass = false conf.RequirePass = false
mockServer := createSugarDBWithConfig(conf) mockServer := createSugarDBWithConfig(conf)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return
} }
go func() { go func() {
mockServer.Start() mockServer.Start()
}() }()
t.Cleanup(func() { t.Cleanup(func() {
mockServer.ShutDown() mockServer.ShutDown()
})
tests := []struct {
name string
command []resp.Value
wantRes []byte
}{
{
name: "1. Hello",
command: []resp.Value{resp.StringValue("HELLO")},
wantRes: connection.BuildHelloResponse(
internal.ServerInfo{
Server: "sugardb",
Version: constants.Version,
Id: "",
Mode: "standalone",
Role: "master",
Modules: mockServer.ListModules(),
},
internal.ConnectionInfo{
Id: 1,
Name: "",
Protocol: 2,
Database: 0,
},
),
},
{
name: "2. Hello 2",
command: []resp.Value{resp.StringValue("HELLO"), resp.StringValue("2")},
wantRes: connection.BuildHelloResponse(
internal.ServerInfo{
Server: "sugardb",
Version: constants.Version,
Id: "",
Mode: "standalone",
Role: "master",
Modules: mockServer.ListModules(),
},
internal.ConnectionInfo{
Id: 2,
Name: "",
Protocol: 2,
Database: 0,
},
),
},
{
name: "3. Hello 3",
command: []resp.Value{resp.StringValue("HELLO"), resp.StringValue("3")},
wantRes: connection.BuildHelloResponse(
internal.ServerInfo{
Server: "sugardb",
Version: constants.Version,
Id: "",
Mode: "standalone",
Role: "master",
Modules: mockServer.ListModules(),
},
internal.ConnectionInfo{
Id: 3,
Name: "",
Protocol: 3,
Database: 0,
},
),
},
}
for i := 0; i < len(tests); i++ {
conn, err := internal.GetConnection("localhost", port)
if err != nil {
t.Error(err)
return
}
client := resp.NewConn(conn)
if err = client.WriteArray(tests[i].command); err != nil {
t.Error(err)
return
}
buf := bufio.NewReader(conn)
res, err := internal.ReadMessage(buf)
if err != nil {
t.Error(err)
return
}
if !bytes.Equal(tests[i].wantRes, res) {
t.Errorf("expected byte resposne:\n%s, \n\ngot:\n%s", string(tests[i].wantRes), string(res))
return
}
// Close connection
_ = conn.Close()
}
}) })
tests := []struct { t.Run("TestSugarDB_SelectDB", func(t *testing.T) {
name string t.Parallel()
command []resp.Value tests := []struct {
wantRes []byte name string
}{ presetValues map[int]map[string]string
{ database int
name: "1. Hello", want map[int][]string
command: []resp.Value{resp.StringValue("HELLO")}, wantErr bool
wantRes: connection.BuildHelloResponse( }{
internal.ServerInfo{ {
Server: "sugardb", name: "1. Change database and read new values",
Version: constants.Version, presetValues: map[int]map[string]string{
Id: "", 0: {"key1": "value-01", "key2": "value-02", "key3": "value-03"},
Mode: "standalone", 1: {"key1": "value-11", "key2": "value-12", "key3": "value-13"},
Role: "master",
Modules: mockServer.ListModules(),
}, },
internal.ConnectionInfo{ database: 1,
Id: 1, want: map[int][]string{
Name: "", 0: {"value-01", "value-02", "value-03"},
Protocol: 2, 1: {"value-11", "value-12", "value-13"},
Database: 0,
}, },
), wantErr: false,
},
{
name: "2. Hello 2",
command: []resp.Value{resp.StringValue("HELLO"), resp.StringValue("2")},
wantRes: connection.BuildHelloResponse(
internal.ServerInfo{
Server: "sugardb",
Version: constants.Version,
Id: "",
Mode: "standalone",
Role: "master",
Modules: mockServer.ListModules(),
},
internal.ConnectionInfo{
Id: 2,
Name: "",
Protocol: 2,
Database: 0,
},
),
},
{
name: "3. Hello 3",
command: []resp.Value{resp.StringValue("HELLO"), resp.StringValue("3")},
wantRes: connection.BuildHelloResponse(
internal.ServerInfo{
Server: "sugardb",
Version: constants.Version,
Id: "",
Mode: "standalone",
Role: "master",
Modules: mockServer.ListModules(),
},
internal.ConnectionInfo{
Id: 3,
Name: "",
Protocol: 3,
Database: 0,
},
),
},
}
for i := 0; i < len(tests); i++ {
conn, err := internal.GetConnection("localhost", port)
if err != nil {
t.Error(err)
return
}
client := resp.NewConn(conn)
if err = client.WriteArray(tests[i].command); err != nil {
t.Error(err)
return
}
buf := bufio.NewReader(conn)
res, err := internal.ReadMessage(buf)
if err != nil {
t.Error(err)
return
}
if !bytes.Equal(tests[i].wantRes, res) {
t.Errorf("expected byte resposne:\n%s, \n\ngot:\n%s", string(tests[i].wantRes), string(res))
return
}
// Close connection
_ = conn.Close()
}
}
func TestSugarDB_SelectDB(t *testing.T) {
t.Parallel()
tests := []struct {
name string
presetValues map[int]map[string]string
database int
want map[int][]string
wantErr bool
}{
{
name: "1. Change database and read new values",
presetValues: map[int]map[string]string{
0: {"key1": "value-01", "key2": "value-02", "key3": "value-03"},
1: {"key1": "value-11", "key2": "value-12", "key3": "value-13"},
}, },
database: 1, {
want: map[int][]string{ name: "2. Error when database parameter is < 0",
0: {"value-01", "value-02", "value-03"}, presetValues: map[int]map[string]string{
1: {"value-11", "value-12", "value-13"}, 0: {"key1": "value-01", "key2": "value-02", "key3": "value-03"},
},
database: -1,
want: map[int][]string{
0: {"value-01", "value-02", "value-03"},
},
wantErr: true,
}, },
wantErr: false, }
}, for _, tt := range tests {
{ t.Run(tt.name, func(t *testing.T) {
name: "2. Error when database parameter is < 0", t.Parallel()
presetValues: map[int]map[string]string{
0: {"key1": "value-01", "key2": "value-02", "key3": "value-03"},
},
database: -1,
want: map[int][]string{
0: {"value-01", "value-02", "value-03"},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
server := createSugarDB()
if tt.presetValues != nil { server := createSugarDB()
for db, data := range tt.presetValues { t.Cleanup(func() {
_ = server.SelectDB(db) server.ShutDown()
if _, err := server.MSet(data); err != nil { })
t.Errorf("SelectDB() error = %v", err)
if tt.presetValues != nil {
for db, data := range tt.presetValues {
_ = server.SelectDB(db)
if _, err := server.MSet(data); err != nil {
t.Errorf("SelectDB() error = %v", err)
return
}
}
_ = server.SelectDB(0)
}
// Check the values for DB 0
values, err := server.MGet("key1", "key2", "key3")
if err != nil {
t.Errorf("SelectDB() error = %v", err)
return
}
if !reflect.DeepEqual(values, tt.want[0]) {
t.Errorf("SelectDB() result-0 = %v, want-0 %v", values, tt.want[0])
return
}
err = server.SelectDB(tt.database)
if tt.wantErr {
if err == nil {
t.Errorf("SelectDB() error = %v, wantErr %v", err, tt.wantErr)
return return
} }
return
} }
_ = server.SelectDB(0) if err != nil {
}
// Check the values for DB 0
values, err := server.MGet("key1", "key2", "key3")
if err != nil {
t.Errorf("SelectDB() error = %v", err)
return
}
if !reflect.DeepEqual(values, tt.want[0]) {
t.Errorf("SelectDB() result-0 = %v, want-0 %v", values, tt.want[0])
return
}
err = server.SelectDB(tt.database)
if tt.wantErr {
if err == nil {
t.Errorf("SelectDB() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("SelectDB() error = %v, wantErr %v", err, tt.wantErr)
return return
} }
return
}
if err != nil {
t.Errorf("SelectDB() error = %v, wantErr %v", err, tt.wantErr)
return
}
// Check the values the new DB // Check the values the new DB
values, err = server.MGet("key1", "key2", "key3") values, err = server.MGet("key1", "key2", "key3")
if err != nil { if err != nil {
t.Errorf("SelectDB() error = %v", err) t.Errorf("SelectDB() error = %v", err)
return return
} }
if !reflect.DeepEqual(values, tt.want[1]) { if !reflect.DeepEqual(values, tt.want[1]) {
t.Errorf("SelectDB() result-1 = %v, want-1 %v", values, tt.want[1]) t.Errorf("SelectDB() result-1 = %v, want-1 %v", values, tt.want[1])
return return
} }
})
}
})
t.Run("TestSugarDB_SetProtocol", func(t *testing.T) {
t.Parallel()
server := createSugarDB()
t.Cleanup(func() {
server.ShutDown()
}) })
}
}
func TestSugarDB_SetProtocol(t *testing.T) { tests := []struct {
t.Parallel() name string
server := createSugarDB() protocol int
tests := []struct { wantErr bool
name string }{
protocol int {
wantErr bool name: "1. Change protocol to 2",
}{ protocol: 2,
{ wantErr: false,
name: "1. Change protocol to 2", },
protocol: 2, {
wantErr: false, name: "2. Change protocol to 3",
}, protocol: 3,
{ wantErr: false,
name: "2. Change protocol to 3", },
protocol: 3, {
wantErr: false, name: "3. Return error when protocol is neither 2 or 3",
}, protocol: 4,
{ wantErr: true,
name: "3. Return error when protocol is neither 2 or 3", },
protocol: 4, }
wantErr: true, for _, tt := range tests {
}, t.Run(tt.name, func(t *testing.T) {
} err := server.SetProtocol(tt.protocol)
for _, tt := range tests { if tt.wantErr {
t.Run(tt.name, func(t *testing.T) { if err == nil {
err := server.SetProtocol(tt.protocol) t.Errorf("SetProtocol() error = %v, wantErr %v", err, tt.wantErr)
if tt.wantErr { return
if err == nil { }
return
}
if err != nil {
t.Errorf("SetProtocol() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("SetProtocol() error = %v, wantErr %v", err, tt.wantErr)
return return
} }
return // Check if the protocol has been changed
} if server.connInfo.embedded.Protocol != tt.protocol {
if err != nil { t.Errorf("SetProtocol() protocol = %v, wantProtocol %v",
t.Errorf("SetProtocol() error = %v, wantErr %v", err, tt.wantErr) server.connInfo.embedded.Protocol, tt.protocol)
return }
} })
// Check if the protocol has been changed }
if server.connInfo.embedded.Protocol != tt.protocol { })
t.Errorf("SetProtocol() protocol = %v, wantProtocol %v",
server.connInfo.embedded.Protocol, tt.protocol)
}
})
}
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -19,349 +19,359 @@ import (
"testing" "testing"
) )
func TestSugarDB_SUBSTR(t *testing.T) { func TestSugarDB_String(t *testing.T) {
server := createSugarDB() server := createSugarDB()
tests := []struct { t.Cleanup(func() {
name string server.ShutDown()
presetValue interface{} })
substrFunc func(key string, start int, end int) (string, error)
key string t.Run("TestSugarDB_SUBSTR", func(t *testing.T) {
start int t.Parallel()
end int
want string tests := []struct {
wantErr bool name string
}{ presetValue interface{}
{ substrFunc func(key string, start int, end int) (string, error)
name: "Return substring within the range of the string", key string
key: "key1", start int
substrFunc: server.SubStr, end int
presetValue: "Test String One", want string
start: 5, wantErr bool
end: 10, }{
want: "String", {
wantErr: false, name: "Return substring within the range of the string",
}, key: "substr_key1",
{ substrFunc: server.SubStr,
name: "Return substring at the end of the string with exact end index", presetValue: "Test String One",
key: "key2", start: 5,
substrFunc: server.SubStr, end: 10,
presetValue: "Test String Two", want: "String",
start: 12, wantErr: false,
end: 14, },
want: "Two", {
wantErr: false, name: "Return substring at the end of the string with exact end index",
}, key: "substr_key2",
{ substrFunc: server.SubStr,
name: "Return substring at the end of the string with end index greater than length", presetValue: "Test String Two",
key: "key3", start: 12,
substrFunc: server.SubStr, end: 14,
presetValue: "Test String Three", want: "Two",
start: 12, wantErr: false,
end: 75, },
want: "Three", {
}, name: "Return substring at the end of the string with end index greater than length",
{ key: "substr_key3",
name: "Return the substring at the start of the string with 0 start index", substrFunc: server.SubStr,
key: "key4", presetValue: "Test String Three",
substrFunc: server.SubStr, start: 12,
presetValue: "Test String Four", end: 75,
start: 0, want: "Three",
end: 3, },
want: "Test", {
wantErr: false, name: "Return the substring at the start of the string with 0 start index",
}, key: "substr_key4",
{ substrFunc: server.SubStr,
// Return the substring with negative start index. presetValue: "Test String Four",
// Substring should begin abs(start) from the end of the string when start is negative. start: 0,
name: "Return the substring with negative start index", end: 3,
key: "key5", want: "Test",
substrFunc: server.SubStr, wantErr: false,
presetValue: "Test String Five", },
start: -11, {
end: 10, // Return the substring with negative start index.
want: "String", // Substring should begin abs(start) from the end of the string when start is negative.
wantErr: false, name: "Return the substring with negative start index",
}, key: "substr_key5",
{ substrFunc: server.SubStr,
// Return reverse substring with end index smaller than start index. presetValue: "Test String Five",
// When end index is smaller than start index, the 2 indices are reversed. start: -11,
name: "Return reverse substring with end index smaller than start index", end: 10,
key: "key6", want: "String",
substrFunc: server.SubStr, wantErr: false,
presetValue: "Test String Six", },
start: 4, {
end: 0, // Return reverse substring with end index smaller than start index.
want: "tseT", // When end index is smaller than start index, the 2 indices are reversed.
}, name: "Return reverse substring with end index smaller than start index",
{ key: "substr_key6",
name: "Return substring within the range of the string", substrFunc: server.SubStr,
key: "key7", presetValue: "Test String Six",
substrFunc: server.GetRange, start: 4,
presetValue: "Test String One", end: 0,
start: 5, want: "tseT",
end: 10, },
want: "String", {
wantErr: false, name: "Return substring within the range of the string",
}, key: "substr_key7",
{ substrFunc: server.GetRange,
name: "Return substring at the end of the string with exact end index", presetValue: "Test String One",
key: "key8", start: 5,
substrFunc: server.GetRange, end: 10,
presetValue: "Test String Two", want: "String",
start: 12, wantErr: false,
end: 14, },
want: "Two", {
wantErr: false, name: "Return substring at the end of the string with exact end index",
}, key: "substr_key8",
{ substrFunc: server.GetRange,
name: "Return substring at the end of the string with end index greater than length", presetValue: "Test String Two",
key: "key9", start: 12,
substrFunc: server.GetRange, end: 14,
presetValue: "Test String Three", want: "Two",
start: 12, wantErr: false,
end: 75, },
want: "Three", {
}, name: "Return substring at the end of the string with end index greater than length",
{ key: "substr_key9",
name: "Return the substring at the start of the string with 0 start index", substrFunc: server.GetRange,
key: "key10", presetValue: "Test String Three",
substrFunc: server.GetRange, start: 12,
presetValue: "Test String Four", end: 75,
start: 0, want: "Three",
end: 3, },
want: "Test", {
wantErr: false, name: "Return the substring at the start of the string with 0 start index",
}, key: "substr_key10",
{ substrFunc: server.GetRange,
// Return the substring with negative start index. presetValue: "Test String Four",
// Substring should begin abs(start) from the end of the string when start is negative. start: 0,
name: "Return the substring with negative start index", end: 3,
key: "key11", want: "Test",
substrFunc: server.GetRange, wantErr: false,
presetValue: "Test String Five", },
start: -11, {
end: 10, // Return the substring with negative start index.
want: "String", // Substring should begin abs(start) from the end of the string when start is negative.
wantErr: false, name: "Return the substring with negative start index",
}, key: "substr_key11",
{ substrFunc: server.GetRange,
// Return reverse substring with end index smaller than start index. presetValue: "Test String Five",
// When end index is smaller than start index, the 2 indices are reversed. start: -11,
name: "Return reverse substring with end index smaller than start index", end: 10,
key: "key12", want: "String",
substrFunc: server.GetRange, wantErr: false,
presetValue: "Test String Six", },
start: 4, {
end: 0, // Return reverse substring with end index smaller than start index.
want: "tseT", // When end index is smaller than start index, the 2 indices are reversed.
}, name: "Return reverse substring with end index smaller than start index",
} key: "substr_key12",
for _, tt := range tests { substrFunc: server.GetRange,
t.Run(tt.name, func(t *testing.T) { presetValue: "Test String Six",
if tt.presetValue != nil { start: 4,
err := presetValue(server, context.Background(), tt.key, tt.presetValue) end: 0,
if err != nil { want: "tseT",
t.Error(err) },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if tt.presetValue != nil {
err := presetValue(server, context.Background(), tt.key, tt.presetValue)
if err != nil {
t.Error(err)
return
}
}
got, err := tt.substrFunc(tt.key, tt.start, tt.end)
if (err != nil) != tt.wantErr {
t.Errorf("GETRANGE() error = %v, wantErr %v", err, tt.wantErr)
return return
} }
} if got != tt.want {
got, err := tt.substrFunc(tt.key, tt.start, tt.end) t.Errorf("GETRANGE() got = %v, want %v", got, tt.want)
if (err != nil) != tt.wantErr { }
t.Errorf("GETRANGE() error = %v, wantErr %v", err, tt.wantErr) })
return }
} })
if got != tt.want {
t.Errorf("GETRANGE() got = %v, want %v", got, tt.want)
}
})
}
}
func TestSugarDB_SETRANGE(t *testing.T) { t.Run("TestSugarDB_SETRANGE", func(t *testing.T) {
server := createSugarDB() t.Parallel()
tests := []struct {
tests := []struct { name string
name string presetValue interface{}
presetValue interface{} key string
key string offset int
offset int new string
new string want int
want int wantErr bool
wantErr bool }{
}{ {
{ name: "Test that SETRANGE on non-existent string creates new string",
name: "Test that SETRANGE on non-existent string creates new string", key: "setrange_key1",
key: "key1", presetValue: "",
presetValue: "", offset: 10,
offset: 10, new: "New String Value",
new: "New String Value", want: len("New String Value"),
want: len("New String Value"), wantErr: false,
wantErr: false, },
}, {
{ name: "Test SETRANGE with an offset that leads to a longer resulting string",
name: "Test SETRANGE with an offset that leads to a longer resulting string", key: "setrange_key2",
key: "key2", presetValue: "Original String Value",
presetValue: "Original String Value", offset: 16,
offset: 16, new: "Portion Replaced With This New String",
new: "Portion Replaced With This New String", want: len("Original String Portion Replaced With This New String"),
want: len("Original String Portion Replaced With This New String"), wantErr: false,
wantErr: false, },
}, {
{ name: "SETRANGE with negative offset prepends the string",
name: "SETRANGE with negative offset prepends the string", key: "setrange_key3",
key: "key3", presetValue: "This is a preset value",
presetValue: "This is a preset value", offset: -10,
offset: -10, new: "Prepended ",
new: "Prepended ", want: len("Prepended This is a preset value"),
want: len("Prepended This is a preset value"), wantErr: false,
wantErr: false, },
}, {
{ name: "SETRANGE with offset that embeds new string inside the old string",
name: "SETRANGE with offset that embeds new string inside the old string", key: "setrange_key4",
key: "key4", presetValue: "This is a preset value",
presetValue: "This is a preset value", offset: 0,
offset: 0, new: "That",
new: "That", want: len("That is a preset value"),
want: len("That is a preset value"), wantErr: false,
wantErr: false, },
}, {
{ name: "SETRANGE with offset longer than original lengths appends the string",
name: "SETRANGE with offset longer than original lengths appends the string", key: "setrange_key5",
key: "key5", presetValue: "This is a preset value",
presetValue: "This is a preset value", offset: 100,
offset: 100, new: " Appended",
new: " Appended", want: len("This is a preset value Appended"),
want: len("This is a preset value Appended"), wantErr: false,
wantErr: false, },
}, {
{ name: "SETRANGE with offset on the last character replaces last character with new string",
name: "SETRANGE with offset on the last character replaces last character with new string", key: "setrange_key6",
key: "key6", presetValue: "This is a preset value",
presetValue: "This is a preset value", offset: len("This is a preset value") - 1,
offset: len("This is a preset value") - 1, new: " replaced",
new: " replaced", want: len("This is a preset valu replaced"),
want: len("This is a preset valu replaced"), wantErr: false,
wantErr: false, },
}, }
} for _, tt := range tests {
for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Parallel()
if tt.presetValue != nil { if tt.presetValue != nil {
err := presetValue(server, context.Background(), tt.key, tt.presetValue) err := presetValue(server, context.Background(), tt.key, tt.presetValue)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return
}
}
got, err := server.SetRange(tt.key, tt.offset, tt.new)
if (err != nil) != tt.wantErr {
t.Errorf("SETRANGE() error = %v, wantErr %v", err, tt.wantErr)
return return
} }
} if got != tt.want {
got, err := server.SetRange(tt.key, tt.offset, tt.new) t.Errorf("SETRANGE() got = %v, want %v", got, tt.want)
if (err != nil) != tt.wantErr { }
t.Errorf("SETRANGE() error = %v, wantErr %v", err, tt.wantErr) })
return }
} })
if got != tt.want {
t.Errorf("SETRANGE() got = %v, want %v", got, tt.want)
}
})
}
}
func TestSugarDB_STRLEN(t *testing.T) { t.Run("TestSugarDB_STRLEN", func(t *testing.T) {
server := createSugarDB() t.Parallel()
tests := []struct {
tests := []struct { name string
name string presetValue interface{}
presetValue interface{} key string
key string want int
want int wantErr bool
wantErr bool }{
}{ {
{ name: "Return the correct string length for an existing string",
name: "Return the correct string length for an existing string", key: "strlen_key1",
key: "key1", presetValue: "Test String",
presetValue: "Test String", want: len("Test String"),
want: len("Test String"), wantErr: false,
wantErr: false, },
}, {
{ name: "If the string does not exist, return 0",
name: "If the string does not exist, return 0", key: "strlen_key2",
key: "key2", presetValue: "",
presetValue: "", want: 0,
want: 0, wantErr: false,
wantErr: false, },
}, }
} for _, tt := range tests {
for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Parallel()
if tt.presetValue != nil { if tt.presetValue != nil {
err := presetValue(server, context.Background(), tt.key, tt.presetValue) err := presetValue(server, context.Background(), tt.key, tt.presetValue)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return
}
}
got, err := server.StrLen(tt.key)
if (err != nil) != tt.wantErr {
t.Errorf("STRLEN() error = %v, wantErr %v", err, tt.wantErr)
return return
} }
} if got != tt.want {
got, err := server.StrLen(tt.key) t.Errorf("STRLEN() got = %v, want %v", got, tt.want)
if (err != nil) != tt.wantErr { }
t.Errorf("STRLEN() error = %v, wantErr %v", err, tt.wantErr) })
return }
} })
if got != tt.want {
t.Errorf("STRLEN() got = %v, want %v", got, tt.want)
}
})
}
}
func TestSugarDB_APPEND(t *testing.T) { t.Run("TestSugarDB_APPEND", func(t *testing.T) {
server := createSugarDB() t.Parallel()
tests := []struct { tests := []struct {
name string name string
presetValue interface{} presetValue interface{}
key string key string
value string value string
want int want int
wantErr bool wantErr bool
}{ }{
{ {
name: "Test APPEND with no preset value", name: "Test APPEND with no preset value",
key: "key1", key: "append_key1",
value: "Hello ", value: "Hello ",
want: 6, want: 6,
wantErr: false, wantErr: false,
}, },
{ {
name: "Test APPEND with preset value", name: "Test APPEND with preset value",
presetValue: "Hello ", presetValue: "Hello ",
key: "key2", key: "append_key2",
value: "World", value: "World",
want: 11, want: 11,
wantErr: false, wantErr: false,
}, },
{ {
name: "Test APPEND with integer preset value", name: "Test APPEND with integer preset value",
key: "key3", key: "append_key3",
presetValue: 10, presetValue: 10,
value: "Hello ", value: "Hello ",
wantErr: true, wantErr: true,
}, },
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if tt.presetValue != nil { t.Parallel()
err := presetValue(server, context.Background(), tt.key, tt.presetValue) if tt.presetValue != nil {
if err != nil { err := presetValue(server, context.Background(), tt.key, tt.presetValue)
t.Error(err) if err != nil {
t.Error(err)
return
}
}
got, err := server.Append(tt.key, tt.value)
if (err != nil) != tt.wantErr {
t.Errorf("APPEND() error = %v, wantErr %v", err, tt.wantErr)
return return
} }
} if got != tt.want {
got, err := server.Append(tt.key, tt.value) t.Errorf("APPEND() got = %v, want %v", got, tt.want)
if (err != nil) != tt.wantErr { }
t.Errorf("APPEND() error = %v, wantErr %v", err, tt.wantErr) })
return }
} })
if got != tt.want {
t.Errorf("APPEND() got = %v, want %v", got, tt.want)
}
})
}
} }

View File

@@ -212,6 +212,8 @@ func makeCluster(size int) ([]ClientServerPair, error) {
} }
func Test_Cluster(t *testing.T) { func Test_Cluster(t *testing.T) {
t.Parallel()
nodes, err := makeCluster(5) nodes, err := makeCluster(5)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
@@ -274,9 +276,7 @@ func Test_Cluster(t *testing.T) {
// Yield // Yield
ticker := time.NewTicker(200 * time.Millisecond) ticker := time.NewTicker(200 * time.Millisecond)
defer func() { defer ticker.Stop()
ticker.Stop()
}()
<-ticker.C <-ticker.C
// Check if the data has been replicated on a quorum (majority of the cluster). // Check if the data has been replicated on a quorum (majority of the cluster).
@@ -322,10 +322,8 @@ func Test_Cluster(t *testing.T) {
// Yield // Yield
ticker := time.NewTicker(200 * time.Millisecond) ticker := time.NewTicker(200 * time.Millisecond)
defer func() {
ticker.Stop()
}()
<-ticker.C <-ticker.C
ticker.Stop()
// Check if the data has been replicated on a quorum (majority of the cluster). // Check if the data has been replicated on a quorum (majority of the cluster).
quorum := int(math.Ceil(float64(len(nodes)/2)) + 1) quorum := int(math.Ceil(float64(len(nodes)/2)) + 1)
@@ -963,8 +961,18 @@ func Test_Standalone(t *testing.T) {
name: "1. Snapshot in embedded instance", name: "1. Snapshot in embedded instance",
dataDir: path.Join(dataDir, "embedded_instance"), dataDir: path.Join(dataDir, "embedded_instance"),
values: map[int]map[string]string{ values: map[int]map[string]string{
0: {"key5": "value-05", "key6": "value-06", "key7": "value-07", "key8": "value-08"}, 0: {
1: {"key5": "value-15", "key6": "value-16", "key7": "value-17", "key8": "value-18"}, "test_snapshot_key5": "value-05",
"test_snapshot_key6": "value-06",
"test_snapshot_key7": "value-07",
"test_snapshot_key8": "value-08",
},
1: {
"test_snapshot_key5": "value-15",
"test_snapshot_key6": "value-16",
"test_snapshot_key7": "value-17",
"test_snapshot_key8": "value-18",
},
}, },
snapshotFunc: func(mockServer *SugarDB) error { snapshotFunc: func(mockServer *SugarDB) error {
if _, err := mockServer.Save(); err != nil { if _, err := mockServer.Save(); err != nil {
@@ -1022,7 +1030,7 @@ func Test_Standalone(t *testing.T) {
} }
// Yield to allow snapshot to complete sync. // Yield to allow snapshot to complete sync.
ticker := time.NewTicker(20 * time.Millisecond) ticker := time.NewTicker(200 * time.Millisecond)
<-ticker.C <-ticker.C
ticker.Stop() ticker.Stop()
@@ -1121,10 +1129,10 @@ func Test_Standalone(t *testing.T) {
<-ticker.C <-ticker.C
// Rewrite AOF // Rewrite AOF
if _, err := mockServer.RewriteAOF(); err != nil { mockServer.RewriteAOF()
t.Error(err)
return // Yield
} <-ticker.C
// Perform write commands from "after-rewrite" // Perform write commands from "after-rewrite"
for key, value := range data["after-rewrite"] { for key, value := range data["after-rewrite"] {