Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pact-server): allow to run pact mock server on a host other than localhost #115

Merged

Conversation

sebastian-curland
Copy link
Contributor

When running pact tests (that also start the pact mock server) and the application code (that calls the APIs defined in the pact interactions) on different servers (or different docker containers), the pact server should be binded to a different host other than localhost, otherwise the API calls in the application won't reach the mock server.

pact constructor in src/pact.js already get a "host" option but it is not passed to serviceFactory.createServer() method.

@coveralls
Copy link

coveralls commented Oct 15, 2017

Coverage Status

Coverage remained the same at 95.767% when pulling e24be20 on sebastian-curland:feat/pact-server into f5387a0 on pact-foundation:master.

2 similar comments
@coveralls
Copy link

Coverage Status

Coverage remained the same at 95.767% when pulling e24be20 on sebastian-curland:feat/pact-server into f5387a0 on pact-foundation:master.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 95.767% when pulling e24be20 on sebastian-curland:feat/pact-server into f5387a0 on pact-foundation:master.

@bethesque bethesque merged commit fe33be1 into pact-foundation:master Oct 15, 2017
@bethesque
Copy link
Member

I know I'm not the js expert here, but I'm taking a bet that this is all good and merging.

@mefellows
Copy link
Member

Thanks @sebastian-curland!

@mefellows
Copy link
Member

@bethesque a pattern I'm seeing is a multi-docker test harness, where the mock-server is running in a separate container. Might be worth us reviewing docs/other library implementations to see how we can simplify this use case.

@lirantal
Copy link
Contributor

@bethesque that's exactly what we're aiming at with @sebastian-curland on this.

@mefellows mefellows mentioned this pull request Oct 16, 2017
31 tasks
@bethesque
Copy link
Member

The original Ruby DSL allowed you to say "don't start up the mock service because I've already got my own one running" (in a more concise way). This would be a good feature for the other implementations too.

@mefellows
Copy link
Member

This change won't achieve your outcome, as the the property you added will be passed to the mock server which will attempt to startup on the host you provided (the only real options here are going to be things like localhost, 127.0.0.1, 0.0.0.0 or the current actual IP of the host).

That being said, whilst not ideal, if you used pact-web for this purpose it would do what you're after (that package provides almost the same DSL, but it won't attempt to start the mock server as it's designed for use in browser-like contexts).

In the TypeScript branch, I will propose some options for improving the DSL to work with this use case.

@lirantal
Copy link
Contributor

@mefellows we need this support in pact-js/pact-node since we plan on using it inside a docker container as a generic mock service in CI, where we will set its IP to 0.0.0.0, but also it will have a real IP for the container.

what did you refer to that is not going to work with this change?

@mefellows
Copy link
Member

The current pact package assumes it will start the mock service and run the tests on the same host (virtualised/containerised etc.).

If I understand your use case correctly, I think you want to do something like this:

[ Mock Server 0.0.0.0:8000 ] <- [ Pact Test Suite 1 ]
                             <- [ Pact Tests Suite 2 ]
                             <- ...

when you call pact.setup() it will starts the mock server, so in Pact Test Suite 1. So you could avoid calling that method and things might work.

Alternatively, the pact-web module should work for the above use case, as it doesn't create or start any mock server and will just attempt to send messages to any host you provide it.

Make sense?

@bethesque
Copy link
Member

Just a warning note, you cannot use the same mock service process for multiple consumer/provider pairs. It's a one consumer/provider only deal.

@lirantal
Copy link
Contributor

@mefellows actually that's not what we're planning.
The test suite and the mock server will run in the same container but we're using an API gateway so requests that we make from our app which the test suite runs, are actually being sent to the API gateway, which in turn sends them to the mock server.

So it's more like:
[ test suite ] -> triggers app code which does an api to mock service -> [ app code] -> sends a request to api gateway (a router) -> [api gateway] -> knows which service to send the request to -> [ pact mock server ]

in the above, the [ test suite] and [ pact mock server] are running in the same container, and the pact mock server will be getting requests from other containers and reply to them.

Makes sense?

@mefellows
Copy link
Member

I think so, so you'll want the mock server to start on 0.0.0.0 and your tests point to gateway. Interesting.

@bethesque
Copy link
Member

I love the way people use things that you write in unexpected ways!

Either way, we want a flag that says "don't start up the mock service". I think in the ruby, it was standalone = true. Anyone got a better name suggestion?

@mefellows
Copy link
Member

I'll think of something. I've been thinking of a nicer DSL which might go out with the 5.0.0 release.

But for now that might be the way to go.

@lirantal
Copy link
Contributor

I think last time we tried it, even with the 0.0.0.0 support with the PR from @sebastian-curland ended up in the mock server halting with "server hangup" error messages.

I'll check later if it's something on our part, but any ideas how/if that could be related to pact?
Is there a better way to debug the underlying mock server besides just running the tests with the 'DEBUG' logging level set?

@bethesque
Copy link
Member

Yes, start it up manually and ping it yourself. Start with this example, and then slowly make changes, one step at a time to get it to the state you want your tests to run with. eg. step 1. swap out the local mock service instance with the docker one

One thing I've just realised is that the docker mock service relies on the consumer and provider name being passed in during the POST /pact call, which I've just said we should take out of the js library. Does anyone know if there is a way to pass in runtime environment variables to the CMD bundle exec pact-mock-service service --consumer $CONSUMER --provider $PROVIDER --host 0.0.0.0 --port 80 --pact-dir ./pacts line?

@bethesque
Copy link
Member

I've just seen a suggestion that you can run a shell script that references the env vars, so that might work.

@mefellows
Copy link
Member

@lirantal the best way is to debug the underlying mock server directly.

What you're describing should work, if not perhaps if you could create a repro for me with your specific setup (so I don't make any silly assumptions) I'll be happy to take a look.

@mefellows
Copy link
Member

@bethesque any environment variables present at the time of executing that script will be available.

e.g. CONSUMER=foo PROVIDER=bar ./example.sh would make CONSUMER and PROVIDER available to the shell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants