예제 #1
0
func Test_Stats(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)

	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	q, err := repo.GetQueue("test")
	assert.Nil(t, err)

	q.Enqueue([]byte("1"))

	err = controller.Stats()
	statsResponse := "STAT uptime 0\r\n" +
		fmt.Sprintf("STAT time %d\r\n", time.Now().Unix()) +
		"STAT version " + repo.Stats.Version + "\r\n" +
		"STAT curr_connections 1\r\n" +
		"STAT total_connections 1\r\n" +
		"STAT cmd_get 0\r\n" +
		"STAT cmd_set 0\r\n" +
		fmt.Sprintf("STAT queue_test_items %d\r\n", q.Length()) +
		"STAT queue_test_open_transactions 0\r\n" +
		"END\r\n"
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), statsResponse)
}
예제 #2
0
func (self *Service) Serve(listener *net.TCPListener) {
	defer self.wg.Done()

	log.Println("initializing...")
	var err error
	self.repo, err = repository.Initialize(self.dataDir)
	log.Println("data directory: ", self.dataDir)
	if err != nil {
		log.Fatal(err)
	}

	for {
		select {
		case <-self.ch:
			log.Println("stopping listening on", listener.Addr())
			listener.Close()
			return
		default:
		}
		listener.SetDeadline(time.Now().Add(1e9))
		conn, err := listener.AcceptTCP()
		if nil != err {
			if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() {
				continue
			}
			log.Println(err)
		}
		self.wg.Add(1)
		go self.HandleConnection(conn)
	}
}
예제 #3
0
func Test_Delete(t *testing.T) {
	repo, _ := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)
	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	q, err := repo.GetQueue("test")
	assert.Nil(t, err)

	q.Enqueue([]byte("1"))

	command := []string{"delete", "test"}
	err = controller.Delete(command)
	assert.Nil(t, err)
	response, err := mockTCPConn.WriteBuffer.ReadString('\n')
	assert.Nil(t, err)
	assert.Equal(t, "END\r\n", response)

	command = []string{"DELETE", "test"}
	err = controller.Delete(command)
	assert.Nil(t, err)
	response, err = mockTCPConn.WriteBuffer.ReadString('\n')
	assert.Nil(t, err)
	assert.Equal(t, "END\r\n", response)
}
예제 #4
0
// Initialize test queue with 2 items
// gets test/open = value
// gets test = error
// GETS test/t=10/close/open = value
func Test_Gets(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)

	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	repo.FlushQueue("test")
	q, err := repo.GetQueue("test")
	assert.Nil(t, err)

	q.Enqueue([]byte("1"))
	q.Enqueue([]byte("2"))

	// gets test/open = 1
	command := []string{"gets", "test"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "VALUE test 0 1\r\n1\r\nEND\r\n", mockTCPConn.WriteBuffer.String())

	mockTCPConn.WriteBuffer.Reset()

	// GETS test/t=10/close/open = 2
	command = []string{"GETS", "test/t=10/close/open"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "VALUE test 0 1\r\n2\r\nEND\r\n", mockTCPConn.WriteBuffer.String())

	mockTCPConn.WriteBuffer.Reset()

}
예제 #5
0
// Initialize test queue with 2 items
// get test/open = value
// FinishSession (disconnect)
// NewSession
// get test = same value
func Test_GetOpen_Disconnect(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)

	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	repo.FlushQueue("test")
	q, err := repo.GetQueue("test")
	assert.Nil(t, err)

	q.Enqueue([]byte("1"))
	q.Enqueue([]byte("2"))

	// get test/open = value
	command := []string{"get", "test/open"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "VALUE test 0 1\r\n1\r\nEND\r\n", mockTCPConn.WriteBuffer.String())

	mockTCPConn.WriteBuffer.Reset()

	controller.FinishSession()

	mockTCPConn = NewMockTCPConn()
	controller = NewSession(mockTCPConn, repo)

	// get test = same value
	command = []string{"get", "test"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "VALUE test 0 1\r\n1\r\nEND\r\n", mockTCPConn.WriteBuffer.String())
}
예제 #6
0
func Test_Version(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)
	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	err = controller.Version()
	assert.Nil(t, err)
	assert.Equal(t, "VERSION "+repo.Stats.Version+"\r\n", mockTCPConn.WriteBuffer.String())
}
예제 #7
0
func Test_SendError(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)

	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	controller.SendError("Test error message")
	assert.Equal(t, "Test error message\r\n", mockTCPConn.WriteBuffer.String())
}
예제 #8
0
func Test_UnknownCommand(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)

	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	err = controller.UnknownCommand()
	assert.Equal(t, "ERROR Unknown command", err.Error())
	assert.Equal(t, "ERROR Unknown command\r\n", mockTCPConn.WriteBuffer.String())

}
예제 #9
0
func Test_NewSession_FinishSession(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)

	mockTCPConn := NewMockTCPConn()
	c := NewSession(mockTCPConn, repo)

	assert.Equal(t, uint64(1), repo.Stats.CurrentConnections)
	assert.Equal(t, uint64(1), repo.Stats.TotalConnections)

	c.FinishSession()
	assert.Equal(t, uint64(0), repo.Stats.CurrentConnections)
}
예제 #10
0
func Test_FlushAll(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)

	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	err = controller.FlushAll()
	assert.Nil(t, err)
	response, err := mockTCPConn.WriteBuffer.ReadString('\n')
	assert.Nil(t, err)
	assert.Equal(t, response, "END\r\n")
}
예제 #11
0
// Initialize queue 'test' with 1 item
// get test = value
// get test = empty
// get test/close = empty
// get test/abort = empty
func Test_Get(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)

	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	q, err := repo.GetQueue("test")
	assert.Nil(t, err)

	q.Enqueue([]byte("0123456789"))

	// When queue has items
	// get test = value
	command := []string{"get", "test"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "VALUE test 0 10\r\n0123456789\r\nEND\r\n", mockTCPConn.WriteBuffer.String())

	mockTCPConn.WriteBuffer.Reset()

	// When queue is empty
	// get test = empty
	command = []string{"get", "test"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "END\r\n", mockTCPConn.WriteBuffer.String())

	mockTCPConn.WriteBuffer.Reset()

	// When queue is empty
	// get test/close = empty
	command = []string{"get", "test/close"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "END\r\n", mockTCPConn.WriteBuffer.String())

	mockTCPConn.WriteBuffer.Reset()

	// When queue is empty
	// get test/abort = empty
	command = []string{"get", "test/close"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "END\r\n", mockTCPConn.WriteBuffer.String())
}
예제 #12
0
func Test_ReadFirstMessage(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)

	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	fmt.Fprintf(&mockTCPConn.ReadBuffer, "GET work\r\n")
	message, err := controller.ReadFirstMessage()
	assert.Nil(t, err)
	assert.Equal(t, "GET work\r\n", message)

	fmt.Fprintf(&mockTCPConn.ReadBuffer, "SET work 0 0 10\r\n0123456789\r\n")
	message, err = controller.ReadFirstMessage()
	assert.Nil(t, err)
	assert.Equal(t, "SET work 0 0 10\r\n", message)
}
예제 #13
0
func Test_Set(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)

	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	command := []string{"set", "test", "0", "0", "10"}
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "0123567890\r\n")

	err = controller.Set(command)
	assert.Nil(t, err)
	assert.Equal(t, "STORED\r\n", mockTCPConn.WriteBuffer.String())

	mockTCPConn.WriteBuffer.Reset()

	command = []string{"set", "test", "0", "1"}
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "0\r\n")

	err = controller.Set(command)
	assert.Equal(t, "ERROR Invalid input", err.Error())

	mockTCPConn.WriteBuffer.Reset()

	command = []string{"set", "test", "0", "0", "invalid"}
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "0123567890\r\n")

	err = controller.Set(command)
	assert.Equal(t, "ERROR Invalid <bytes> number", err.Error())

	mockTCPConn.WriteBuffer.Reset()

	command = []string{"set", "test", "0", "0", "10"}
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "01235678901234567890\r\n")

	err = controller.Set(command)
	assert.Equal(t, "CLIENT_ERROR bad data chunk", err.Error())
}
예제 #14
0
func Test_Dispatch(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)

	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	// Command: set test 0 0 1
	// 1
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "set test 0 0 1\r\n1\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), "STORED\r\n")

	mockTCPConn.WriteBuffer.Reset()

	// Command: SET test 0 0 2
	// 20
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "SET test 0 0 2\r\n")
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "20\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), "STORED\r\n")

	mockTCPConn.WriteBuffer.Reset()

	// Command: set test 0 0 10
	// 123
	// 12
	// 1
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "set test 0 0 10\r\n")
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "123\r\n")
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "12\r\n")
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "1\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), "STORED\r\n")

	mockTCPConn.WriteBuffer.Reset()

	// Command: get test
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "get test\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), "VALUE test 0 1\r\n1\r\nEND\r\n")

	mockTCPConn.WriteBuffer.Reset()

	// Command: get test/open
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "get test/open\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), "VALUE test 0 2\r\n20\r\nEND\r\n")

	mockTCPConn.WriteBuffer.Reset()

	// Command: GET test/abort
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "GET test/abort\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), "END\r\n")

	mockTCPConn.WriteBuffer.Reset()

	// Command: get test/open
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "get test/open\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), "VALUE test 0 2\r\n20\r\nEND\r\n")

	mockTCPConn.WriteBuffer.Reset()

	// Command: get test/close
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "get test/close\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), "END\r\n")

	mockTCPConn.WriteBuffer.Reset()

	// Command: version
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "version\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), "VERSION "+repo.Stats.Version+"\r\n")

	mockTCPConn.WriteBuffer.Reset()

	// Command: STATS
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "STATS\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	response, _ := mockTCPConn.WriteBuffer.ReadString('\n')
	fmt.Println(response)
	assert.True(t, strings.HasPrefix(response, "STAT uptime"))

	mockTCPConn.WriteBuffer.Reset()

	// Command: flush test
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "flush test\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), "END\r\n")

	mockTCPConn.WriteBuffer.Reset()

	// Command: DELETE test
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "DELETE test\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), "END\r\n")

	mockTCPConn.WriteBuffer.Reset()

	// Command: flush_all
	fmt.Fprintf(&mockTCPConn.ReadBuffer, "flush_all\r\n")
	err = controller.Dispatch()
	assert.Nil(t, err)
	assert.Equal(t, mockTCPConn.WriteBuffer.String(), "END\r\n")
}
예제 #15
0
// Initialize test queue with 4 items
// get test/open = value
// get test = error
// get test/close = empty
// get test/open = value
// get test/open = error
// get test/abort = empty
// get test/open = value
// get test/peek = next value
// get test/close = empty
func Test_GetOpen(t *testing.T) {
	repo, err := repository.Initialize(dir)
	defer repo.CloseAllQueues()
	assert.Nil(t, err)

	mockTCPConn := NewMockTCPConn()
	controller := NewSession(mockTCPConn, repo)

	q, err := repo.GetQueue("test")
	assert.Nil(t, err)

	q.Enqueue([]byte("1"))
	q.Enqueue([]byte("2"))
	q.Enqueue([]byte("3"))
	q.Enqueue([]byte("4"))

	// get test/open = value
	command := []string{"get", "test/open"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "VALUE test 0 1\r\n1\r\nEND\r\n", mockTCPConn.WriteBuffer.String())

	mockTCPConn.WriteBuffer.Reset()

	// get test = error
	command = []string{"get", "test"}
	err = controller.Get(command)
	assert.Equal(t, "CLIENT_ERROR Close current item first", err.Error())

	mockTCPConn.WriteBuffer.Reset()

	// get test/close = value
	command = []string{"get", "test/close"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "END\r\n", mockTCPConn.WriteBuffer.String())

	mockTCPConn.WriteBuffer.Reset()

	// get test/open = value
	command = []string{"get", "test/open"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "VALUE test 0 1\r\n2\r\nEND\r\n", mockTCPConn.WriteBuffer.String())

	// get test/open = error
	command = []string{"get", "test/open"}
	err = controller.Get(command)
	assert.Equal(t, err.Error(), "CLIENT_ERROR Close current item first")

	mockTCPConn.WriteBuffer.Reset()

	// get test/abort = value
	command = []string{"get", "test/abort"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "END\r\n", mockTCPConn.WriteBuffer.String())

	mockTCPConn.WriteBuffer.Reset()

	// get test/open = value
	command = []string{"get", "test/open"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "VALUE test 0 1\r\n2\r\nEND\r\n", mockTCPConn.WriteBuffer.String())

	mockTCPConn.WriteBuffer.Reset()

	// get test/peek = value
	command = []string{"get", "test/peek"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "VALUE test 0 1\r\n3\r\nEND\r\n", mockTCPConn.WriteBuffer.String())

	mockTCPConn.WriteBuffer.Reset()

	// get test/close = value
	command = []string{"get", "test/close"}
	err = controller.Get(command)
	assert.Nil(t, err)
	assert.Equal(t, "END\r\n", mockTCPConn.WriteBuffer.String())
}