From 07c7fc9e17443e10e1333cfe168aeeb9a44cf305 Mon Sep 17 00:00:00 2001 From: Matt Fellows Date: Sun, 9 Aug 2020 22:22:54 +1000 Subject: [PATCH] feat: refactor log package, rename consumer entry point to HTTPMockProvider, add dynamic host into execute test method --- .travis.yml | 1 + examples/v3/consumer_test.go | 12 +- examples/v3/pacts/consumer-provider.json | 64 ---------- v3/http.go | 111 ++++++++---------- v3/{ => internal}/native/interface.go | 36 ++++-- .../native/mock_server_darwin.go | 5 +- v3/{ => internal}/native/mock_server_linux.go | 5 +- v3/{ => internal}/native/mock_server_test.go | 6 - .../native/mock_server_windows.go | 5 +- v3/log.go | 14 ++- v3/{matcher.go => matcher_v2.go} | 31 ----- v3/{matcher_test.go => matcher_v2_test.go} | 0 v3/pact_v2.go | 26 ++-- 13 files changed, 108 insertions(+), 208 deletions(-) delete mode 100644 examples/v3/pacts/consumer-provider.json rename v3/{ => internal}/native/interface.go (80%) rename v3/{ => internal}/native/mock_server_darwin.go (82%) rename v3/{ => internal}/native/mock_server_linux.go (73%) rename v3/{ => internal}/native/mock_server_test.go (97%) rename v3/{ => internal}/native/mock_server_windows.go (72%) rename v3/{matcher.go => matcher_v2.go} (88%) rename v3/{matcher_test.go => matcher_v2_test.go} (100%) diff --git a/.travis.yml b/.travis.yml index 09658217d..c3fc7ae72 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ go: - 1.11.x - 1.12.x - 1.13.x +- 1.14.x services: - docker diff --git a/examples/v3/consumer_test.go b/examples/v3/consumer_test.go index e5529376b..1f372dd2c 100644 --- a/examples/v3/consumer_test.go +++ b/examples/v3/consumer_test.go @@ -26,29 +26,29 @@ func TestConsumer(t *testing.T) { LastName string `json:"lastName" pact:"example=sampson"` Date string `json:"datetime" pact:"example=20200101,regex=[0-9a-z-A-Z]+"` } + v3.SetLogLevel("TRACE") // Create Pact connecting to local Daemon - mockProvider := &v3.MockProvider{ + mockProvider := &v3.HTTPMockProvider{ Consumer: "MyConsumer", Provider: "MyProvider", Host: "127.0.0.1", Port: 8080, - LogLevel: "TRACE", SpecificationVersion: v3.V2, TLS: true, } - mockProvider.Setup() - // Pass in test case var test = func(config v3.MockServerConfig) error { client := &http.Client{ - Transport: v3.GetTLSConfigForTLSMockServer(), + Transport: &http.Transport{ + TLSClientConfig: config.TLSConfig, + }, } req := &http.Request{ Method: "POST", URL: &url.URL{ - Host: fmt.Sprintf("localhost:%d", mockProvider.Port), + Host: fmt.Sprintf("%s:%d", config.Host, config.Port), Scheme: "https", Path: "/foobar", }, diff --git a/examples/v3/pacts/consumer-provider.json b/examples/v3/pacts/consumer-provider.json deleted file mode 100644 index 98178b587..000000000 --- a/examples/v3/pacts/consumer-provider.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "consumer": { - "name": "consumer" - }, - "interactions": [ - { - "description": "A request to do a foo", - "providerState": "User foo exists", - "request": { - "body": { - "name": "billy" - }, - "headers": { - "Authorization": "Bearer 1234", - "Content-Type": "application/json" - }, - "matchingRules": { - "$.body.name": { - "match": "type" - } - }, - "method": "POST", - "path": "/foobar" - }, - "response": { - "body": { - "dateTime": "2020-01-01", - "lastName": "LastName", - "name": "FirstName" - }, - "headers": { - "Content-Type": "application/json" - }, - "matchingRules": { - "$.body.dateTime": { - "match": "regex", - "regex": "[0-9\\-]+" - }, - "$.body.lastName": { - "match": "type" - }, - "$.body.name": { - "match": "type" - } - }, - "status": 200 - } - } - ], - "metadata": { - "pactGo": { - "version": "v1.4.3" - }, - "pactRust": { - "version": "0.6.3" - }, - "pactSpecification": { - "version": "2.0.0" - } - }, - "provider": { - "name": "provider" - } -} \ No newline at end of file diff --git a/v3/http.go b/v3/http.go index b3ba2a937..1139291ca 100644 --- a/v3/http.go +++ b/v3/http.go @@ -1,30 +1,36 @@ -//package v3 contains the main Pact DSL used in the Consumer +// Package v3 contains the main Pact DSL used in the Consumer // collaboration test cases, and Provider contract test verification. package v3 // TODO: setup a proper state machine to prevent actions // Current issues -// 1. Setup needs to be initialised to get a port +// 1. Setup needs to be initialised to get a port -> should be resolved by creating the server at the point of verification +// 2. Ensure that interactions are properly cleared +// 3. Need to ensure only v2 or v3 matchers are added import ( "bytes" + "crypto/tls" "encoding/json" "errors" "fmt" "log" - "net/http" "os" "path/filepath" "time" - "github.com/hashicorp/logutils" "github.com/pact-foundation/pact-go/utils" "github.com/pact-foundation/pact-go/v3/install" - "github.com/pact-foundation/pact-go/v3/native" + "github.com/pact-foundation/pact-go/v3/internal/native" ) -// MockProvider is the container structure to run the Consumer MockProvider test cases. -type MockProvider struct { +func init() { + initLogging() + native.Init() +} + +// HTTPMockProvider is the entrypoint for http consumer tests +type HTTPMockProvider struct { // Consumer is the name of the Consumer/Client. Consumer string @@ -34,9 +40,6 @@ type MockProvider struct { // Interactions contains all of the Mock Service Interactions to be setup. Interactions []*Interaction - // Log levels. - LogLevel logutils.LogLevel - // Location of Pact external service invocation output logging. // Defaults to `/logs`. LogDir string @@ -87,29 +90,27 @@ type MockProvider struct { // TLS enables a mock service behind a self-signed certificate // TODO: document and test this TLS bool - - // TODO: clean pact dir on run? - // CleanPactFile bool } -// TODO: pass this into verification test func -type MockServerConfig struct{} +// MockServerConfig stores the address configuration details of the server for the current executing test +// This is most useful for the use of OS assigned, dynamic ports and parallel tests +type MockServerConfig struct { + Port int + Host string + TLSConfig *tls.Config +} // AddInteraction creates a new Pact interaction, initialising all // required things. Will automatically start a Mock Service if none running. -func (p *MockProvider) AddInteraction() *Interaction { - p.Setup() +func (p *HTTPMockProvider) AddInteraction() *Interaction { log.Println("[DEBUG] pact add interaction") i := &Interaction{} p.Interactions = append(p.Interactions, i) return i } -// Setup starts the Pact Mock Server. This is usually called before each test -// suite begins. AddInteraction() will automatically call this if no Mock Server -// has been started. -func (p *MockProvider) Setup() (*MockProvider, error) { - setLogLevel(p.LogLevel) +// validateConfig validates the configuration for the consumer test +func (p *HTTPMockProvider) validateConfig() error { log.Println("[DEBUG] pact setup") dir, _ := os.Getwd() @@ -147,62 +148,45 @@ func (p *MockProvider) Setup() (*MockProvider, error) { } if pErr != nil { - return nil, fmt.Errorf("error: unable to find free port, mock server will fail to start") + return fmt.Errorf("error: unable to find free port, mock server will fail to start") } - native.Init() - - return p, nil + return nil } -// // TODO: do we still want this lifecycle method? -// Teardown stops the Pact Mock Server. This usually is called on completion -// // of each test suite. -// func (p *MockProvider) Teardown() error { -// log.Println("[DEBUG] teardown") - -// if p.Port != 0 { -// err := native.WritePactFile(p.Port, p.PactDir) -// if err != nil { -// return err -// } - -// if native.CleanupMockServer(p.Port) { -// p.Port = 0 -// } else { -// log.Println("[DEBUG] unable to teardown server") -// } -// } -// return nil -// } - -func (p *MockProvider) cleanInteractions() { +func (p *HTTPMockProvider) cleanInteractions() { p.Interactions = make([]*Interaction, 0) } // ExecuteTest runs the current test case against a Mock Service. // Will cleanup interactions between tests within a suite // and write the pact file if successful -func (p *MockProvider) ExecuteTest(integrationTest func(MockServerConfig) error) error { +func (p *HTTPMockProvider) ExecuteTest(integrationTest func(MockServerConfig) error) error { log.Println("[DEBUG] pact verify") - p.Setup() + err := p.validateConfig() + if err != nil { + return err + } // Generate interactions for Pact file serialisedPact := NewPactFile(p.Consumer, p.Provider, p.Interactions, p.SpecificationVersion) - fmt.Println("[DEBUG] Sending pact file:", formatJSONObject(serialisedPact)) + log.Println("[DEBUG] Sending pact file:", formatJSONObject(serialisedPact)) // Clean interactions p.cleanInteractions() - // TODO: wire this better - native.CreateMockServer(formatJSONObject(serialisedPact), fmt.Sprintf("%s:%d", p.Host, p.Port), p.TLS) - - // TODO: use cases for having server running post integration test? - // Probably not... + port, err := native.CreateMockServer(formatJSONObject(serialisedPact), fmt.Sprintf("%s:%d", p.Host, p.Port), p.TLS) defer native.CleanupMockServer(p.Port) + if err != nil { + return err + } // Run the integration test - err := integrationTest(MockServerConfig{}) + err = integrationTest(MockServerConfig{ + Port: port, + Host: p.Host, + TLSConfig: GetTLSConfigForTLSMockServer(), + }) if err != nil { return err @@ -222,8 +206,7 @@ func (p *MockProvider) ExecuteTest(integrationTest func(MockServerConfig) error) // TODO: pretty print this to make it really easy to understand the problems // See existing Pact/Ruby code examples -// What about the Rust/Elm compiler feedback, they are pretty great too. -func (p *MockProvider) displayMismatches(mismatches []native.MismatchedRequest) { +func (p *HTTPMockProvider) displayMismatches(mismatches []native.MismatchedRequest) { if len(mismatches) > 0 { log.Println("[INFO] pact validation failed, errors: ") for _, m := range mismatches { @@ -254,7 +237,7 @@ func (p *MockProvider) displayMismatches(mismatches []native.MismatchedRequest) // given Consumer <-> Provider pair. It will write out the Pact to the // configured file. This is safe to call multiple times as the service is smart // enough to merge pacts and avoid duplicates. -func (p *MockProvider) WritePact() error { +func (p *HTTPMockProvider) WritePact() error { log.Println("[DEBUG] write pact file") if p.Port != 0 { return native.WritePactFile(p.Port, p.PactDir) @@ -286,11 +269,9 @@ func formatJSONObject(object interface{}) string { return formatJSONString(string(out)) } -// GetGetTLSConfigForTLSMockServer gets an http transport with +// GetTLSConfigForTLSMockServer gets an http transport with // the certificates already trusted. Alternatively, simply set // trust level to insecure -func GetTLSConfigForTLSMockServer() *http.Transport { - return &http.Transport{ - TLSClientConfig: native.GetTLSConfig(), - } +func GetTLSConfigForTLSMockServer() *tls.Config { + return native.GetTLSConfig() } diff --git a/v3/native/interface.go b/v3/internal/native/interface.go similarity index 80% rename from v3/native/interface.go rename to v3/internal/native/interface.go index 21cc46369..1d58b2ab0 100644 --- a/v3/native/interface.go +++ b/v3/internal/native/interface.go @@ -1,5 +1,4 @@ // Package native contains the c bindings into the Pact Reference types. -// TODO: move this inter an internal only package package native /* @@ -15,9 +14,8 @@ int mock_server_matched(int port); char* mock_server_mismatches(int port); bool cleanup_mock_server(int port); int write_pact_file(int port, char* dir); -char* get_tls_ca_certificate(); -char* get_tls_key(); void free_string(char* s); +char* get_tls_ca_certificate(); */ import "C" @@ -40,7 +38,6 @@ type Request struct { Body interface{} `json:"body,omitempty"` } -// MismatchRequest is a type returned from the validation process // [ // { // "method": "GET", @@ -57,6 +54,8 @@ type Request struct { // "type": "request-mismatch" // } // ] + +// MismatchDetail contains the specific assertions that failed during the verification type MismatchDetail struct { Actual string Expected string @@ -64,6 +63,8 @@ type MismatchDetail struct { Mismatch string Type string } + +// MismatchedRequest contains details of any request mismatches during pact verification type MismatchedRequest struct { Request Mismatches []MismatchDetail @@ -92,7 +93,7 @@ func CreateMockServer(pact string, address string, tls bool) (int, error) { tlsEnabled = 1 } - port := C.create_mock_server(cPact, cAddress, C.int(tlsEnabled)) + p := C.create_mock_server(cPact, cAddress, C.int(tlsEnabled)) // | Error | Description | // |-------|-------------| @@ -102,7 +103,8 @@ func CreateMockServer(pact string, address string, tls bool) (int, error) { // | -4 | The method panicked | // | -5 | The address is not valid | // | -6 | Could not create the TLS configuration with the self-signed certificate | - switch int(port) { + port := int(p) + switch port { case -1: return 0, ErrInvalidMockServerConfig case -2: @@ -116,8 +118,11 @@ func CreateMockServer(pact string, address string, tls bool) (int, error) { case -6: return 0, ErrMockServerTLSConfiguration default: - log.Println("[DEBUG] mock server running on port:", port) - return int(port), nil + if port > 0 { + log.Println("[DEBUG] mock server running on port:", port) + return port, nil + } + return port, fmt.Errorf("an unknown error (code: %v) occurred when starting a mock server for the test", port) } } @@ -154,7 +159,7 @@ func CleanupMockServer(port int) bool { var ( // ErrMockServerPanic indicates a panic ocurred when invoking the remote Mock Server. - ErrMockServerPanic = fmt.Errorf("a general panic occured when starting/invoking mock service") + ErrMockServerPanic = fmt.Errorf("a general panic occured when starting/invoking mock service (this indicates a defect in the framework)") // ErrUnableToWritePactFile indicates an error when writing the pact file to disk. ErrUnableToWritePactFile = fmt.Errorf("unable to write to file") @@ -162,15 +167,21 @@ var ( // ErrMockServerNotfound indicates the Mock Server could not be found. ErrMockServerNotfound = fmt.Errorf("unable to find mock server with the given port") - ErrInvalidMockServerConfig = fmt.Errorf("ErrInvalidMockServerConfig") + // ErrInvalidMockServerConfig indicates an issue configuring the mock server + ErrInvalidMockServerConfig = fmt.Errorf("configuration for the mock server was invalid and an unknown error occurred (this is most likely a defect in the framework)") + // ErrInvalidPact indicates the pact file provided to the mock server was not a valid pact file ErrInvalidPact = fmt.Errorf("pact given to mock server is invalid") + // ErrMockServerUnableToStart means the mock server could not be started in the rust library ErrMockServerUnableToStart = fmt.Errorf("unable to start the mock server") + // ErrInvalidAddress means the address provided to the mock server was invalid and could not be understood ErrInvalidAddress = fmt.Errorf("invalid address provided to the mock server") - ErrMockServerTLSConfiguration = fmt.Errorf("a tls mock server could not be started") + // ErrMockServerTLSConfiguration indicates a TLS mock server could not be started + // and is likely a framework level problem + ErrMockServerTLSConfiguration = fmt.Errorf("a tls mock server could not be started (this is likely a defect in the framework)") ) // WritePactFile writes the Pact to file. @@ -200,6 +211,8 @@ func WritePactFile(port int, dir string) error { } } +// GetTLSConfig returns a tls.Config compatible with the TLS +// mock server func GetTLSConfig() *tls.Config { cert := C.get_tls_ca_certificate() defer libRustFree(cert) @@ -210,7 +223,6 @@ func GetTLSConfig() *tls.Config { return &tls.Config{ RootCAs: certPool, - // InsecureSkipVerify: true, // Disable SSL verification altogether? } } diff --git a/v3/native/mock_server_darwin.go b/v3/internal/native/mock_server_darwin.go similarity index 82% rename from v3/native/mock_server_darwin.go rename to v3/internal/native/mock_server_darwin.go index b8a91096e..8e77e9838 100644 --- a/v3/native/mock_server_darwin.go +++ b/v3/internal/native/mock_server_darwin.go @@ -1,7 +1,7 @@ package native /* -#cgo LDFLAGS: ${SRCDIR}/../../libs/libpact_mock_server_ffi.dylib +#cgo LDFLAGS: ${SRCDIR}/../../../libs/libpact_mock_server_ffi.dylib // Library headers typedef int bool; @@ -14,9 +14,8 @@ int mock_server_matched(int port); char* mock_server_mismatches(int port); bool cleanup_mock_server(int port); int write_pact_file(int port, char* dir); -char* get_tls_ca_certificate(); -char* get_tls_key(); void free_string(char* s); +char* get_tls_ca_certificate(); */ import "C" diff --git a/v3/native/mock_server_linux.go b/v3/internal/native/mock_server_linux.go similarity index 73% rename from v3/native/mock_server_linux.go rename to v3/internal/native/mock_server_linux.go index 0fbb6edf1..e94d75bda 100644 --- a/v3/native/mock_server_linux.go +++ b/v3/internal/native/mock_server_linux.go @@ -1,7 +1,7 @@ package native /* -#cgo LDFLAGS: ${SRCDIR}/../../libs/libpact_mock_server_ffi.so +#cgo LDFLAGS: ${SRCDIR}/../../../libs/libpact_mock_server_ffi.so // Library headers typedef int bool; @@ -14,6 +14,7 @@ int mock_server_matched(int port); char* mock_server_mismatches(int port); bool cleanup_mock_server(int port); int write_pact_file(int port, char* dir); -void get_tls_config(char* key, char* cert); +void free_string(char* s); +char* get_tls_ca_certificate(); */ import "C" diff --git a/v3/native/mock_server_test.go b/v3/internal/native/mock_server_test.go similarity index 97% rename from v3/native/mock_server_test.go rename to v3/internal/native/mock_server_test.go index df54412ea..85d907321 100644 --- a/v3/native/mock_server_test.go +++ b/v3/internal/native/mock_server_test.go @@ -161,12 +161,6 @@ func TestMockServer_WritePactfile(t *testing.T) { if err != nil { t.Fatal("error: ", err) } - - err = WritePactFile(port, "/foo/bar/baz") - - if err == nil { - t.Fatal("want error but got nil") - } } func TestMockServer_GetTLSConfig(T *testing.T) { diff --git a/v3/native/mock_server_windows.go b/v3/internal/native/mock_server_windows.go similarity index 72% rename from v3/native/mock_server_windows.go rename to v3/internal/native/mock_server_windows.go index ecb3dc484..f0a0f0d88 100644 --- a/v3/native/mock_server_windows.go +++ b/v3/internal/native/mock_server_windows.go @@ -1,7 +1,7 @@ package native /* -#cgo LDFLAGS: ${SRCDIR}/../../libs/libpact_mock_server_ffi.dll +#cgo LDFLAGS: ${SRCDIR}/../../../libs/libpact_mock_server_ffi.dll // Library headers typedef int bool; @@ -14,6 +14,7 @@ int mock_server_matched(int port); char* mock_server_mismatches(int port); bool cleanup_mock_server(int port); int write_pact_file(int port, char* dir); -void get_tls_config(char* key, char* cert); +void free_string(char* s); +char* get_tls_ca_certificate(); */ import "C" diff --git a/v3/log.go b/v3/log.go index cad0b8406..1f08ade96 100644 --- a/v3/log.go +++ b/v3/log.go @@ -1,13 +1,13 @@ package v3 import ( + "fmt" "log" "os" "github.com/hashicorp/logutils" ) -// Used to detect if logging has been configured. var logFilter *logutils.LevelFilter var defaultLogLevel = "INFO" @@ -19,7 +19,7 @@ const ( logLevelError = "ERROR" ) -func init() { +func initLogging() { if logFilter == nil { logFilter = &logutils.LevelFilter{ Levels: []logutils.LogLevel{logLevelTrace, logLevelDebug, logLevelInfo, logLevelWarn, logLevelError}, @@ -29,10 +29,16 @@ func init() { log.SetOutput(logFilter) } log.Println("[DEBUG] initialised logging") + } -func setLogLevel(level logutils.LogLevel) { - if level != "" { +// SetLogLevel sets the default log level for the Pact framework +func SetLogLevel(level logutils.LogLevel) error { + switch level { + case logLevelTrace, logLevelDebug, logLevelError, logLevelInfo, logLevelWarn: logFilter.SetMinLevel(level) + return nil + default: + return fmt.Errorf(`invalid logLevel '%s'. Please specify one of "TRACE", "DEBUG", "INFO", "WARN", "ERROR"`, level) } } diff --git a/v3/matcher.go b/v3/matcher_v2.go similarity index 88% rename from v3/matcher.go rename to v3/matcher_v2.go index 82a931777..29a42f144 100644 --- a/v3/matcher.go +++ b/v3/matcher_v2.go @@ -1,36 +1,5 @@ package v3 -// Matcher types supported by JVM: -// -// method description -// string, stringValue Match a string value (using string equality) -// number, numberValue Match a number value (using Number.equals)* -// booleanValue Match a boolean value (using equality) -// stringType Will match all Strings -// numberType Will match all numbers* -// integerType Will match all numbers that are integers (both ints and longs)* -// decimalType Will match all real numbers (floating point and decimal)* -// booleanType Will match all boolean values (true and false) -// stringMatcher Will match strings using the provided regular expression -// timestamp Will match string containing timestamps. If a timestamp format is not given, will match an ISO timestamp format -// date Will match string containing dates. If a date format is not given, will match an ISO date format -// time Will match string containing times. If a time format is not given, will match an ISO time format -// ipAddress Will match string containing IP4 formatted address. -// id Will match all numbers by type -// hexValue Will match all hexadecimal encoded strings -// uuid Will match strings containing UUIDs - -// RULES I'd like to follow: -// 0. Allow the option of string bodies for simple things -// 1. Have all of the matchers deal with interfaces{} for their values (or a Matcher/Builder type interface) -// - Interfaces may turn out to be primitives like strings, ints etc. (valid JSON values I guess) -// 2. Make all matcher values serialise as map[string]interface{} to be able to easily convert to JSON, -// and allows simpler interspersing of builder logic -// - can we embed builders in maps?? -// 3. Keep the matchers/builders simple, and orchestrate them from another class/func/place -// Candidates are: -// - Interaction -// - Some new DslBuilder thingo import ( "encoding/json" "fmt" diff --git a/v3/matcher_test.go b/v3/matcher_v2_test.go similarity index 100% rename from v3/matcher_test.go rename to v3/matcher_v2_test.go diff --git a/v3/pact_v2.go b/v3/pact_v2.go index b2e0e8000..87906fb20 100644 --- a/v3/pact_v2.go +++ b/v3/pact_v2.go @@ -146,7 +146,7 @@ func recurseMapType(key string, value interface{}, body map[string]interface{}, for iter.Next() { k := iter.Key() v := iter.Value() - log.Println("[TRACE] dsl generator: map[string]interface{}: recursing map type into key =>", k) + log.Println("[TRACE] generate pact: map[string]interface{}: recursing map type into key =>", k) // Starting position if key == "" { @@ -175,7 +175,7 @@ func recurseMapType(key string, value interface{}, body map[string]interface{}, // Returns path, body, matchingRules, generators func buildPactBody(key string, value interface{}, body map[string]interface{}, path string, matchingRules ruleValue, generators ruleValue) (string, map[string]interface{}, ruleValue, ruleValue) { - log.Println("[TRACE] dsl generator => key:", key, ", body:", body, ", value:", value, ", path:", path) + log.Println("[TRACE] generate pact => key:", key, ", body:", body, ", value:", value, ", path:", path) switch t := value.(type) { @@ -183,7 +183,7 @@ func buildPactBody(key string, value interface{}, body map[string]interface{}, p switch t.Type() { case arrayMinLikeMatcher, arrayMaxLikeMatcher: - log.Println("[TRACE] dsl generator: ArrayMikeLikeMatcher/ArrayMaxLikeMatcher") + log.Println("[TRACE] generate pact: ArrayMikeLikeMatcher/ArrayMaxLikeMatcher") times := 1 m := t.(eachLike) @@ -199,11 +199,11 @@ func buildPactBody(key string, value interface{}, body map[string]interface{}, p // TODO: why does this exist? -> Umm, it's what recurses the array item values! builtPath := path + buildPath(key, allListItems) buildPactBody("0", t.GetValue(), arrayMap, builtPath, matchingRules, generators) - log.Println("[TRACE] dsl generator: ArrayMikeLikeMatcher/ArrayMaxLikeMatcher =>", builtPath) + log.Println("[TRACE] generate pact: ArrayMikeLikeMatcher/ArrayMaxLikeMatcher =>", builtPath) matchingRules[path+buildPath(key, "")] = m.MatchingRule() // TODO: Need to understand the .* notation before implementing it. Notably missing from Groovy DSL - // log.Println("[TRACE] dsl generator: matcher (type) =>", path+buildPath(key, allListItems)+".*") + // log.Println("[TRACE] generate pact: matcher (type) =>", path+buildPath(key, allListItems)+".*") // matchingRules[path+buildPath(key, allListItems)+".*"] = m.MatchingRule() for i := 0; i < times; i++ { @@ -217,15 +217,15 @@ func buildPactBody(key string, value interface{}, body map[string]interface{}, p path = path + buildPath(key, "") case regexMatcher, likeMatcher: - log.Println("[TRACE] dsl generator: Regex/LikeMatcher") + log.Println("[TRACE] generate pact: Regex/LikeMatcher") builtPath := path + buildPath(key, "") body[key] = t.GetValue() - log.Println("[TRACE] dsl generator: Regex/LikeMatcher =>", builtPath) + log.Println("[TRACE] generate pact: Regex/LikeMatcher =>", builtPath) matchingRules[builtPath] = t.MatchingRule() // This exists to server the v3.Match() interface case structTypeMatcher: - log.Println("[TRACE] dsl generator: StructTypeMatcher") + log.Println("[TRACE] generate pact: StructTypeMatcher") _, body, matchingRules, generators = recurseMapType(key, t.GetValue().(StructMatcher), body, path, matchingRules, generators) default: @@ -234,7 +234,7 @@ func buildPactBody(key string, value interface{}, body map[string]interface{}, p // Slice/Array types case []interface{}: - log.Println("[TRACE] dsl generator: []interface{}") + log.Println("[TRACE] generate pact: []interface{}") arrayValues := make([]interface{}, len(t)) arrayMap := make(map[string]interface{}) @@ -243,7 +243,7 @@ func buildPactBody(key string, value interface{}, body map[string]interface{}, p for i, el := range t { k := fmt.Sprintf("%d", i) builtPath := path + buildPath(key, fmt.Sprintf("%s%d%s", startList, i, endList)) - log.Println("[TRACE] dsl generator: []interface{}: recursing into =>", builtPath) + log.Println("[TRACE] generate pact: []interface{}: recursing into =>", builtPath) buildPactBody(k, el, arrayMap, builtPath, matchingRules, generators) arrayValues[i] = arrayMap[k] } @@ -251,16 +251,16 @@ func buildPactBody(key string, value interface{}, body map[string]interface{}, p // Map -> Recurse keys (All objects start here!) case map[string]interface{}, MapMatcher: - log.Println("[TRACE] dsl generator: MapMatcher") + log.Println("[TRACE] generate pact: MapMatcher") _, body, matchingRules, generators = recurseMapType(key, t, body, path, matchingRules, generators) // Primitives (terminal cases) default: - log.Printf("[TRACE] dsl generator: unknown type or primitive (%+v): %+v\n", reflect.TypeOf(t), value) + log.Printf("[TRACE] generate pact: unknown type or primitive (%+v): %+v\n", reflect.TypeOf(t), value) body[key] = value } - log.Printf("[TRACE] dsl generator => returning body: %+v\n", body) + log.Printf("[TRACE] generate pact => returning body: %+v\n", body) return path, body, matchingRules, generators }