class ParallelTests::Test::RuntimeLogger
def log(test, time)
def log(test, time) return unless message = message(test, time) with_locked_log do |logfile| logfile.seek(0, IO::SEEK_END) logfile.puts message end end
def log_test_run(test)
def log_test_run(test) prepare result = nil time = ParallelTests.delta { result = yield } log(test, time) result end
def logfile
def logfile ParallelTests::Test::Runner.runtime_log end
def message(test, delta)
def message(test, delta) return unless method = test.public_instance_methods(true).detect { |m| m =~ /^test_/ } filename = test.instance_method(method).source_location.first.sub("#{Dir.pwd}/", "") "#{filename}:#{delta}" end
def prepare
this will happen in multiple processes, but should be roughly at the same time
ensure folder exists + clean out previous log
def prepare return if @@prepared @@prepared = true FileUtils.mkdir_p(File.dirname(logfile)) File.write(logfile, '') end
def unique_log
def unique_log with_locked_log do |logfile| separator = "\n" groups = logfile.read.split(separator).map { |line| line.split(":") }.group_by(&:first) lines = groups.map do |file, times| time = "%.2f" % times.map(&:last).map(&:to_f).sum "#{file}:#{time}" end logfile.rewind logfile.write(lines.join(separator) + separator) logfile.truncate(logfile.pos) end end
def with_locked_log
def with_locked_log File.open(logfile, File::RDWR | File::CREAT) do |logfile| logfile.flock(File::LOCK_EX) yield logfile end end