ijpiantanida / talkback

A simple HTTP proxy that records and playbacks requests
MIT License
283 stars 41 forks source link

How to stop the server on CI? #49

Closed denislutz closed 3 years ago

denislutz commented 3 years ago

Hi,

first: thank you so much for this awesome project! It rocks.

I have a simple case.

I start talk back in CI than I run the tests, and now I need to stop it somehow. I see localServer.stop() in the doc but, it implies that the script that is tarting the server is somehow informed from outside that tests are done running.

A separate node script just to call localServer.stop(), fails, since the server is not initialized in this context and its not a singleton as it looks like. What should I do?

Basically you always need it if you want your server and tests to run as one command and you dont want to deal with two terminals.

I think this is a very common situation and worth mentioning.

Thanks in advance.

Denis.

ijpiantanida commented 3 years ago

Hi @denislutz, how is your CI server starting talkback and the tests?

denislutz commented 3 years ago

Hi I have a file tapesServer.js

const opts = {
  host,
  port,
  path: `${__dirname}/tapes`,
  record,
  fallbackMode: (req) => {
    console.warn(`Tape NOT FOUND for request: ${req.method} ${req.url} ${req.body ? req.body.toString() : 'no body'}`)
    return talkback.Options.FallbackMode.NOT_FOUND
  },
  // urlMatcher,
  // bodyMatcher,
  ignoreHeaders,
  tapeNameGenerator,
}
const localServer = talkback(opts)
localServer.start()

module.exports = async () => {
  global.__MY_LOCAL_SERVER = localServer
}

Usually I would start the tapes in a separate terminal and the run 'yarn test' in another on. Then when I am done testing just kill it by hand.

For the CI I then do all in one command. Something like:

yarn node tapesServer.js & yarn test && kill -9 $(lsof -t -i:$TAPES_PORT) || true

This works in general but its not very clean, since I am killing it in a hard way, besides this I would like to have one command locally to offer it to new developers who dont know abouth the whole tapes setup and just want to run one command 'yarn test'.

So the final question is, how can I a) reference the running server from some other script that would stop it? b) Maybe start and stop it out of jest?

ijpiantanida commented 3 years ago

I extended the examples to show how you can do this in a few ways.

Starting talkback in a separate process than the tests (what you are already doing)

You can continue using the single line command.

node tapesServer.js & TALKBACK_PID=$! && sleep 1 && yarn test && kill $TALKBACK_PID

Note that you don't need to send a SIGKILL. Talkback handles SIGTERM (kill -15 or just kill) and shutdowns gracefully. Also it's probably a good idea to give talkback some time (sleep 1) to initialize before running the tests.

I'm using the once liner in this example.

You could put it as the definition of yarn test in your package.json, or alternatively, you could create a test.sh script, put the commands there instead of the long one-liner and then have yarn test just call the script.

Let the test runner start/stop talkback

There are many ways in which you can do this, depending on what your test runner allows.

Personally, I prefer the second option since it plays nicely with IDEs running the tests as they start all the context that they require by themselves.

Hopefully, this helps you.

denislutz commented 3 years ago

Thanks so much, let my try it all out.