Module: TestR::Master

Extended by:
Master, Server
Included in:
Master
Defined in:
lib/testr/master.rb

Instance Method Summary collapse

Methods included from Server

quit

Instance Method Details

#load(paths, files) ⇒ Object



11
12
13
14
15
16
17
18
19
# File 'lib/testr/master.rb', line 11

def load paths, files
  $LOAD_PATH.unshift(*paths)

  files.each do |file|
    branch, leaf = File.split(file)
    file = leaf if paths.include? branch
    require file.sub(/\.rb$/, '')
  end
end

#loopObject



67
68
69
70
# File 'lib/testr/master.rb', line 67

def loop
  super
  stop
end

#stopObject



61
62
63
64
65
# File 'lib/testr/master.rb', line 61

def stop
  unless @command_by_worker_pid.empty?
    Process.kill :SIGKILL, *@command_by_worker_pid.keys.map {|pid| -pid }
  end
end

#test(test_file, test_names) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/testr/master.rb', line 21

def test test_file, test_names
  # throttle forking rate to meet the maximum concurrent workers limit
  sleep 1 until @command_by_worker_pid.size < Config.max_concurrent_tests
  @upstream.puts JSON.dump(@command)

  log_file = test_file + '.log'
  worker_number = @worker_number_pool.shift

  Config.before_fork_hooks.each do |hook|
    hook.call worker_number, log_file, test_file, test_names
  end

  worker_pid = fork do
    # make the process title Test::Unit friendly and ps(1) searchable
    $0 = "testr-worker[#{worker_number}] #{test_file}"

    # detach worker process from master process' group for kill -pgrp
    Process.setsid

    # detach worker process from master process' standard input stream
    STDIN.reopen IO.pipe.first

    # capture test output in log file because tests are run in parallel
    # which makes it difficult to understand interleaved output thereof
    STDERR.reopen(STDOUT.reopen(log_file, 'w')).sync = true

    Config.after_fork_hooks.each do |hook|
      hook.call worker_number, log_file, test_file, test_names
    end

    # after loading the user's test file, the at_exit() hook of the user's
    # testing framework will take care of running the tests and reflecting
    # any failures in the worker process' exit status, which will then be
    # handled by the SIGCHLD trap registered in the master process (above)
    Kernel.load test_file
  end

  @command_by_worker_pid[worker_pid] = @command.push(worker_number)
end