WireMock-Net / WireMock.Net

WireMock.Net is a flexible product for stubbing and mocking web HTTP responses using advanced request matching and response templating. Based on the functionality from http://WireMock.org, but extended with more functionality.
Apache License 2.0
1.39k stars 207 forks source link

WireMock.Net does not appear to work with Github Actions #1019

Closed aplant-sb closed 10 months ago

aplant-sb commented 10 months ago

I've been trying to get an integration test running in Github Actions using WireMock.NET for the past day and a bit, but having no joy. As it stands, I am able to run our integration test (which is triggered as part of a Nuke build script) completely fine locally, however when running in Github actions, the Wiremock server shows 0 log entries and so our tests are failing.

Is there any specific configuration required inside of a github action to ensure that Wiremock is able to intercept requests correctly? It seems like it's just not getting anything, but after trying to change localhost, ports and other various settings, I've still come up empty handed.

For more context, the Nuke build script basically spins up a docker-compose command which creates containers for Kafka and our app, at which point we run the integration test directly. This integration test publishes a message onto a kafka topic, which the app should then pick up, and send an HTTP request to it's configured endpoint.

When running this from anywhere else, the integration test indicates that there is 1 call matched from Wiremock, and so it passes. In Github actions, it reports 0 calls being made at all (in the log entries).

Any help here would be much appreciated!

StefH commented 10 months ago

@aplant-sb I'll investigate this.

StefH commented 10 months ago

@aplant-sb I did add a GutHub Action to WireMock.Net project to run the same unit tests as I run in Azure Pipeline, and it works fine.

See https://github.com/WireMock-Net/WireMock.Net/pull/1020

aplant-sb commented 10 months ago

@StefH thanks for testing this for me.

So I'm even more confused why this isn't working for us then. To be 100% clear - our test involves basically setting up the wiremock server, listening on a port and path that is used by our internal app, and then after publishing a kafka message to the app, verifying that the app sent a HTTP request to the expected endpoint. Is there anything about that scenario that you see as being different to what you tested? And I guess to explicitly call it out again, the app is running in a docker container, whereas the integration test is run from the github actions VM itself (maybe there's some networking difference there?)

aplant-sb commented 10 months ago

And I guess for more info, this essentially how we are trying to assert that wiremock received anything (right now we don't even filter by path, we just purely go on the port number):

private void Assert()
{
    Xunit.Assert.Single(_mockSetup.Server.LogEntries);
    Xunit.Assert.Equal(_mockSetup.Path, _mockSetup.Server.LogEntries.First().RequestMessage.AbsolutePath);
}

Running this in Github actions tells us that the LogEntries dictionary has 0 elements. Our Wiremock setup looks like the following (Port here is set to 5002):

public void StartServer()
{
    Server = WireMockServer.Start(new WireMockServerSettings
    {
     StartTimeout = 60000,
     Port = Port
    });
    SetupStubResponseForExecutor();
}

private void SetupStubResponseForExecutor()
{
    Server.Given(
            Request.Create().UsingAnyMethod()
        ).RespondWith(
            Response.Create()
                .WithStatusCode(200)
                .WithHeader("Content-Type", "application/x-protobuf"));
}

And then for the app itself, the URL it is (meant) to be sending a request to is: http://localhost:5002/Executor/RunModelProto

For avoidance of doubt, that particular part of the app code looks like the following (again, the _client here is using the URL above to send the request):

// construct request
var httpReq = CreateHttpRequestMessageFor(request);
httpReq.Headers.Add("Correlation-Id", request.CorrelationId);

var response = await _client.SendAsync(httpReq);
response.EnsureSuccessStatusCode();

var _ = await response.Content.ReadAsStringAsync();

I still cannot for the life of me figure out why this fails only in Github actions, but works fine on my local machine when running the exact same build script

aplant-sb commented 10 months ago

Scratch all the above - I figured out the problem. I was running this stuff on a windows machine locally, so host.docker.internal was setup already with WSL. Github actions was of course running with Linux 😄

Adding the following to our docker-compose file has allowed this to finally work properly:

    extra_hosts:
      - "host.docker.internal:host-gateway"

Thanks for your help and apologies for wasting your time with this!