1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
#!/usr/bin/env ruby
# frozen_string_literal: true
require "json"
require_relative "../lib/sus/config"
config = Sus::Config.load
require_relative "../lib/sus"
verbose = false
guard = Thread::Mutex.new
require "etc"
count = Etc.nprocessors
$stdout.sync = true
require_relative "../lib/sus/output/structured"
input = $stdin.dup
$stdin.reopen(File::NULL)
output = $stdout.dup
$stdout.reopen($stderr)
def messages_for(assertions)
messages = []
assertions.each_failure do |failure|
messages << failure.message
end
return messages
end
while line = input.gets
message = JSON.parse(line)
if tests = message["run"]
jobs = Thread::Queue.new
results = Thread::Queue.new
top = Sus::Assertions.new(measure: true)
config.before_tests(top)
aggregate = Thread.new do
while result = results.pop
top.add(result)
end
end
loader = Thread.new do
registry = config.load_registry(tests)
registry.each do |child|
jobs << child
end
jobs.close
end
workers = count.times.map do |index|
Thread.new do
while job = jobs.pop
guard.synchronize do
output.puts JSON.generate({started: job.identity})
end
structured_output = Sus::Output::Structured.buffered(output, job.identity)
assertions = Sus::Assertions.new(output: structured_output, measure: true)
job.call(assertions)
results.push(assertions)
guard.synchronize do
if assertions.passed?
output.puts JSON.generate({passed: job.identity, messages: messages_for(assertions), duration: assertions.clock.ms})
elsif assertions.errored?
output.puts JSON.generate({errored: job.identity, messages: messages_for(assertions), duration: assertions.clock.ms})
else
output.puts JSON.generate({failed: job.identity, messages: messages_for(assertions), duration: assertions.clock.ms})
end
end
end
end
end
loader.join
workers.each(&:join)
results.close
aggregate.join
config.after_tests(top)
workers.each(&:join)
if config.respond_to?(:covered)
if covered = config.covered and covered.record?
covered.policy.each do |coverage|
output.puts JSON.generate({coverage: coverage.path, counts: coverage.counts})
end
end
end
output.puts JSON.generate({finished: true, message: top.output.string, duration: top.clock.ms})
else
$stderr.puts "Unknown message: #{message}"
end
end
|