3

I have a headless application that uses sockets for communication. When launched, it remains active until sent a message telling it to quit (or it crashes, or is killed).

When unit testing this application using Ruby, I need to launch the process, interact with it (via sockets), and then kill it.

I thought I could do this using this pattern:

class TestServer < MiniTest::Unit::TestCase
  def setup
    @thread = Thread.new{ `#{MY_COMMAND}` }
  end

  def test_aaa
    # my test code
  end

  def teardown
    @thread.kill if @thread
  end
end

However, that teardown code kills the thread but does not kill the process launched by it.

How can I launch the process in a way that:

  1. Allows it to run in the background (immediately returns control to my Ruby test harness)
  2. Allows me to force kill the process later on, if need be.

I happen to be developing on OS X, but if possible I'd appreciate a generic solution that works across all OS where Ruby runs.

Phrogz
  • 296,393
  • 112
  • 651
  • 745

1 Answers1

2

You can use Process.spawn instead of threads and backticks:

class TestServer < MiniTest::Unit::TestCase
  def setup
    @pid = spawn "#{MY_COMMAND}"
  end

  def test_aaa
    # my test code
  end

  def teardown
    Process.kill('TERM', @pid) if @pid
  end
end
Adrian
  • 14,931
  • 9
  • 45
  • 70
  • Thanks! As you were answering I found [another answer](http://stackoverflow.com/a/3579050/405017) which suggests `@pid = Process.fork{ exec "my_command" }`. Are you able to comment on the functional difference (if any) between these two? – Phrogz Aug 01 '15 at 05:22
  • Never mind, I [found that answer](http://stackoverflow.com/a/4129557/405017), too. :) – Phrogz Aug 01 '15 at 05:24