Module: TestR::Master

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

Instance Method Summary collapse

Methods included from Server

extended, quit

Instance Method Details

#load(paths, files) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
# 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

  @client.print @command_line
end

#loopObject



70
71
72
73
# File 'lib/testr/master.rb', line 70

def loop
  super
  stop
end

#stopObject



63
64
65
66
67
68
# File 'lib/testr/master.rb', line 63

def stop
  # NOTE: the SIGCHLD handler will reap these killed worker processes
  Process.kill :SIGTERM, *@command_by_worker_pid.keys.map {|pid| -pid }
rescue ArgumentError, SystemCallError
  # some workers might have already exited before we sent them the signal
end

#test(test_file, test_names) ⇒ Object



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
60
61
# File 'lib/testr/master.rb', line 23

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_forked_workers

  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 (below)
    Kernel.load test_file
  end

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