pact-foundation / pact-go

Golang version of Pact. Pact is a contract testing framework for HTTP APIs and non-HTTP asynchronous messaging systems.
http://pact.io
MIT License
834 stars 104 forks source link

pact-go v2.0.x requires CGO #321

Closed StephanHCB closed 11 months ago

StephanHCB commented 11 months ago

We tried updating our pact-go contract tests to v2.0.1, and saw that pact-go now apparently requires a C compiler to run.

Is there any chance this could be avoided? There are lots of systems and containerized build environments that do not have or want a C compiler.

We tried setting CGO_ENABLED=0, but since no pure go alternative is provided in the code, this did not help either.

Software versions

Expected behaviour

A simple consumer test that makes a single HTTP get request works.

Actual behaviour

go compile fails

# github.com/pact-foundation/pact-go/v2/consumer
..\golang\gopath\pkg\mod\github.com\pact-foundation\pact-go\v2@v2.0.1\consumer\http.go:82:31: undefined: native.MockServer
..\golang\gopath\pkg\mod\github.com\pact-foundation\pact-go\v2@v2.0.1\consumer\http.go:114:24: undefined: native.NewHTTPPact
..\golang\gopath\pkg\mod\github.com\pact-foundation\pact-go\v2@v2.0.1\consumer\http.go:117:48: undefined: native.SPECIFICATION_VERSION_V2
..\golang\gopath\pkg\mod\github.com\pact-foundation\pact-go\v2@v2.0.1\consumer\http.go:119:48: undefined: native.SPECIFICATION_VERSION_V3
..\golang\gopath\pkg\mod\github.com\pact-foundation\pact-go\v2@v2.0.1\consumer\http.go:121:48: undefined: native.SPECIFICATION_VERSION_V4
..\golang\gopath\pkg\mod\github.com\pact-foundation\pact-go\v2@v2.0.1\consumer\http.go:123:9: undefined: native.Init
..\golang\gopath\pkg\mod\github.com\pact-foundation\pact-go\v2@v2.0.1\consumer\http.go:316:16: undefined: native.GetTLSConfig
..\golang\gopath\pkg\mod\github.com\pact-foundation\pact-go\v2@v2.0.1\consumer\interaction.go:16:35: undefined: mockserver.Interaction
..\golang\gopath\pkg\mod\github.com\pact-foundation\pact-go\v2@v2.0.1\consumer\http_v4.go:461:65: undefined: native.INTERACTION_PART_REQUEST
..\golang\gopath\pkg\mod\github.com\pact-foundation\pact-go\v2@v2.0.1\consumer\http_v4.go:542:65: undefined: native.INTERACTION_PART_RESPONSE
..\golang\gopath\pkg\mod\github.com\pact-foundation\pact-go\v2@v2.0.1\consumer\http_v4.go:542:65: too many errors

Steps to reproduce

Any http request consumer test will do this. Simple example:

package sample

import (
    "fmt"
    "net/http"
    "testing"

    "github.com/go-http-utils/headers"
    "github.com/pact-foundation/pact-go/v2/consumer"
    "github.com/pact-foundation/pact-go/v2/matchers"
)

func TestSampleConsumer(t *testing.T) {
    pact, err := consumer.NewV2Pact(consumer.MockHTTPProviderConfig{
        Consumer: "sample",
        Provider: "sample-provider",
        Host:     "localhost",
    })
    if err != nil {
        t.FailNow()
    }

    var test = func(serverConfig consumer.MockServerConfig) error {
        requestUrl := fmt.Sprintf("http://localhost:%d/hello", serverConfig.Port)
        req, err := http.NewRequest(http.MethodGet, requestUrl, nil)
        if err != nil {
            return err
        }
        _, err = http.DefaultClient.Do(req)
        return err
    }

    err = pact.
        AddInteraction().
        Given("this test compiles").
        UponReceiving("A request for a greeting").
        WithCompleteRequest(consumer.Request{
            Method: http.MethodGet,
            Path:   matchers.String("/hello"),
        }).
        WithCompleteResponse(consumer.Response{
            Status:  200,
            Headers: matchers.MapMatcher{headers.ContentType: matchers.String("application/json")},
            Body: map[string]interface{}{
                "greeting": "hello",
            },
        }).
        ExecuteTest(t, test)
    if err != nil {
        t.FailNow()
    }
}

Relevent log files

No log file, the test fails to compile. Compile output see above.

mefellows commented 11 months ago

Thanks for the detailed report.

Unfortunately CGO will be required for 2.x.x and beyond as we move to a different (Rust based) shared core, which contains most of the complex functionality that makes Pact work (there were also challenges with the Ruby based core).

You can stick with 1.x.x but it won't receive any major feature updates, and doesn't support things like plugins etc.

We currently take the position that a C development environment is not an undue expectation for a developer tool. For context, all Pact client languages will be moving (or already have moved) to this model.

Apologies for any inconvenience, however I will have to close this for now unless a workable model can be proposed.

mefellows commented 11 months ago

Note, I will update the requirements in the docs for this package to note CGO and a C build end. For now, I'll close this off.