Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions lib/buildkite/test_collector/cucumber_plugin/trace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,33 @@

module Buildkite::TestCollector::CucumberPlugin
class Trace < Buildkite::TestCollector::Trace
attr_accessor :scenario, :failure_reason, :failure_expanded
attr_accessor :failure_reason, :failure_expanded
attr_reader :history, :tags, :location_prefix

FILE_PATH_REGEX = /^(.*?\.(rb|feature))/

def initialize(scenario, history:, failure_reason: nil, failure_expanded: [], tags: nil, location_prefix: nil)
@scenario = scenario
@history = history
@failure_reason = failure_reason
@failure_expanded = failure_expanded
@tags = tags
@location_prefix = location_prefix

# Extract all data eagerly to allow GC of the scenario object
@result = if scenario.passed?
'passed'
elsif scenario.failed?
'failed'
else
'skipped'
end
@name = scenario.name
@location = scenario.location&.to_s
@file_name = @location&.to_s[FILE_PATH_REGEX]
end

def result
if scenario.passed?
'passed'
elsif scenario.failed?
'failed'
else
'skipped'
end
@result
end

private
Expand All @@ -41,15 +46,15 @@ def scope
end

def name
scenario.name
@name
end

def location
scenario.location&.to_s
@location
end

def file_name
@file_name ||= location&.to_s[FILE_PATH_REGEX]
@file_name
end
end
end
2 changes: 1 addition & 1 deletion lib/buildkite/test_collector/minitest_plugin/reporter.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

module Buildkite::TestCollector::MinitestPlugin
class Reporter < Minitest::StatisticsReporter
class Reporter < Minitest::Reporter
def initialize(io, options)
super
@io = io
Expand Down
43 changes: 24 additions & 19 deletions lib/buildkite/test_collector/minitest_plugin/trace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

module Buildkite::TestCollector::MinitestPlugin
class Trace < Buildkite::TestCollector::Trace
attr_accessor :example
attr_writer :failure_reason, :failure_expanded
attr_reader :history
attr_reader :location_prefix
attr_reader :tags
Expand All @@ -18,28 +16,45 @@ class Trace < Buildkite::TestCollector::Trace
FILE_PATH_REGEX = /^(.*?\.(rb|feature))/

def initialize(example, history:, tags: nil, trace: nil, location_prefix: nil)
@example = example
@history = history
@tags = tags
@location_prefix = location_prefix

# Extract all data eagerly to allow GC of the test object
@source_location = example.method(example.name).source_location
@result = RESULT_CODES[example.result_code]
@scope = example.class.name
@name = example.name
@failure_reason = strip_invalid_utf8_chars(example.failure&.message)&.split("\n")&.first
@failure_expanded = example.failures.map.with_index do |failure, index|
# remove the first line of message from the first failure
# to avoid duplicate line in Test Analytics UI
messages = strip_invalid_utf8_chars(failure.message).split("\n")
messages = messages[1..-1] if index.zero?

{
expanded: messages,
backtrace: failure.backtrace
}
end
end

def result
RESULT_CODES[example.result_code]
@result
end

def source_location
@source_location ||= example.method(example.name).source_location
@source_location
end

private

def scope
example.class.name
@scope
end

def name
example.name
@name
end

def location
Expand All @@ -65,21 +80,11 @@ def project_dir
end

def failure_reason
@failure_reason ||= strip_invalid_utf8_chars(example.failure&.message)&.split("\n")&.first
@failure_reason
end

def failure_expanded
@failure_expanded ||= example.failures.map.with_index do |failure, index|
# remove the first line of message from the first failure
# to avoid duplicate line in Test Analytics UI
messages = strip_invalid_utf8_chars(failure.message).split("\n")
messages = messages[1..-1] if index.zero?

{
expanded: messages,
backtrace: failure.backtrace
}
end
@failure_expanded
end
end
end
6 changes: 5 additions & 1 deletion lib/buildkite/test_collector/rspec_plugin/reporter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ def handle_example(notification)
trace = Buildkite::TestCollector.uploader.traces[example.id]

