You need to sign in or sign up before continuing.
Commit 4f54a90d authored by Sushant Mahajan's avatar Sushant Mahajan

added concurrency test cases and added time to run in README.md

parent eaf5828f
...@@ -22,3 +22,5 @@ In this project we have implemented the following commands: ...@@ -22,3 +22,5 @@ In this project we have implemented the following commands:
* delete - Deletes a key from the server, error if key is expired or not found. * delete - Deletes a key from the server, error if key is expired or not found.
All functions use locking mechanisms to provide concurrency. For performance reasons, if a user asks for a key and it is expired, the user is notified as not found and the key is deleted. All functions use locking mechanisms to provide concurrency. For performance reasons, if a user asks for a key and it is expired, the user is notified as not found and the key is deleted.
Note: Time taken to run all tesk cases 97.555 sec (150 concurrent clients sending 250 commands each)
...@@ -14,16 +14,18 @@ type TestCasePair struct { ...@@ -14,16 +14,18 @@ type TestCasePair struct {
expected []byte expected []byte
} }
const MAX_CLIENTS = 150
const MAX_CMD_NUM = 250
//this test function will start tests for various commands, one client at a time //this test function will start tests for various commands, one client at a time
func TestSerial(t *testing.T) { func TestCommands(t *testing.T) {
go main() go main()
//give some time for server to initialize //give some time for server to initialize
time.Sleep(time.Second) time.Sleep(time.Second)
testIndividualCommands(t) testIndividualCommands(t)
testRapidCommands(t) testRapidCommands(t)
ReInitServer() ReInitServer()
//testMaxClients(t) testConcurrentCommands(t)
//testConcurrentCommands(t)
} }
func testIndividualCommands(t *testing.T) { func testIndividualCommands(t *testing.T) {
...@@ -218,17 +220,146 @@ func testRapidCommands(t *testing.T) { ...@@ -218,17 +220,146 @@ func testRapidCommands(t *testing.T) {
} }
} }
func testMaxClients(t *testing.T) { func testConcurrentCommands(t *testing.T) {
//conn, err := net.Dial("localhost", ":5000") testConcurrentSet(t)
table := make(map[int]*net.Conn) testConcurrentGet(t)
i := 0 testConcurrentGetm(t)
for i < 1000 { testConcurrentCas(t)
testConcurrentDelete(t)
}
func testConcurrentSet(t *testing.T) {
ch := make(chan int)
for i := 0; i < MAX_CLIENTS; i++ {
conn, err := net.Dial("tcp", ":5000")
defer conn.Close()
if err != nil {
t.Errorf("too many clients")
}
go runSet(t, conn, i, ch)
}
num := 0
for num < MAX_CLIENTS {
num += <-ch
//fmt.Println(num)
}
}
func testConcurrentGet(t *testing.T) {
ch := make(chan int)
for i := 0; i < MAX_CLIENTS; i++ {
conn, err := net.Dial("tcp", ":5000")
defer conn.Close()
if err != nil {
t.Errorf("too many clients")
}
go runGet(t, conn, i, ch)
}
num := 0
for num < MAX_CLIENTS {
num += <-ch
//fmt.Println(num)
}
}
func testConcurrentCas(t *testing.T) {
ch := make(chan int)
for i := 0; i < MAX_CLIENTS; i++ {
conn, err := net.Dial("tcp", ":5000")
defer conn.Close()
if err != nil {
t.Errorf("too many clients")
}
go runCas(t, conn, i, ch)
}
num := 0
for num < MAX_CLIENTS {
num += <-ch
//fmt.Println(num)
}
}
func testConcurrentGetm(t *testing.T) {
ch := make(chan int)
for i := 0; i < MAX_CLIENTS; i++ {
conn, err := net.Dial("tcp", ":5000")
defer conn.Close()
if err != nil {
t.Errorf("too many clients")
}
go runGetm(t, conn, i, ch)
}
num := 0
for num < MAX_CLIENTS {
num += <-ch
//fmt.Println(num)
}
}
func testConcurrentDelete(t *testing.T) {
ch := make(chan int)
for i := 0; i < MAX_CLIENTS; i++ {
conn, err := net.Dial("tcp", ":5000") conn, err := net.Dial("tcp", ":5000")
defer conn.Close()
if err != nil { if err != nil {
t.Errorf("error", err.Error()) t.Errorf("too many clients")
} }
table[i] = &conn go runDelete(t, conn, i, ch)
i++ }
//fmt.Println(len(table)) num := 0
for num < MAX_CLIENTS {
num += <-ch
//fmt.Println(num)
}
}
func runSet(t *testing.T, conn net.Conn, i int, ch chan int) {
version := 1
for j := 0; j < MAX_CMD_NUM; j++ {
cases := TestCasePair{[]byte("set somekey" + strconv.Itoa(i) + " 0 5" + CRLF + "12345" + CRLF), []byte("OK " + strconv.Itoa(version) + CRLF)}
doTest(t, cases, conn)
//fmt.Println(i)
version++
}
//fmt.Println(i)
ch <- 1
}
func runGet(t *testing.T, conn net.Conn, i int, ch chan int) {
for j := 0; j < MAX_CMD_NUM; j++ {
cases := TestCasePair{[]byte("get somekey" + strconv.Itoa(i) + CRLF), []byte("VALUE 5" + CRLF + "12345" + CRLF)}
doTest(t, cases, conn)
//fmt.Println(i)
}
//fmt.Println(i)
ch <- 1
}
func runCas(t *testing.T, conn net.Conn, i int, ch chan int) {
version := MAX_CMD_NUM
for j := 0; j < MAX_CMD_NUM; j++ {
cases := TestCasePair{[]byte("cas somekey" + strconv.Itoa(i) + " 0 " + strconv.Itoa(version) + " 5" + CRLF + "12345" + CRLF), []byte("OK " + strconv.Itoa(version+1) + CRLF)}
doTest(t, cases, conn)
//fmt.Println(i)
version++
} }
//fmt.Println(i)
ch <- 1
}
func runGetm(t *testing.T, conn net.Conn, i int, ch chan int) {
version := MAX_CMD_NUM
for j := 0; j < MAX_CMD_NUM; j++ {
cases := TestCasePair{[]byte("getm somekey" + strconv.Itoa(i) + CRLF), []byte("VALUE " + strconv.Itoa(version) + " 0 5" + CRLF + "12345" + CRLF)}
doTest(t, cases, conn)
//fmt.Println(i)
}
//fmt.Println(i)
ch <- 1
}
func runDelete(t *testing.T, conn net.Conn, i int, ch chan int) {
cases := TestCasePair{[]byte("delete somekey" + strconv.Itoa(i) + CRLF), []byte("DELETED" + CRLF)}
doTest(t, cases, conn)
ch <- 1
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment