discourse/lib/turbo_tests/documentation_formatter.rb
Alan Guo Xiang Tan 655c106101
DEV: Capture and log AR debug logs on GitHub actions for flaky tests (#25048)
Why this change?

We have been running into flaky tests which seems to be related to
AR transaction problems. However, we are not able to reproduce this
locally and do not have sufficient information on our builds now to
debug the problem.

What does this change do?

Noe the following changes only applies when `ENV["GITHUB_ACTIONS"]` is
present.

This change introduces an RSpec around hook when `capture_log: true` has
been set for a test. The responsibility of the hook is to capture the
ActiveRecord debug logs and print them out.
2023-12-27 14:40:00 +08:00

69 lines
1.9 KiB
Ruby

# frozen_string_literal: true
module TurboTests
# An RSpec formatter that prepends the process id to all messages
class DocumentationFormatter < ::TurboTests::BaseFormatter
RSpec::Core::Formatters.register(self, :example_failed, :example_passed, :example_pending)
def example_passed(notification)
output.puts RSpec::Core::Formatters::ConsoleCodes.wrap(
output_example(notification.example),
:success,
)
output_activerecord_debug_logs(output, notification.example)
output.flush
end
def example_pending(notification)
message = notification.example.execution_result.pending_message
output.puts RSpec::Core::Formatters::ConsoleCodes.wrap(
"#{output_example(notification.example)} (PENDING: #{message})",
:pending,
)
output.flush
end
def example_failed(notification)
output.puts RSpec::Core::Formatters::ConsoleCodes.wrap(
"#{output_example(notification.example)} (FAILED - #{next_failure_index})",
:failure,
)
output_activerecord_debug_logs(output, notification.example)
output.flush
end
private
def output_activerecord_debug_logs(output, example)
if ENV["GITHUB_ACTIONS"] &&
active_record_debug_logs = example.metadata[:active_record_debug_logs]
output.puts "::group::ActiveRecord Debug Logs"
output.puts active_record_debug_logs
output.puts "::endgroup::"
end
end
def output_example(example)
output =
+"[#{example.process_id}] (##{example.metadata[:process_pid]}) #{example.full_description}"
if run_duration_ms = example.metadata[:run_duration_ms]
output << " (#{run_duration_ms}ms)"
end
output
end
def next_failure_index
@next_failure_index ||= 0
@next_failure_index += 1
end
end
end