Skip to content

Commit

Permalink
More stringent tests
Browse files Browse the repository at this point in the history
  • Loading branch information
outdead committed Nov 14, 2020
1 parent 4840272 commit 42d1cb2
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 52 deletions.
7 changes: 6 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io"
"os"
"strings"

"github.com/gorcon/rcon-cli/internal/config"
"github.com/gorcon/rcon-cli/internal/logger"
Expand All @@ -21,7 +22,7 @@ const CommandQuit = ":q"

// Version displays service version in semantic versioning (http://semver.org/).
// Can be replaced while compiling with flag `-ldflags "-X main.Version=${VERSION}"`.
var Version = "develop"
var Version = "0.0.0-develop"

func main() {
app := NewApp(os.Stdin, os.Stdout)
Expand Down Expand Up @@ -118,6 +119,10 @@ func Execute(w io.Writer, ses session.Session, command string) error {
}

if result != "" {
result = strings.TrimSuffix(result, "\r\n")
result = strings.TrimSuffix(result, "\r")
result = strings.TrimSuffix(result, "\n")

fmt.Fprintln(w, result)
}

Expand Down
106 changes: 70 additions & 36 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package main

import (
"bytes"
"encoding/json"
"fmt"
"net/http/httptest"
"os"
"strings"
"testing"
Expand Down Expand Up @@ -164,53 +164,89 @@ func TestExecute(t *testing.T) {
}
}()

w := &bytes.Buffer{}
serverWebRCON := httptest.NewServer(MockHandlersWebRCON())
defer serverWebRCON.Close()

// Test empty address.
t.Run("empty address", func(t *testing.T) {
w := &bytes.Buffer{}

err := Execute(w, session.Session{Address: "", Password: MockPasswordRCON}, MockCommandHelpRCON)
assert.Error(t, err)
})

// Test empty password.
t.Run("empty password", func(t *testing.T) {
w := &bytes.Buffer{}

err := Execute(w, session.Session{Address: serverRCON.Addr(), Password: ""}, MockCommandHelpRCON)
assert.Error(t, err)
})

// Test wrong password.
t.Run("wrong password", func(t *testing.T) {
w := &bytes.Buffer{}

err := Execute(w, session.Session{Address: serverRCON.Addr(), Password: "wrong"}, MockCommandHelpRCON)
assert.Error(t, err)
})

// Test empty command.
t.Run("empty command", func(t *testing.T) {
w := &bytes.Buffer{}

err := Execute(w, session.Session{Address: serverRCON.Addr(), Password: MockPasswordRCON}, "")
assert.Error(t, err)
})

// Test long command.
t.Run("long command", func(t *testing.T) {
w := &bytes.Buffer{}

bigCommand := make([]byte, 1001)
err := Execute(w, session.Session{Address: serverRCON.Addr(), Password: MockPasswordRCON}, string(bigCommand))
assert.Error(t, err)
})

// Positive RCON test Execute func.
t.Run("no error rcon", func(t *testing.T) {
w := &bytes.Buffer{}

err := Execute(w, session.Session{Address: serverRCON.Addr(), Password: MockPasswordRCON}, MockCommandHelpRCON)
assert.NoError(t, err)

result := strings.TrimSuffix(w.String(), "\n")
assert.Equal(t, MockCommandHelpResponseTextRCON, result)
})

// Positive TELNET test Execute func.
t.Run("no error telnet", func(t *testing.T) {
w := &bytes.Buffer{}

err := Execute(w, session.Session{Address: serverTELNET.Addr(), Password: MockPasswordTELNET, Type: session.ProtocolTELNET}, MockCommandHelpTELNET)
assert.NoError(t, err)

result := strings.TrimSuffix(w.String(), "\n")
if !strings.Contains(result, MockCommandHelpResponseTextTELNET) {
assert.Equal(t, MockCommandHelpResponseTextTELNET, result)
}
})

// Positive WEB RCON test Execute func.
t.Run("no error web", func(t *testing.T) {
w := &bytes.Buffer{}

err := Execute(w, session.Session{Address: serverWebRCON.Listener.Addr().String(), Password: MockPasswordWebRCON, Type: session.ProtocolWebRCON}, "status")
assert.NoError(t, err)

result := strings.TrimSuffix(w.String(), "\n")
assert.Equal(t, MockCommandStatusResponseTextWebRCON, result)
})

// Positive test Execute func with log.
t.Run("no error with log", func(t *testing.T) {
w := &bytes.Buffer{}

logFileName := "tmpfile.log"
defer func() {
err := os.Remove(logFileName)
Expand All @@ -226,7 +262,8 @@ func TestExecute(t *testing.T) {
password := getVar("TEST_PZ_SERVER_PASSWORD", "docker")

t.Run("pz server", func(t *testing.T) {
needle := `List of server commands :
needle := func() string {
n := `List of server commands :
* addalltowhitelist : Add all the current users connected with a password in the whitelist, so their account is protected.
* additem : Add an item to a player, if no username is given the item will be added to you, count is optional, use /additem \"username\" \"module.item\" count, ex : /additem \"rj\" \"Base.Axe\" count
* adduser : Use this command to add a new user in a whitelisted server, use : /adduser \"username\" \"pwd\"
Expand Down Expand Up @@ -264,23 +301,18 @@ func TestExecute(t *testing.T) {
* unbanuser : Unban a player, use : /unbanuser \"username\"
* voiceban : Block voice from user \"username\", use : /voiceban \"username\" -value, ex /voiceban \"rj\" -true (could be -false)`

needle = strings.Replace(needle, "List of server commands :", "List of server commands : ", -1)
n = strings.Replace(n, "List of server commands :", "List of server commands : ", -1)

err := Execute(w, session.Session{Address: addr, Password: password}, "help")
assert.NoError(t, err)
assert.NotEmpty(t, w.String())
return n
}()

if !strings.Contains(w.String(), needle) {
diff := struct {
R string
N string
}{R: w.String(), N: needle}
w := &bytes.Buffer{}

js, _ := json.Marshal(diff)
fmt.Println(string(js))
err := Execute(w, session.Session{Address: addr, Password: password}, "help")
assert.NoError(t, err)

t.Error("response is not contain needle string")
}
result := strings.TrimSuffix(w.String(), "\n")
assert.Equal(t, needle, result)
})
}

Expand All @@ -289,7 +321,8 @@ func TestExecute(t *testing.T) {
password := getVar("TEST_7DTD_SERVER_PASSWORD", "banana")

t.Run("7dtd server", func(t *testing.T) {
needle := `*** List of Commands ***
needle := func() string {
n := `*** List of Commands ***
admin => Manage user permission levels
aiddebug => Toggles AIDirector debug output.
audio => Watch audio stats
Expand Down Expand Up @@ -405,24 +438,21 @@ of your current perk levels in a CSV file next to it.
xuireload => Access xui related functions such as reinitializing a window group, opening a window group
zip => Control zipline settings`

needle = strings.Replace(needle, "\n", "\r\n", -1)
needle = strings.Replace(needle, "some generic info\r\n", "some generic info\n", -1)
needle = strings.Replace(needle, "Also stores a list\r\n", "Also stores a list\n", -1)
n = strings.Replace(n, "\n", "\r\n", -1)
n = strings.Replace(n, "some generic info\r\n", "some generic info\n", -1)
n = strings.Replace(n, "Also stores a list\r\n", "Also stores a list\n", -1)

return n
}()

w := &bytes.Buffer{}

err := Execute(w, session.Session{Address: addr, Password: password, Type: session.ProtocolTELNET}, "help")
assert.NoError(t, err)
assert.NotEmpty(t, w.String())

result := strings.TrimSuffix(w.String(), "\n")
if !strings.Contains(w.String(), needle) {
diff := struct {
R string
N string
}{R: w.String(), N: needle}

js, _ := json.Marshal(diff)
fmt.Println(string(js))

t.Error("response is not contain needle string")
assert.Equal(t, needle, result)
}
})
}
Expand All @@ -432,6 +462,8 @@ of your current perk levels in a CSV file next to it.
password := getVar("TEST_RUST_SERVER_RCON_PASSWORD", "docker")

t.Run("rust server rcon", func(t *testing.T) {
w := &bytes.Buffer{}

err := Execute(w, session.Session{Address: addr, Password: password}, "status")
assert.NoError(t, err)
assert.NotEmpty(t, w.String())
Expand All @@ -445,6 +477,8 @@ of your current perk levels in a CSV file next to it.
password := getVar("TEST_RUST_SERVER_WEB_PASSWORD", "docker")

t.Run("rust server web", func(t *testing.T) {
w := &bytes.Buffer{}

err := Execute(w, session.Session{Address: addr, Password: password, Type: session.ProtocolWebRCON}, "status")
assert.NoError(t, err)
assert.NotEmpty(t, w.String())
Expand Down Expand Up @@ -552,7 +586,7 @@ func TestNewApp(t *testing.T) {
// Test getting address and password from config. Log is not used.
t.Run("getting address and password from args with log", func(t *testing.T) {
var configFileName = "rcon-temp.yaml"
err := CreateConfigFile(configFileName, server.Addr(), MockPasswordRCON)
err := createConfigFile(configFileName, server.Addr(), MockPasswordRCON)
assert.NoError(t, err)
defer func() {
err := os.Remove(configFileName)
Expand Down Expand Up @@ -590,7 +624,7 @@ func TestNewApp(t *testing.T) {
// Test default config file is incorrect. Log is not used.
t.Run("default config file is incorrect", func(t *testing.T) {
var configFileName = "rcon-temp.yaml"
err := CreateInvalidConfigFile(configFileName, server.Addr(), MockPasswordRCON)
err := createInvalidConfigFile(configFileName, server.Addr(), MockPasswordRCON)
assert.NoError(t, err)
defer func() {
err := os.Remove(configFileName)
Expand Down Expand Up @@ -661,8 +695,8 @@ func TestNewApp(t *testing.T) {
// DefaultTestLogName sets the default log file name.
const DefaultTestLogName = "rcon-default.log"

// CreateConfigFile creates config file with default section.
func CreateConfigFile(name string, address string, password string) error {
// createConfigFile creates config file with default section.
func createConfigFile(name string, address string, password string) error {
var stringBody = fmt.Sprintf(
"%s:\n address: \"%s\"\n password: \"%s\"\n log: \"%s\"",
config.DefaultConfigEnv, address, password, DefaultTestLogName,
Expand All @@ -676,8 +710,8 @@ func CreateConfigFile(name string, address string, password string) error {
return err
}

// CreateIncorrectConfigFile creates incorrect yaml config file.
func CreateInvalidConfigFile(name string, address string, password string) error {
// createIncorrectConfigFile creates incorrect yaml config file.
func createInvalidConfigFile(name string, address string, password string) error {
var stringBody = fmt.Sprintf(
"address: \"%s\"\n password: \"%s\"\n log: \"%s\"",
address, password, DefaultTestLogName,
Expand Down
6 changes: 3 additions & 3 deletions mockserver_rcon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ const (
MockAddressRCON = "127.0.0.1:0"
MockPasswordRCON = "password"

MockCommandHelpRCON = "help"
MockCommandHelpResponseRCON = "lorem ipsum dolor sit amet"
MockCommandHelpRCON = "help"
MockCommandHelpResponseTextRCON = "lorem ipsum dolor sit amet"
)

// MockServerRCON is a mock Source RCON Protocol server.
Expand Down Expand Up @@ -136,7 +136,7 @@ func (s *MockServerRCON) handle(conn net.Conn) {
case rcon.SERVERDATA_EXECCOMMAND:
switch request.Body() {
case MockCommandHelpRCON:
responseBody = MockCommandHelpResponseRCON
responseBody = MockCommandHelpResponseTextRCON
default:
responseBody = "unknown command"
}
Expand Down
6 changes: 3 additions & 3 deletions mockserver_telnet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ const (
MockAddressTELNET = "127.0.0.1:0"
MockPasswordTELNET = "password"

MockCommandHelpTELNET = "help"
MockCommandHelpResponseTELNET = "lorem ipsum dolor sit amet"
MockCommandHelpTELNET = "help"
MockCommandHelpResponseTextTELNET = "lorem ipsum dolor sit amet"
)

// MockServerTELNET is a mock Source TELNET protocol server.
Expand Down Expand Up @@ -140,7 +140,7 @@ func (s *MockServerTELNET) handle(conn net.Conn) {
switch request {
case "":
case MockCommandHelpTELNET:
w.WriteString(MockCommandHelpResponseTELNET + telnet.CRLF)
w.WriteString(MockCommandHelpResponseTextTELNET + telnet.CRLF)
case "exit":
default:
w.WriteString(fmt.Sprintf("*** ERROR: unknown command '%s'", request) + telnet.CRLF)
Expand Down
16 changes: 7 additions & 9 deletions mockserver_web_rcon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,25 @@ import (
"strings"
"time"

gorilla "github.com/gorilla/websocket"
"github.com/gorcon/websocket"
gorilla "github.com/gorilla/websocket"
)

const MockPasswordWebsocket = "password"
const MockPasswordWebRCON = "password"

const MockCommandStatusResponseTextWebsocket = `status
hostname: Rust Server [DOCKER]
const MockCommandStatusResponseTextWebRCON = `hostname: Rust Server [DOCKER]
version : 2260 secure (secure mode enabled, connected to Steam3)
map : Procedural Map
players : 0 (500 max) (0 queued) (0 joining)
id name ping connected addr owner violation kicks
`
id name ping connected addr owner violation kicks`

func MockServerWebsocketHandlers() http.Handler {
func MockHandlersWebRCON() http.Handler {
server := http.NewServeMux()

var upgrader = gorilla.Upgrader{}
upgrader.CheckOrigin = func(r *http.Request) bool { return true }

server.HandleFunc("/"+MockPasswordWebsocket, func(w http.ResponseWriter, r *http.Request) {
server.HandleFunc("/"+MockPasswordWebRCON, func(w http.ResponseWriter, r *http.Request) {
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Printf("upgrade error: %v\n", err)
Expand Down Expand Up @@ -59,7 +57,7 @@ func MockServerWebsocketHandlers() http.Handler {
switch message.Message {
case "status":
response = websocket.Message{
Message: MockCommandStatusResponseTextWebsocket,
Message: MockCommandStatusResponseTextWebRCON,
Identifier: message.Identifier,
Type: "Generic",
}
Expand Down

0 comments on commit 42d1cb2

Please sign in to comment.