Skip to content

Commit

Permalink
test(daemon): RPC client testing
Browse files Browse the repository at this point in the history
  • Loading branch information
mefellows committed Jun 4, 2016
1 parent 8b52754 commit 83c75c2
Show file tree
Hide file tree
Showing 15 changed files with 439 additions and 54 deletions.
16 changes: 16 additions & 0 deletions command/pact_mock_service_cmd_test.go
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
package command

import "testing"

func init() {
// os.Args = append(os.Args, "mock")
// os.Args = append(os.Args, "--help")
}

func Test_PactMockServiceCommand(t *testing.T) {
err := mockServiceCmd.Help()
if err != nil {
t.Fatalf("Error: %v", err)
}

// mockServiceCmd.Run(nil, os.Args)
}
2 changes: 1 addition & 1 deletion command/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

func init() {
// Set CLI flags to simulate real
os.Args[1] = "version"
os.Args = []string{"version"}
}

func Test_RootCommand(t *testing.T) {
Expand Down
20 changes: 20 additions & 0 deletions command/version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package command

import (
"os"
"testing"
)

func init() {
// Set CLI flags to simulate real
// os.Args = append(os.Args, "version")
os.Args = []string{"version"}
}

func Test_VersionCommand(t *testing.T) {
err := versionCmd.Execute()
if err != nil {
t.Fatalf("Error: %v", err)
}
versionCmd.Run(nil, os.Args)
}
29 changes: 12 additions & 17 deletions daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,6 @@ func NewDaemon(pactMockServiceManager Service) *Daemon {
// StartDaemon starts the daemon RPC server.
func (d *Daemon) StartDaemon(port int) {
fmt.Println("Starting daemon on port", port)
// rpc.Register(d)
// rpc.HandleHTTP()
//
// // Start daemon in background
// go func() {
// l, e := net.Listen("tcp", fmt.Sprintf(":%d", port))
// if e != nil {
// log.Fatal("listen error:", e)
// }
// http.Serve(l, nil)
// }()

serv := rpc.NewServer()
serv.Register(d)
Expand All @@ -102,8 +91,7 @@ func (d *Daemon) StartDaemon(port int) {
panic(err)
}
go http.Serve(l, mux)

// d.pactMockSvcManager.Start()
fmt.Println("Server started, waiting for stuff!")

// Wait for sigterm
signal.Notify(d.signalChan, os.Interrupt, os.Kill)
Expand All @@ -114,6 +102,13 @@ func (d *Daemon) StartDaemon(port int) {
fmt.Println("done")
}

// StopDaemon allows clients to programmatically shuts down the running Daemon
// via RPC.
func (d *Daemon) StopDaemon(request string, reply *string) error {
d.signalChan <- os.Interrupt
return nil
}

// Shutdown ensures all services are cleanly destroyed.
func (d *Daemon) Shutdown() {
for _, s := range d.pactMockSvcManager.List() {
Expand All @@ -126,12 +121,12 @@ func (d *Daemon) Shutdown() {
// StartServer starts a mock server and returns a pointer to aPactMockServer
// struct.
func (d *Daemon) StartServer(request *PactMockServer, reply *PactMockServer) error {
reply = &PactMockServer{}
server := &PactMockServer{}
port, svc := d.pactMockSvcManager.NewService()
reply.Port = port
server.Port = port
cmd := svc.Start()
reply.Pid = cmd.Process.Pid

server.Pid = cmd.Process.Pid
*reply = *server
return nil
}

Expand Down
12 changes: 10 additions & 2 deletions daemon/daemon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ func TestNewDaemon(t *testing.T) {
}
}

func TestStopDaemon(t *testing.T) {
d, _ := createMockedDaemon()
port, _ := utils.GetFreePort()
go d.StartDaemon(port)
connectToDaemon(port, t)
d.Shutdown()
}

// Use this to wait for a daemon to be running prior
// to running tests
func connectToDaemon(port int, t *testing.T) {
Expand Down Expand Up @@ -125,7 +133,7 @@ func TestStartServer(t *testing.T) {
t.Fatalf("Error: %v", err)
}

if res.Pid != 0 {
if res.Pid == 0 {
t.Fatalf("Expected non-zero Pid but got: %d", res.Pid)
}

Expand Down Expand Up @@ -253,7 +261,7 @@ func TestRPCClient_StartServer(t *testing.T) {
log.Fatal("rpc error:", err)
}

if res.Pid != 0 {
if res.Pid == 0 {
t.Fatalf("Expected non-zero Pid but got: %d", res.Pid)
}

Expand Down
16 changes: 8 additions & 8 deletions daemon/pact_mock_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ type PactMockService struct {
// NewService creates a new PactMockService with default settings.
func (m *PactMockService) NewService() (int, Service) {
port, _ := utils.GetFreePort()
version := 2
dir, _ := os.Getwd()
dir = fmt.Sprintf(filepath.Join(dir, "../", "pacts"))
logDir := fmt.Sprintf(filepath.Join(dir, "../", "logs"))
// version := 2
// dir, _ := os.Getwd()
// dir = fmt.Sprintf(filepath.Join(dir, "../", "pacts"))
// logDir := fmt.Sprintf(filepath.Join(dir, "../", "logs"))
log.Println("Starting mock service on port:", port)

m.Args = []string{
fmt.Sprintf("--port %d", port),
fmt.Sprintf("--pact-specification-version %d", version),
fmt.Sprintf("--pact-dir %s", dir),
fmt.Sprintf("--log-dir %s", logDir),
fmt.Sprintf("--ssl"),
// fmt.Sprintf("--pact-specification-version %d", version),
// fmt.Sprintf("--pact-dir %s", dir),
// fmt.Sprintf("--log-dir %s", logDir),
// fmt.Sprintf("--ssl"),
}
m.Command = getCommandPath()
return port, m
Expand Down
4 changes: 0 additions & 4 deletions daemon/pact_mock_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,4 @@ func TestNewService(t *testing.T) {
if svc == nil {
t.Fatalf("Expected a non-nil object but got nil")
}

// if len(svc.Args) != 1 {
// t.Fatalf("Expected 1 argument (--port) but got: %d", len(svc.Args))
// }
}
31 changes: 17 additions & 14 deletions daemon/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"time"
)

var channelTimeout = time.After(50 * time.Millisecond)
var channelTimeout = 50 * time.Millisecond

func createServiceManager() *ServiceManager {
cs := []string{"-test.run=TestHelperProcess", "--", os.Args[0]}
Expand Down Expand Up @@ -53,17 +53,17 @@ func TestServiceManager_removeServiceMonitor(t *testing.T) {
}

mgr.commandCompleteChan <- cmd

var timeout = time.After(channelTimeout)
for {
select {
case <-time.After(10 * time.Millisecond):
if len(mgr.processes) == 0 {
return
}
case <-channelTimeout:
case <-timeout:
if len(mgr.processes) != 0 {
t.Fatalf(`Expected 1 command to be removed from the queue.
Timed out after 500millis`)
t.Fatalf(`Expected 1 command to be removed from the queue. Have %d
Timed out after 500millis`, len(mgr.processes))
}
}
}
Expand All @@ -74,14 +74,15 @@ func TestServiceManager_addServiceMonitor(t *testing.T) {
cmd := fakeExecCommand("", true, "")
cmd.Start()
mgr.commandCreatedChan <- cmd
var timeout = time.After(channelTimeout)

for {
select {
case <-time.After(10 * time.Millisecond):
if len(mgr.processes) == 1 {
return
}
case <-channelTimeout:
case <-timeout:
if len(mgr.processes) != 1 {
t.Fatalf(`Expected 1 command to be added to the queue, but got: %d.
Timed out after 500millis`, len(mgr.processes))
Expand All @@ -95,19 +96,21 @@ func TestServiceManager_addServiceMonitorWithDeadJob(t *testing.T) {
mgr := createServiceManager()
cmd := fakeExecCommand("", true, "")
mgr.commandCreatedChan <- cmd
var timeout = time.After(channelTimeout)

attempts := 0
for {
select {
case <-time.After(10 * time.Millisecond):
if len(mgr.processes) != 0 {
t.Fatalf(`Expected 0 command to be added to the queue, but got: %d.
Timed out after 5 attempts`, len(mgr.processes))
}
attempts++
if attempts == 5 {
return
case <-timeout:
if len(mgr.processes) != 0 {
t.Fatalf(`Expected 0 command to be added to the queue, but got: %d.
Timed out after 50millis`, len(mgr.processes))
}
return
}
}
}
Expand All @@ -121,14 +124,14 @@ func TestServiceManager_Stop(t *testing.T) {
}

mgr.Stop(cmd.Process.Pid)

var timeout = time.After(channelTimeout)
for {
select {
case <-time.After(10 * time.Millisecond):
if len(mgr.processes) == 0 {
return
}
case <-channelTimeout:
case <-timeout:
if len(mgr.processes) != 0 {
t.Fatalf(`Expected 1 command to be removed from the queue.
Timed out after 500millis`)
Expand All @@ -155,20 +158,20 @@ func TestServiceManager_List(t *testing.T) {
func TestServiceManager_Start(t *testing.T) {
mgr := createServiceManager()
mgr.Start()
var timeout = time.After(channelTimeout)

for {
select {
case <-time.After(10 * time.Millisecond):
if len(mgr.processes) == 1 {
return
}
case <-channelTimeout:
case <-timeout:
if len(mgr.processes) != 1 {
t.Fatalf(`Expected 1 command to be added to the queue, but got: %d.
Timed out after 500millis`, len(mgr.processes))
}
return
}
}

}
81 changes: 81 additions & 0 deletions dsl/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package dsl

import (
"fmt"
"log"
"net"
"net/rpc"
"time"

"github.com/mefellows/pact-go/daemon"
)

// Client is the simplified remote interface to the Pact Daemon
type Client interface {
StartServer() *daemon.PactMockServer
}

// PactClient is the default implementation of the Client interface.
type PactClient struct {
port int
}

func getHTTPClient(port int) (*rpc.Client, error) {
waitForPort(port)
return rpc.DialHTTP("tcp", fmt.Sprintf(":%d", port))
}

// Use this to wait for a daemon to be running prior
// to running tests
func waitForPort(port int) {
fmt.Printf("client - Waiting for daemon port: %d", port)
timeout := time.After(10 * time.Second)

for {
select {
case <-timeout:
log.Fatalf("Expected server to start < 1s.")
case <-time.After(50 * time.Millisecond):
_, err := net.Dial("tcp", fmt.Sprintf(":%d", port))
if err == nil {
return
}
}
}
}

// StartServer starts a remote Pact Mock Server.
func (p *PactClient) StartServer() *daemon.PactMockServer {
var res daemon.PactMockServer
client, err := getHTTPClient(p.port)
if err != nil {
log.Fatal("rpc error:", err)
}
err = client.Call("Daemon.StartServer", daemon.PactMockServer{}, &res)
if err != nil {
log.Fatal("rpc error:", err)
}
return &res
}

// ListServers starts a remote Pact Mock Server.
func (p *PactClient) ListServers() *daemon.PactListResponse {
var res daemon.PactListResponse
client, err := getHTTPClient(p.port)
err = client.Call("Daemon.ListServers", daemon.PactMockServer{}, &res)
if err != nil {
log.Fatal("rpc error:", err)
}
return &res
}

// StopServer stops a remote Pact Mock Server.
func (p *PactClient) StopServer(server *daemon.PactMockServer) *daemon.PactMockServer {
client, err := getHTTPClient(p.port)
var res daemon.PactMockServer
err = client.Call("Daemon.StopServer", server, &res)
if err != nil {
log.Fatal("rpc error:", err)
}
return &res
}
Loading

0 comments on commit 83c75c2

Please sign in to comment.