diff --git a/ruby/lib/ci/queue/configuration.rb b/ruby/lib/ci/queue/configuration.rb index 1941b81e..f7aa3601 100644 --- a/ruby/lib/ci/queue/configuration.rb +++ b/ruby/lib/ci/queue/configuration.rb @@ -3,7 +3,7 @@ module CI module Queue class Configuration attr_accessor :timeout, :worker_id, :max_requeues, :grind_count, :failure_file, :export_flaky_tests_file - attr_accessor :requeue_tolerance, :namespace, :failing_test, :statsd_endpoint + attr_accessor :requeue_tolerance, :namespace, :failing_test, :statsd_endpoint, :summary_file attr_accessor :max_test_duration, :max_test_duration_percentile, :track_test_duration attr_accessor :max_test_failed, :redis_ttl, :warnings_file, :debug_log, :max_missed_heartbeat_seconds attr_reader :circuit_breakers @@ -37,7 +37,8 @@ def initialize( grind_count: nil, max_duration: nil, failure_file: nil, max_test_duration: nil, max_test_duration_percentile: 0.5, track_test_duration: false, max_test_failed: nil, queue_init_timeout: nil, redis_ttl: 8 * 60 * 60, report_timeout: nil, inactive_workers_timeout: nil, - export_flaky_tests_file: nil, warnings_file: nil, debug_log: nil, max_missed_heartbeat_seconds: nil) + export_flaky_tests_file: nil, warnings_file: nil, debug_log: nil, max_missed_heartbeat_seconds: nil, + summary_file: nil) @build_id = build_id @circuit_breakers = [CircuitBreaker::Disabled] @failure_file = failure_file @@ -62,6 +63,7 @@ def initialize( @inactive_workers_timeout = inactive_workers_timeout @export_flaky_tests_file = export_flaky_tests_file @warnings_file = warnings_file + @summary_file = summary_file @debug_log = debug_log @max_missed_heartbeat_seconds = max_missed_heartbeat_seconds end diff --git a/ruby/lib/ci/queue/redis/build_record.rb b/ruby/lib/ci/queue/redis/build_record.rb index b1329ff9..1ed92795 100644 --- a/ruby/lib/ci/queue/redis/build_record.rb +++ b/ruby/lib/ci/queue/redis/build_record.rb @@ -66,6 +66,7 @@ def record_error(id, payload, stats: nil) pipeline.expire(key('error-reports'), config.redis_ttl) record_stats(stats, pipeline: pipeline) end + record_executed_tests(id) nil end @@ -75,10 +76,20 @@ def record_success(id, stats: nil, skip_flaky_record: false) pipeline.hget(key('requeues-count'), id.b) record_stats(stats, pipeline: pipeline) end + record_executed_tests(id) record_flaky(id) if !skip_flaky_record && (error_reports_deleted_count.to_i > 0 || requeued_count.to_i > 0) nil end + def record_executed_tests(id) + return unless ENV['LOG_EXECUTED_TESTS'] + redis.pipelined do |pipeline| + pipeline.sadd?(key('executed-tests'), id.b) + pipeline.expire(key('executed-tests'), config.redis_ttl) + end + nil + end + def record_flaky(id, stats: nil) redis.pipelined do |pipeline| pipeline.sadd?( @@ -104,6 +115,10 @@ def flaky_reports redis.smembers(key('flaky-reports')) end + def executed_tests + redis.smembers(key('executed-tests')) + end + def fetch_stats(stat_names) counts = redis.pipelined do |pipeline| stat_names.each { |c| pipeline.hvals(key(c)) } diff --git a/ruby/lib/minitest/queue/build_status_reporter.rb b/ruby/lib/minitest/queue/build_status_reporter.rb index b34084cb..43158a25 100644 --- a/ruby/lib/minitest/queue/build_status_reporter.rb +++ b/ruby/lib/minitest/queue/build_status_reporter.rb @@ -21,6 +21,10 @@ def flaky_reports build.flaky_reports end + def executed_tests + build.executed_tests + end + def requeued_tests build.requeued_tests end @@ -82,6 +86,18 @@ def progress build.progress end + def write_summary_file(total_tests, file) + File.write(file, { + total_tests: total_tests, + failures: failures, + errors: errors, + skips: skips, + requeues: requeues, + total_executed_tests: executed_tests.size, + executed_tests: executed_tests, + }.to_json) + end + def write_failure_file(file) File.write(file, error_reports.map(&:to_h).to_json) end diff --git a/ruby/lib/minitest/queue/runner.rb b/ruby/lib/minitest/queue/runner.rb index 5b437088..33cc0f4b 100644 --- a/ruby/lib/minitest/queue/runner.rb +++ b/ruby/lib/minitest/queue/runner.rb @@ -276,6 +276,7 @@ def report_command reporter = BuildStatusReporter.new(build: supervisor.build) reporter.write_failure_file(queue_config.failure_file) if queue_config.failure_file reporter.write_flaky_tests_file(queue_config.export_flaky_tests_file) if queue_config.export_flaky_tests_file + reporter.write_summary_file(supervisor.total, queue_config.summary_file) if queue_config.summary_file reporter.report exit! reporter.success? ? 0 : 1 @@ -551,6 +552,15 @@ def parser queue_config.export_flaky_tests_file = file end + help = <<~EOS + Defines a file where summary of test execution is written. + Defaults to disabled. + EOS + opts.separator "" + opts.on('--summary-file FILE', help) do |file| + queue_config.summary_file = file + end + help = <<~EOS Defines a file where warnings during the execution are written to. Defaults to disabled.