From 250e0c6ff29a07ff9939ce8bfc44fc58747a6d0c Mon Sep 17 00:00:00 2001 From: Christian Adell Querol Date: Wed, 15 Nov 2017 16:04:04 +0100 Subject: [PATCH 1/6] Testing TCPConnect --- tcpclient/connectionsManagement_test.go | 89 +++++++++++++++++++------ 1 file changed, 70 insertions(+), 19 deletions(-) diff --git a/tcpclient/connectionsManagement_test.go b/tcpclient/connectionsManagement_test.go index 383923f..b5fb446 100644 --- a/tcpclient/connectionsManagement_test.go +++ b/tcpclient/connectionsManagement_test.go @@ -2,7 +2,6 @@ package tcpclient import ( "io/ioutil" - "strconv" "sync" "testing" "time" @@ -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() + } } From 031f04f932e138f271c6a3cacab466fae002654f Mon Sep 17 00:00:00 2001 From: Christian Adell Querol Date: Thu, 16 Nov 2017 14:16:28 +0100 Subject: [PATCH 2/6] Testing for connection.go --- tcpclient/connection_test.go | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 tcpclient/connection_test.go diff --git a/tcpclient/connection_test.go b/tcpclient/connection_test.go new file mode 100644 index 0000000..563f890 --- /dev/null +++ b/tcpclient/connection_test.go @@ -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") + } +} From 18d66d39f891b80ab2f732d6436476e39276075d Mon Sep 17 00:00:00 2001 From: Christian Adell Querol Date: Sun, 19 Nov 2017 18:59:55 +0100 Subject: [PATCH 3/6] Centralise use of os.Exit in main package --- cmdutil/closureLogic.go | 13 ++++++------- tcpgoon.go | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/cmdutil/closureLogic.go b/cmdutil/closureLogic.go index 8392c95..ce25f57 100644 --- a/cmdutil/closureLogic.go +++ b/cmdutil/closureLogic.go @@ -3,7 +3,6 @@ package cmdutil import ( "fmt" "io" - "os" "github.com/dachad/tcpgoon/mtcpclient" ) @@ -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 } diff --git a/tcpgoon.go b/tcpgoon.go index 8922080..08db54c 100644 --- a/tcpgoon.go +++ b/tcpgoon.go @@ -38,7 +38,7 @@ 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) @@ -46,5 +46,5 @@ func main() { 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)) } From 4612c52e97a57b73890291eec93bdbf1083ef3e1 Mon Sep 17 00:00:00 2001 From: Christian Adell Querol Date: Sun, 19 Nov 2017 19:00:51 +0100 Subject: [PATCH 4/6] Implement a set method for connectionstatus --- tcpclient/connection.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tcpclient/connection.go b/tcpclient/connection.go index 857c14e..c597bc7 100644 --- a/tcpclient/connection.go +++ b/tcpclient/connection.go @@ -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 { From f1fe1398997db468b22cda0c2351e22e8d0d5291 Mon Sep 17 00:00:00 2001 From: Christian Adell Querol Date: Sun, 19 Nov 2017 19:01:07 +0100 Subject: [PATCH 5/6] Testing for closureLogic.go --- cmdutil/closureLogic_test.go | 59 ++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 cmdutil/closureLogic_test.go diff --git a/cmdutil/closureLogic_test.go b/cmdutil/closureLogic_test.go new file mode 100644 index 0000000..de0d4d8 --- /dev/null +++ b/cmdutil/closureLogic_test.go @@ -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) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + mockObj := something.NewMockMyInterface(mockCtrl) + + 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") + } +} From 1a469058c91f01e1d923cda2e092f1260debb6ba Mon Sep 17 00:00:00 2001 From: Christian Adell Querol Date: Sun, 19 Nov 2017 19:01:21 +0100 Subject: [PATCH 6/6] Testing for sliceUtil --- cmdutil/sliceUtil_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 cmdutil/sliceUtil_test.go diff --git a/cmdutil/sliceUtil_test.go b/cmdutil/sliceUtil_test.go new file mode 100644 index 0000000..ed0e093 --- /dev/null +++ b/cmdutil/sliceUtil_test.go @@ -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") + } +}