if trace
trace.example = example
trace.result = case example.execution_result.status
when :passed; "passed"
when :failed; "failed"
when :pending; "skipped"
end
if example.execution_result.status == :failed
trace.failure_reason, trace.failure_expanded = failure_info(notification)
end
Expand Down
36 changes: 17 additions & 19 deletions lib/buildkite/test_collector/rspec_plugin/trace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,54 @@

module Buildkite::TestCollector::RSpecPlugin
class Trace < Buildkite::TestCollector::Trace
attr_accessor :example, :failure_reason, :failure_expanded
attr_accessor :failure_reason, :failure_expanded
attr_writer :result
attr_reader :history
attr_reader :tags
attr_reader :location_prefix

FILE_PATH_REGEX = /^(.*?\.(rb|feature))/

def initialize(example, history:, failure_reason: nil, failure_expanded: [], tags: nil, location_prefix: nil)
@example = example
@history = history
@failure_reason = failure_reason
@failure_expanded = failure_expanded
@tags = tags
@location_prefix = location_prefix

# Extract all data eagerly to allow GC of the test object
@scope = example.example_group.metadata[:full_description]
@name = example.description
@location = example.location
@id = strip_invalid_utf8_chars(example.id)
@shared_group_inclusion_backtrace = example.metadata[:shared_group_inclusion_backtrace]
end

def result
case example.execution_result.status
when :passed; "passed"
when :failed; "failed"
when :pending; "skipped"
end
@result
end

private

def scope
example.example_group.metadata[:full_description]
@scope
end

def name
example.description
@name
end

def location
example.location
@location
end

def file_name
@file_name ||= begin
identifier_file_name = strip_invalid_utf8_chars(example.id)[FILE_PATH_REGEX]
location_file_name = example.location[FILE_PATH_REGEX]
identifier_file_name = @id[FILE_PATH_REGEX]
location_file_name = @location[FILE_PATH_REGEX]

if identifier_file_name != location_file_name
# If the identifier and location files are not the same, we assume
# that the test was run as part of a shared example. If this isn't the
# case, then there's something we haven't accounted for
if shared_example?
# Taking the last frame in this backtrace will give us the original
# entry point for the shared example
shared_example_call_location[FILE_PATH_REGEX]
else
"Unknown"
Expand All @@ -63,11 +61,11 @@ def file_name
end

def shared_example?
!example.metadata[:shared_group_inclusion_backtrace].empty?
!@shared_group_inclusion_backtrace.empty?
end

def shared_example_call_location
example.metadata[:shared_group_inclusion_backtrace].last.inclusion_location
@shared_group_inclusion_backtrace.last.inclusion_location
end
end
end
4 changes: 2 additions & 2 deletions spec/support/rspec_example_trace_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ def fake_example(opts = {})
end

def fake_trace(a_example)
fake_trace = double("Buildkite::TestCollector::RSpecPlugin::Trace", example: a_example)
fake_trace = double("Buildkite::TestCollector::RSpecPlugin::Trace")
allow(fake_trace).to receive(:[]) { fake_trace }
allow(fake_trace).to receive(:example=)
allow(fake_trace).to receive(:result=)
allow(fake_trace).to receive(:failure_reason=)
allow(fake_trace).to receive(:failure_expanded=)
fake_trace
Expand Down
9 changes: 7 additions & 2 deletions spec/test_collector/http_client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@
description: "mince and cheese",
id: "12",
location: "123 Pie St",
execution_result: execution_result
execution_result: execution_result,
metadata: { shared_group_inclusion_backtrace: [] }
)
end

let(:trace) { Buildkite::TestCollector::RSpecPlugin::Trace.new(example, history: "pie lore") }
let(:trace) do
t = Buildkite::TestCollector::RSpecPlugin::Trace.new(example, history: "pie lore")
t.result = "passed"
t
end

let(:http_double) { double("Net::HTTP_double") }
let(:post_double) { double("Net::HTTP::Post") }
Expand Down