Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM golang:latest

COPY . /go/src/TinyRedis

ENTRYPOINT ["/go/src/TinyRedis/TinyRedisServer/TinyRedisServer"]

EXPOSE 9090
49 changes: 49 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
SERVER_PATH := ./TinyRedisServer
CLIENT_PATH := ./TinyRedisClient
SERVER_FILE := ./TinyRedisServer/TinyRedisServer.go
CLIENT_FILE := ./TinyRedisClient/TinyRedisClient.go
SERVER_BIN := ./TinyRedisServer/TinyRedisServer
CLIENT_BIN := ./TinyRedisClient/TinyRedisClient

BECOME := sudo -E
VERSION := $(shell cat VERSION)
DOCKER_IMAGE := tinyredis:$(VERSION)
DOCKER_BUILDER := golang:1.11
RUNNER = docker run --rm -v $(CURDIR):/go/src/TinyRedis/$(SERVER_PATH)
RUNNER += $(DOCKER_ENVS) -w /go/src/TinyRedis/$(SERVER_PATH)

SEARCH_GOFILES = find -not -path '*/vendor/*' -type f -name "*.go" ! -name "*_test*"
BUILDER = $(RUNNER) $(DOCKER_BUILDER)
PORT := 9090

.PHONY: tinyredis
tinyredis:
docker build -t tinyredis .

.PHONY: build
build:
go build -o $(SERVER_BIN) $(SERVER_FILE)
go build -o $(CLIENT_BIN) $(CLIENT_FILE)

.PHONY: clean
clean:
$(BECOME) $(RM) $(SERVER_PATH)/TinyRedisServer
$(BECOME) $(RM) $(CLIENT_PATH)/TinyRedisClient

.PHONY: cleancontainer
cleancontainer:
docker rm tinyredis

.PHONY: check
check:
$(BECOME) $(BUILDER) sh -xc '\
test -z "`$(SEARCH_GOFILES) -exec gofmt -s -l {} \;`" \
&& test -z "`$(SEARCH_GOFILES) -exec go vet {} \;`"'

.PHONY: test
test:
go test $(SERVER_PATH) -coverprofile coverage.out
go test $(CLIENT_PATH) -coverprofile coverage_client.out
tail -n +2 coverage_client.out >> coverage.out
rm coverage_client.out
go tool cover -html coverage.out
69 changes: 69 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# TinyRedis

*TinyRedis* is a very lightweight app, divided into two parts, *TinyRedisServer* & *TinyRedisClient*, which work together just like [Redis](https://redis.io), but only with 4 commands: `SET`, `GET`, `DEL` and `EXIT`.

## Instruction
In order to launch the program, it's ought to do the following steps:
Get the app via following commands:
``` sh
git clone https://github.com/corvustristis/GoHomework
cd GoHomework
```

### Run via terminal
To do it, you have to install [Go](https://golang.org/) compiler. Then proceed to the following steps:
1) Launch *TinyRedisServer* from the folder of the same name:
```sh
./TinyRedisServer
```
There are options `-p` or `--port` for the choice of port and options `-m` or `--mode` for the choice of port.

2) Launch *TinyRedisClient* from another folder:
```sh
./TinyRedisClient
```
If you had chosen a port of your preferences in a previous step, don't forget to use it here as well. Optionally you can launch multiple clients at the same time, though you would be doing it at your own risk.

### Run via Docker
To proceed, you must have [Docker](https://www.docker.com/) installed. After that proceed to the following steps:

1) The project is already built and checked, but just in case you can delete binaries, compile them again, or check the code with `gofmt` and `go vet`, run some of the the following lines:
```sh
make clean build check
```

2) Build the project with:
```sh
make tinyredis
```

