Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Testing cmdutils #34

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
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
13 changes: 6 additions & 7 deletions cmdutil/closureLogic.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package cmdutil
import (
"fmt"
"io"
"os"

"github.com/dachad/tcpgoon/mtcpclient"
)
Expand All @@ -14,21 +13,21 @@ const (
completedButConnErrorsExitStatus = 2
)

func CloseNicely(host string, port int, gc mtcpclient.GroupOfConnections, debugOut io.Writer) {
func CloseNicely(host string, port int, gc mtcpclient.GroupOfConnections, debugOut io.Writer) int {
printClosureReport(host, port, gc)
if gc.PendingConnections() {
fmt.Fprintln(debugOut, "We detected some connections did not complete")
os.Exit(incompleteExecutionExitStatus)
return incompleteExecutionExitStatus
}
if gc.AtLeastOneConnectionInError() {
fmt.Fprintln(debugOut, "We detected connection errors")
os.Exit(completedButConnErrorsExitStatus)
return completedButConnErrorsExitStatus
}
fmt.Fprintln(debugOut, "Metrics point to a clean execution. Successful exit")
os.Exit(okExitStatus)
return okExitStatus
}

func CloseAbruptly() {
func CloseAbruptly() int {
fmt.Println("\n*** Execution aborted as prompted by the user ***")
os.Exit(incompleteExecutionExitStatus)
return incompleteExecutionExitStatus
}
59 changes: 59 additions & 0 deletions cmdutil/closureLogic_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package cmdutil

import (
"io/ioutil"
"testing"

"github.com/dachad/tcpgoon/mtcpclient"
"github.com/dachad/tcpgoon/tcpclient"
)

func TestCloselyNicelyPendingConnections(t *testing.T) {
Copy link
Collaborator

@dcaba dcaba Dec 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add more works in the middle to make this more readable. For instance: TestCloseNicelyWhenThereArePendingConnections

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, TestCloselyNicely does not make too much sense xD

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockObj := something.NewMockMyInterface(mockCtrl)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this PR complete? I don't see where this block is being used..


var host = "127.0.0.1"
var port = 55555
var gc = mtcpclient.GroupOfConnections{tcpclient.Connection{
ID: 0,
}}
gc[0].SetConnectionStatus(tcpclient.ConnectionDialing)

if CloseNicely(host, port, gc, ioutil.Discard) != incompleteExecutionExitStatus {
t.Error("Some connection is still dialing")
}
}

func TestCloselyNicelyErroredConnections(t *testing.T) {
var host = "127.0.0.1"
var port = 55555
var gc = mtcpclient.GroupOfConnections{tcpclient.Connection{
ID: 0,
}}
gc[0].SetConnectionStatus(tcpclient.ConnectionError)

if CloseNicely(host, port, gc, ioutil.Discard) != completedButConnErrorsExitStatus {
t.Error("Some connection is still errored")
}
}

func TestCloselyNicelyClean(t *testing.T) {
var host = "127.0.0.1"
var port = 55555
var gc = mtcpclient.GroupOfConnections{tcpclient.Connection{
ID: 0,
}}
gc[0].SetConnectionStatus(tcpclient.ConnectionEstablished)

if CloseNicely(host, port, gc, ioutil.Discard) != okExitStatus {
t.Error("All connections are established")
}
}

func TestCloseAbruptly(t *testing.T) {

if CloseAbruptly() != incompleteExecutionExitStatus {
t.Error("Failed abruptly closing")
}
}
13 changes: 13 additions & 0 deletions cmdutil/sliceUtil_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package cmdutil

import (
"testing"
)

func TestStringInSlice(t *testing.T) {
testString := "test"
testList := []string{"test", "tset"}
if !stringInSlice(testString, testList) {
t.Error("stringInSlice")
}
}
4 changes: 4 additions & 0 deletions tcpclient/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ func (c Connection) GetConnectionStatus() ConnectionStatus {
return c.status
}

func (c Connection) SetConnectionStatus(cs ConnectionStatus) {
c.status = cs
}

func (c Connection) String() string {
var status string
switch c.status {
Expand Down
41 changes: 41 additions & 0 deletions tcpclient/connection_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package tcpclient

import (
"testing"
"time"
)

func TestGetConnectionStatus(t *testing.T) {
connectionDescription := Connection{
ID: 0,
status: ConnectionDialing,
metrics: connectionMetrics{},
}
if connectionDescription.GetConnectionStatus() != ConnectionDialing {
t.Error("GetConnectionStatus is not working")
}
}

func TestGetTCPProcessingDurationEstablished(t *testing.T) {

connectionDescription := Connection{
ID: 0,
status: ConnectionEstablished,
metrics: connectionMetrics{tcpEstablishedDuration: 1 * time.Second},
}
if connectionDescription.GetTCPProcessingDuration(ConnectionEstablished) != 1*time.Second {
t.Error("GetTCPProcessingDuration is not working")
}
}

func TestGetTCPProcessingDurationErrored(t *testing.T) {

connectionDescription := Connection{
ID: 0,
status: ConnectionError,
metrics: connectionMetrics{tcpErroredDuration: 1 * time.Second},
}
if connectionDescription.GetTCPProcessingDuration(ConnectionError) != 1*time.Second {
t.Error("GetTCPProcessingDuration is not working")
}
}
89 changes: 70 additions & 19 deletions tcpclient/connectionsManagement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package tcpclient

import (
"io/ioutil"
"strconv"
"sync"
"testing"
"time"
Expand All @@ -13,41 +12,93 @@ import (
// We really need to refactor this test. We should verify connections do become established,
// rather than just waiting for a second and finish
// We should also test "failing" connections, and ensure their status is reported properly
func TestTcpConnect(t *testing.T) {
var numberConnections = 2
func TestTcpConnectEstablished(t *testing.T) {
var host = "127.0.0.1"
var port = 55555

dispatcher := &tcpserver.Dispatcher{make(map[string]*tcpserver.Handler)}

run := func() {
t.Log("Starting TCP server...")
if err := dispatcher.ListenHandlers(port); err != nil {
t.Error("Could not start the TCP server", err)
t.Fatal("Could not start the TCP server", err)
return
}
t.Log("TCP server started")
}
go run()
time.Sleep(1 * time.Second)

var wg sync.WaitGroup
wg.Add(numberConnections)
wg.Add(1)

for runner := 1; runner <= numberConnections; runner++ {
t.Log("Initiating runner # ", strconv.Itoa(runner))
go TCPConnect(runner, host, port, &wg, ioutil.Discard, make(chan Connection, numberConnections), make(chan bool))
t.Logf("Runner %s initated. Remaining: %s", strconv.Itoa(runner), strconv.Itoa(numberConnections-runner))
var statusChannel = make(chan Connection, 2)
var closeRequest = make(chan bool)

t.Log("Initiating TCP Connect")
go TCPConnect(1, host, port, &wg, ioutil.Discard, statusChannel, closeRequest)
time.Sleep(1 * time.Second)
if (<-statusChannel).GetConnectionStatus() == ConnectionDialing {
t.Log("Connection Dialing")
} else {
t.Error("Connection failed to dial")
}
var connectionEstablished = <-statusChannel
if connectionEstablished.GetConnectionStatus() == ConnectionEstablished {
t.Log("Connection Estalished")
} else {
t.Error("Connection failed to establish")
}
if connectionEstablished.GetTCPProcessingDuration(ConnectionEstablished) != 0 {
t.Log("Connection Estalished in ", connectionEstablished.GetTCPProcessingDuration(ConnectionEstablished))
} else {
t.Error("Connection TCP Processing Duration not consistent")
}
}

t.Log("Waiting runners to finish")
time.Sleep(time.Second)
func TestTcpConnectErrored(t *testing.T) {
var host = "127.0.0.1"
var port = 55556

var wg sync.WaitGroup
wg.Add(1)

// Marking wait groups as done after a second does not make sense...
// and in case one client finishes before this loop being executed (because of an error?)
// we will get an exception (panic: sync: negative WaitGroup counter [recovered])
var statusChannel = make(chan Connection, 2)
var closeRequest = make(chan bool)

//for runner := 1; runner <= numberConnections; runner++ {
// t.Log("Closing runner #", strconv.Itoa(runner))
// wg.Done()
//}
t.Log("Initiating TCP Connect")
go TCPConnect(1, host, port, &wg, ioutil.Discard, statusChannel, closeRequest)
time.Sleep(1 * time.Second)
if (<-statusChannel).GetConnectionStatus() == ConnectionDialing {
t.Log("Connection Dialing")
} else {
t.Error("Connection failed to dial")
}

var connectionErrored = <-statusChannel

if connectionErrored.GetConnectionStatus() == ConnectionError {
t.Log("Connection Errored")
} else {
t.Error("Connection not errored")
}
if connectionErrored.GetTCPProcessingDuration(ConnectionError) != 0 {
t.Log("Connection Errored in ", connectionErrored.GetTCPProcessingDuration(ConnectionError))
} else {
t.Error("Connection TCP Processing Duration not consistent")
}
}

func TestReportConnectionStatus(t *testing.T) {
var debugOut = ioutil.Discard
connStatusCh := make(chan Connection, 1)
connectionDescription := Connection{
ID: 0,
status: ConnectionDialing,
metrics: connectionMetrics{},
}
reportConnectionStatus(debugOut, connStatusCh, connectionDescription)
if <-connStatusCh != connectionDescription {
t.Log("Not proper Connection reported: ", <-connStatusCh)
t.Error()
}
}
4 changes: 2 additions & 2 deletions tcpgoon.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ func main() {

if !(*assumeyesPtr || cmdutil.AskForUserConfirmation(*hostPtr, *portPtr, *numberConnectionsPtr)) {
fmt.Fprintln(debugOut, "Execution not approved by the user")
cmdutil.CloseAbruptly()
os.Exit(cmdutil.CloseAbruptly())
}

connStatusCh, connStatusTracker := mtcpclient.StartBackgroundReporting(*numberConnectionsPtr, *reportingIntervalPtr)
closureCh := mtcpclient.StartBackgroundClosureTrigger(connStatusTracker, debugOut)
mtcpclient.MultiTCPConnect(*numberConnectionsPtr, *delayPtr, *hostPtr, *portPtr, connStatusCh, closureCh, debugOut)
fmt.Fprintln(debugOut, "Tests execution completed")

cmdutil.CloseNicely(*hostPtr, *portPtr, connStatusTracker, debugOut)
os.Exit(cmdutil.CloseNicely(*hostPtr, *portPtr, connStatusTracker, debugOut))
}