Running processes in the background in Travis

3 min. read

Caution! This article is 6 years old. It may be obsolete or show old techniques. It may also still be relevant, and you may find it useful! So it has been marked as deprecated, just in case.

The other day I had a surprise in Travis. I wrote my first scraper ever and I wasn't sure how to test it. Now I know better, if the page is relatively stable you can save a version of the page you are scraping and use webmock to retrieve it in tests, or you can use VCR to record the request, which is similar.

Because I was young and innocent (I was never lol), I downloaded the page but also thought it would be a good idea to run a local server and serve the page, which I stored in the fixtures folder:

ruby -run -e httpd -- -p 4000 spec/fixtures

and then run the tests against that, for which I was using another terminal window:

bundle exec rake

I naively put this into my Travis file:

image: ruby:2.3.0

  - gem install bundler --no-ri --no-rdoc
  - bundle install --jobs $(nproc)  "${FLAGS[@]}"

    - ruby -run -e httpd -- -p 4000 spec/fixtures

    - bundle exec rspec

If you want to run a command before running the tests, you should do so specifying a "before_script" action. In the documentation examples, there is a command to start a server before running the tests. That process should run in a different thread. However, when I pushed to GitHub, Travis started the server and everything was blocked, so the process was stopped after 10 minutes, with errors like:

ruby -run -e httpd -- -p 4000 spec/fixtures
[2016-07-07 18:40:20] INFO  WEBrick 1.3.1
[2016-07-07 18:40:20] INFO  ruby 2.3.0 (2015-12-25) [x86_64-linux]
[2016-07-07 18:40:20] INFO  WEBrick::HTTPServer#start: pid=12791 port=4000

ERROR: Build failed: execution took longer than 3600 seconds

This has an easy solution, adding the & operator at the end of the command, which tells the system to run it in the background. Ah, silly me.

The information in the .travis.yml file is compiled into a bash script. Commands you specify in "before_install", "install", "script", etc., are executed sequentially.

I'm leaving it here to shame myself and to demonstrate that no matter how many years you are doing this, you still will make the stupidest mistakes. The times I've used this in the past... and I didn't see it coming.

ruby -run -e httpd -- -p 4000 spec/fixtures &