Best pattern for "captive" servers in testing?

So I'm wondering what other people do in this scenario:

  • You have an executable that provides a (networked) service
  • You want to test against the executable's service
  • You want to be able to start/stop the executable during the tests
  • You want to be able to run multiple executables between test suites (i.e. with different configs for each suite of tests)

I'm mostly been using subprocess, and this works; but I always seem to wind up with situations where the child process is hung, or winds up running past the execution of the tearDown() for the suite.  Any given failure can almost always be fixed, but it always feels messy and low-level, and it just feels like there should be something better.

So, how do *you* run captive servers?

Comments

  1. Jean-Paul Calderone

    Jean-Paul Calderone on 02/03/2010 9:42 p.m. #

    I haven't had to write a test like this in quite a while, so this isn't how *I* do it, but...

    If you run a child process with Twisted's spawnProcess, and you run your tests with trial (or maybe the logic is in trial's TestCase, and you can use any runner, I'm not sure), then the child process will never be allowed to run past the end of the test.

    If your test also avoids blocking and, say, returns a Deferred to represent completion, then trial will also enforce a (configurable) two minute timeout for you, which should help with cases where the child hangs.

    Maybe that helps you, maybe not. :)

  2. Nick Barendt

    Nick Barendt on 02/04/2010 7:50 a.m. #

    I often have the same problem.

    I've resorted to subprocess, as well, with the tearDown() calling a platform-specific process_kill() (kill on Unix and subprocess of taskkill on Win32) to make sure the server process is cleaned up, one way or another.

    I'd like to hear of better solutions.

  3. Jacob Oscarson

    Jacob Oscarson on 02/04/2010 8:16 a.m. #

    A somewhat heavy-handed approach (requires a Posix'y system):

    Let the server processes be handled bySupervisor
    (http://supervisord.org/), call it (via subprocess or something) to
    control the server processes. Supervisor is good at knocking down
    uncooperative processes.

  4. Mike C. Fletcher

    Mike C. Fletcher on 02/09/2010 1:21 a.m. #

    Hmm, Trial is probably too much of a departure for this project. Supervisord likely as well, but other projects might be able to use it. I'd really like something that was in pure Python (i.e. that I could just use in projects without any large dependency being injected).

  5. Felix Schwarz

    Felix Schwarz on 02/16/2010 4:06 p.m. #

    We actually use trac's functional test infrastructure (heavily modified). It has custom kills + subprocess.

Comments are closed.

Pingbacks

Pingbacks are closed.