class ParallelTests::Test::RuntimeLogger

def lock

def lock
  File.open(logfile, 'r') do |f|
    begin
      f.flock File::LOCK_EX
      yield
    ensure
      f.flock File::LOCK_UN
    end
  end
end

def log(test, time)

def log(test, time)
  return unless message = message(test, time)
  lock do
    File.open(logfile, 'a') { |f| f.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, time)

def message(test, time)
  return unless method = test.public_instance_methods(true).detect { |method| method =~ /^test_/ }
  delta = "%.2f" % time
  filename = test.instance_method(method).source_location.first.sub("#{Dir.pwd}/", "")
  "#{filename}:#{delta}"
end

def prepare

so there should be no log message lost
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
  lock do
    separator = "\n"
    groups = File.read(logfile).split(separator).map { |line| line.split(":") }.group_by(&:first)
    lines = groups.map { |file, times| "#{file}:#{times.map(&:last).map(&:to_f).inject(:+)}" }
    File.write(logfile, lines.join(separator) + separator)
  end
end