3) Launch server:
```sh
docker run -p 9090:9090 --name tinyredis tinyredis
```
There are options `-p` or `--port` for the choice of port and options `-m` or `--mode` for the choice of port. For example, if you have chosen custom port 3333, launch server via following:
```sh
docker run -p 3333:9090 --name tinyredis tinyredis --port=3333
```
If you have already lauched the container at least once, and there is a name conflict, do this:
```sh
make cleancontainer
```

4) Launch bash for *TinyRedisClient*:
```sh
docker exec -it tinyredis bash
```

5) Finally, lauch the client itself:
```sh
./src/TinyRedis/TinyRedisClient/TinyRedisClient
```
Don't forget about your custom port here!

## Testing
Thought test files are stored in each folder separately, you can test the code via following instruction right from the main folder:
```sh
make test
```
After it, the browser with test data will open, and you would be able to choose either server, or client coverage.
Binary file added TinyRedisClient/TinyRedisClient
Binary file not shown.
97 changes: 97 additions & 0 deletions TinyRedisClient/TinyRedisClient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package main

import (
"bufio"
"flag"
"fmt"
"net"
"os"
"time"
)

var port, host string

type cmdFlagHandler struct { // command line flag handler
options []string
defaultVal string
warning string
possibleRange []string
}

func main() {
address := getAddress() // address retrieving

conn := connectionAttempt(address) // connection handler
fmt.Printf("Connected to %s\n", address)
defer fmt.Println("Connection closed")

for {
fmt.Print(">>> ")
reader := bufio.NewReader(os.Stdin)
text, _ := reader.ReadString('\n') // got client's command
fmt.Fprintf(conn, text+"\n") // which is being sent via port

if len(text) > 4 { // closing connection with server
if text[0:4] == "EXIT" {
return
}
}

message, _ := bufio.NewReader(conn).ReadString('\n')
fmt.Print(message)
}
}

func getAddress() string { // returns complete server address
port, host = cmdFlagParse()
address := host + ":" + port
return address
}

func cmdFlagParse() (string, string) { // cmd flag parser
portHandler := cmdFlagHandler{ // default port and host data
options: []string{"p", "port"},
defaultVal: "9090",
warning: "specify port to use",
}
hostHandler := cmdFlagHandler{
options: []string{"h", "host"},
defaultVal: "127.0.0.1",
warning: "specify port to use",
}
// long and short forms are for long and short flags, e.g. -p and --port
portShortResult := flag.String(portHandler.options[0],
portHandler.defaultVal,
portHandler.warning)

portLongResult := flag.String(portHandler.options[1],
portHandler.defaultVal,
portHandler.warning)

hostShortResult := flag.String(hostHandler.options[0], hostHandler.defaultVal, hostHandler.warning)
hostLongResult := flag.String(hostHandler.options[1], hostHandler.defaultVal, hostHandler.warning)

flag.Parse()

var portResult, hostResult string
if *portLongResult != portHandler.defaultVal {
portResult = *portLongResult
} else {
portResult = *portShortResult
}

if *hostLongResult != hostHandler.defaultVal {
hostResult = *hostLongResult
} else {
hostResult = *hostShortResult
}
return portResult, hostResult
}

func connectionAttempt(addr string) net.Conn { // five seconds for dialing server
conn, err := net.DialTimeout("tcp", addr, 5*time.Second)
if err != nil {
panic(err)
}
return conn
}
24 changes: 24 additions & 0 deletions TinyRedisClient/TinyRedisClient_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import "testing"

func TestGetAddress(t *testing.T) {
address := getAddress()
if address == "127.0.0.1:9090" {
t.Log("\t[OK]")
} else {
t.Error("\t[ERR]\tError with address")
}
}

func TestConnectionAttempt(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Errorf("Error with connection")
} else {
t.Log("\t[OK]")
}
}()

connectionAttempt("127:0:0:1:9090")
}
1 change: 1 addition & 0 deletions TinyRedisServer/ServerData.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0 0
Binary file added TinyRedisServer/TinyRedisServer
Binary file not shown.
Loading