Commit 2373e395 authored by Sushant Mahajan's avatar Sushant Mahajan

completed implementation, added test cases

parent e0747868
package main
import (
"fmt"
"raft"
)
const (
SERVERS = 5
)
func main() {
dummyCh := make(chan bool, 1)
fmt.Println("Started")
for i := 1; i <= 5; i++ {
go raft.Start(i, true)
}
if <-dummyCh {
fmt.Println("khattam")
}
}
This diff is collapsed.
......@@ -216,7 +216,7 @@ func main() {
go initInterServerCommunication(server, rft, ch2)
time.Sleep(100 * time.Millisecond)
rft.Loop()
go rft.Loop()
for <-ch1 && <-ch2 {
......
......@@ -20,34 +20,37 @@ const (
)
type Testpair struct {
to_server []byte
from_server []byte
test []byte
expected []byte
}
var LeaderId int
var Info *log.Logger
var logger *log.Logger
var keyPrefix int
func getPrefix() int {
keyPrefix++
return keyPrefix
}
//
func TestAll(t *testing.T) {
//start the servers
initLogger()
initTestLogger()
for i := 0; i < NUM_SERVERS; i++ {
go startServers(i, t)
}
//wait for some time so that servers are ready
time.Sleep(5 * time.Second)
time.Sleep(8 * time.Second)
testPerformClientConnect(t)
testPerformSet(t, 1)
testPerformSet(t, 2)
testPerformSet(t, 3)
testPerformSet(t, 4)
//testKillLeader(t)
testCommands(t)
killServers()
}
//kill all servers, cleanup
func killServers() {
Info.Println("killing servers")
logger.Println("killing servers")
cmd := exec.Command("sh", "-c", "for i in `netstat -ntlp|grep server|awk '{print $7}'`; do kill -9 ${i%%/*}; done")
cmd.Run()
}
......@@ -66,6 +69,7 @@ func startServers(i int, t *testing.T) {
cmd.Run()
}
//check which server is the leader
func probeLeader(t *testing.T) (int, error) {
if conn, err := net.Dial("tcp", ":"+strconv.Itoa(9000)); err != nil {
t.Errorf("Could not connect")
......@@ -87,6 +91,7 @@ func probeLeader(t *testing.T) (int, error) {
}
}
//returns a connection to the leader server
func getLeaderConn(t *testing.T) net.Conn {
if conn, err := net.Dial("tcp", ":"+strconv.Itoa(9000+LeaderId)); err != nil {
t.Errorf("Could not connect")
......@@ -96,10 +101,10 @@ func getLeaderConn(t *testing.T) net.Conn {
}
}
func initLogger() {
// Logger Initializaion
//initialize logger meant for test cases
func initTestLogger() {
f, _ := os.OpenFile("test.log", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
Info = log.New(f, "INFO: ", log.Ldate|log.Lmicroseconds|log.Lshortfile)
logger = log.New(f, "INFO: ", log.Ldate|log.Lmicroseconds|log.Lshortfile)
}
func testPerformClientConnect(t *testing.T) {
......@@ -109,24 +114,96 @@ func testPerformClientConnect(t *testing.T) {
} else if id < 0 || id > 4 {
t.Errorf("Invalid leader id")
}
Info.Println("Leader Id:", id)
logger.Println("Leader Id:", id)
}
func testCommands(t *testing.T) {
testPerformMultipleSet(t, getPrefix(), 1) //check single set
testPerformMultipleSet(t, getPrefix(), 200)
testPerformCas(t)
testPerformMultipleCas(t, 200)
testPerformMultipleGet(t, 200)
testPerformMultipleGetm(t, 200)
testPerformMultipleDelete(t, 100)
}
func doTest(conn net.Conn, t *testing.T, test *Testpair) {
conn.Write(test.test)
buf := make([]byte, 1024)
time.Sleep(time.Millisecond * 20)
n, _ := conn.Read(buf)
if !bytes.Equal(test.expected, buf[:n]) {
logger.Println("test:", string(test.test), "got:", string(buf[:n]), "expected:", string(test.expected))
t.Errorf("invalid reply received", string(buf[:n]))
}
}
func testPerformSet(t *testing.T, i int) {
func testPerformMultipleSet(t *testing.T, start int, times int) {
if conn := getLeaderConn(t); conn != nil {
sending := []byte("set mykey" + strconv.Itoa(i) + " 100 3\r\nlul\r\n")
conn.Write(sending)
buffer := make([]byte, 1024)
time.Sleep(time.Millisecond * 50)
conn.Read(buffer)
n := bytes.Index(buffer, []byte{0})
str := string(buffer[:n])
if strings.TrimSpace(str) != "OK "+strconv.Itoa(1) {
t.Errorf("invalid reply received", str)
} else {
Info.Println(str)
defer conn.Close()
for i := start; i < start+times; i++ {
test := &Testpair{[]byte("set mykey" + strconv.Itoa(i) + " 0 3\r\nlul\r\n"), []byte("OK 1\r\n")}
doTest(conn, t, test)
}
} else {
t.Errorf("could not get leader connection")
}
}
func testPerformCas(t *testing.T) {
if conn := getLeaderConn(t); conn != nil {
defer conn.Close()
test := &Testpair{[]byte("cas mykey1 1000 1 3\r\nlul\r\n"), []byte("OK 2\r\n")}
doTest(conn, t, test)
} else {
t.Errorf("could not get leader connection")
}
}
func testPerformMultipleCas(t *testing.T, end int) {
if conn := getLeaderConn(t); conn != nil {
defer conn.Close()
for i := 0; i < end; i++ {
test := &Testpair{[]byte("cas mykey2 1000 " + strconv.Itoa(i+1) + " 3\r\nlul\r\n"), []byte("OK " + strconv.Itoa(i+2) + "\r\n")}
doTest(conn, t, test)
}
} else {
t.Errorf("could not get leader connection")
}
}
func testPerformMultipleGet(t *testing.T, end int) {
if conn := getLeaderConn(t); conn != nil {
defer conn.Close()
for i := 0; i < end; i++ {
test := &Testpair{[]byte("get mykey3\r\n"), []byte("VALUE 3\r\nlul\r\n")}
doTest(conn, t, test)
}
} else {
t.Errorf("could not get leader connection")
}
}
func testPerformMultipleGetm(t *testing.T, end int) {
if conn := getLeaderConn(t); conn != nil {
defer conn.Close()
for i := 0; i < end; i++ {
test := &Testpair{[]byte("getm mykey4\r\n"), []byte("VALUE 1 0 3\r\nlul\r\n")}
doTest(conn, t, test)
}
} else {
t.Errorf("could not get leader connection")
}
}
func testPerformMultipleDelete(t *testing.T, end int) {
if conn := getLeaderConn(t); conn != nil {
defer conn.Close()
for i := 0; i < end; i++ {
test := &Testpair{[]byte("delete mykey" + strconv.Itoa(i+1) + "\r\n"), []byte("DELETED\r\n")}
doTest(conn, t, test)
}
conn.Close()
} else {
t.Errorf("could not get leader connection")
}
......
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