Skip to content

Commit

Permalink
feat(verifier): complete implementation of pact verification feature
Browse files Browse the repository at this point in the history
Refactor common types into the 'types' package.
Update README with provider testing example.
  • Loading branch information
mefellows committed Jun 6, 2016
1 parent a4c9d35 commit 3255d7f
Show file tree
Hide file tree
Showing 18 changed files with 158 additions and 172 deletions.
65 changes: 61 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ DSLs communicate over a local (RPC) connection, and is transparent to clients.
NOTE: The daemon is completely thread safe and it is safe to leave the daemon
running for long periods (e.g. on a CI server).

### Example
### Example - Consumer
1. Start the daemon with `./pact-go daemon`
1. `cd <pact-go>/examples`
1. `go run consumer.go`
Expand All @@ -68,7 +68,7 @@ func TestSomeApi(t *testing.T) {

// Pass in your test case as a function to Verify()
var test = func() error {
_, err := http.Get(fmt.Sprintf("http://localhost:%d/", pact.Server.Port))
_, err := http.Get("http://localhost:8000/")
return err
}

Expand All @@ -90,12 +90,69 @@ func TestSomeApi(t *testing.T) {
if err != nil {
t.Fatalf("Error on Verify: %v", err)
}

// You should now have a pact file in the file `<pact-go>/pacts/my_consumer-my_provider.json`
}
```

### Matching
### Example - Provider

Start your Provider API:

```go
mux := http.NewServeMux()
mux.HandleFunc("/setup", func(w http.ResponseWriter, req *http.Request) {
w.Header().Add("Content-Type", "application/json")
})
mux.HandleFunc("/states", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, `{"My Consumer": ["Some state", "Some state2"]}`)
w.Header().Add("Content-Type", "application/json")
})
mux.HandleFunc("/someapi", func(w http.ResponseWriter, req *http.Request) {
w.Header().Add("Content-Type", "application/json")
fmt.Fprintf(w, `
[
[
{
"size": 10,
"colour": "red",
"tag": [
[
"jumper",
"shirt"
],
[
"jumper",
"shirt"
]
]
}
]
]`)
})
go http.ListenAndServe(":8000"), mux)
```

Note that the server has 2 endpoints: `/states` and `/setup` that allows the
verifier to setup
[provider states](http://docs.pact.io/documentation/provider_states.html) before
each test is run.

You can now tell Pact to read in your Pact files and verify that your API will
satisy the requirements of each of your known consumers:

```go
response := pact.VerifyProvider(&types.VerifyRequest{
ProviderBaseURL: "http://localhost:8000",
PactURLs: []string{"./pacts/my_consumer-my_provider.json"},
ProviderStatesURL: "http://localhost:8000/states",
ProviderStatesSetupURL: "http://localhost:8000/setup",
})
```

See the `Skip()'ed` [integration tests](https://github.com/pact-foundation/pact-go/blob/master/dsl/pact_test.go)
for a more complete E2E example.

### Matching (Consumer Tests)

In addition to verbatim value matching, you have 3 useful matching functions
in the `dsl` package that can increase expressiveness and reduce brittle test
Expand Down
35 changes: 0 additions & 35 deletions command/pact_mock_service_cmd.go

This file was deleted.

10 changes: 0 additions & 10 deletions command/pact_mock_service_cmd_test.go

This file was deleted.

28 changes: 0 additions & 28 deletions command/pact_verification_service_cmd.go

This file was deleted.

1 change: 0 additions & 1 deletion command/verifier.go

This file was deleted.

1 change: 0 additions & 1 deletion command/verifier_test.go

This file was deleted.

28 changes: 15 additions & 13 deletions daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"net/rpc"
"os"
"os/signal"

"github.com/pact-foundation/pact-go/types"
)

// Daemon wraps the commands for the RPC server.
Expand Down Expand Up @@ -83,11 +85,11 @@ func (d *Daemon) Shutdown() {
}
}

// StartServer starts a mock server and returns a pointer to aPactMockServer
// StartServer starts a mock server and returns a pointer to atypes.PactMockServer
// struct.
func (d *Daemon) StartServer(request *PactMockServer, reply *PactMockServer) error {
func (d *Daemon) StartServer(request *types.PactMockServer, reply *types.PactMockServer) error {
log.Println("[DEBUG] daemon - starting mock server")
server := &PactMockServer{}
server := &types.PactMockServer{}
port, svc := d.pactMockSvcManager.NewService(request.Args)
server.Port = port
server.Status = -1
Expand All @@ -98,57 +100,57 @@ func (d *Daemon) StartServer(request *PactMockServer, reply *PactMockServer) err
}

// VerifyProvider runs the Pact Provider Verification Process.
func (d *Daemon) VerifyProvider(request *VerifyRequest, reply *Response) error {
func (d *Daemon) VerifyProvider(request *types.VerifyRequest, reply *types.CommandResponse) error {
log.Println("[DEBUG] daemon - verifying provider")
exitCode := 1

// Convert request into flags, and validate request
err := request.Validate()
if err != nil {
*reply = *&Response{
*reply = *&types.CommandResponse{
ExitCode: exitCode,
Message: err.Error(),
}
return nil
}

var out bytes.Buffer
_, svc := d.verificationSvcManager.NewService(request.args)
_, svc := d.verificationSvcManager.NewService(request.Args)
cmd, err := svc.Run(&out)

if cmd.ProcessState.Success() && err == nil {
exitCode = 0
}

*reply = *&Response{
*reply = *&types.CommandResponse{
ExitCode: exitCode,
Message: string(out.Bytes()),
}

return nil
}

// ListServers returns a slice of all running PactMockServers.
func (d *Daemon) ListServers(request PactMockServer, reply *PactListResponse) error {
// ListServers returns a slice of all running types.PactMockServers.
func (d *Daemon) ListServers(request types.PactMockServer, reply *types.PactListResponse) error {
log.Println("[DEBUG] daemon - listing mock servers")
var servers []*PactMockServer
var servers []*types.PactMockServer

for port, s := range d.pactMockSvcManager.List() {
servers = append(servers, &PactMockServer{
servers = append(servers, &types.PactMockServer{
Pid: s.Process.Pid,
Port: port,
})
}

*reply = *&PactListResponse{
*reply = *&types.PactListResponse{
Servers: servers,
}

return nil
}

// StopServer stops the given mock server.
func (d *Daemon) StopServer(request *PactMockServer, reply *PactMockServer) error {
func (d *Daemon) StopServer(request *types.PactMockServer, reply *types.PactMockServer) error {
log.Println("[DEBUG] daemon - stopping mock server")
success, err := d.pactMockSvcManager.Stop(request.Pid)
if success == true && err == nil {
Expand Down
Loading

0 comments on commit 3255d7f

Please sign in to comment.