Commit b8335525 authored by Maxime Orefice's avatar Maxime Orefice Committed by Sean McGivern

Add attachment attribute to a test case

This MR makes it possible to parse an attachment tag on a JUnit report.
It creates a new attachment attribute on a test case object.
parent 76ed3182
...@@ -6,6 +6,7 @@ module Gitlab ...@@ -6,6 +6,7 @@ module Gitlab
module Test module Test
class Junit class Junit
JunitParserError = Class.new(Gitlab::Ci::Parsers::ParserError) JunitParserError = Class.new(Gitlab::Ci::Parsers::ParserError)
ATTACHMENT_TAG_REGEX = /\[\[ATTACHMENT\|(?<path>.+?)\]\]/.freeze
def parse!(xml_data, test_suite) def parse!(xml_data, test_suite)
root = Hash.from_xml(xml_data) root = Hash.from_xml(xml_data)
...@@ -49,6 +50,7 @@ module Gitlab ...@@ -49,6 +50,7 @@ module Gitlab
if data['failure'] if data['failure']
status = ::Gitlab::Ci::Reports::TestCase::STATUS_FAILED status = ::Gitlab::Ci::Reports::TestCase::STATUS_FAILED
system_output = data['failure'] system_output = data['failure']
attachment = attachment_path(data['system_out'])
elsif data['error'] elsif data['error']
status = ::Gitlab::Ci::Reports::TestCase::STATUS_ERROR status = ::Gitlab::Ci::Reports::TestCase::STATUS_ERROR
system_output = data['error'] system_output = data['error']
...@@ -63,9 +65,17 @@ module Gitlab ...@@ -63,9 +65,17 @@ module Gitlab
file: data['file'], file: data['file'],
execution_time: data['time'], execution_time: data['time'],
status: status, status: status,
system_output: system_output system_output: system_output,
attachment: attachment
) )
end end
def attachment_path(data)
return unless data
matches = data.match(ATTACHMENT_TAG_REGEX)
matches[:path] if matches
end
end end
end end
end end
......
...@@ -10,9 +10,9 @@ module Gitlab ...@@ -10,9 +10,9 @@ module Gitlab
STATUS_ERROR = 'error' STATUS_ERROR = 'error'
STATUS_TYPES = [STATUS_SUCCESS, STATUS_FAILED, STATUS_SKIPPED, STATUS_ERROR].freeze STATUS_TYPES = [STATUS_SUCCESS, STATUS_FAILED, STATUS_SKIPPED, STATUS_ERROR].freeze
attr_reader :name, :classname, :execution_time, :status, :file, :system_output, :stack_trace, :key attr_reader :name, :classname, :execution_time, :status, :file, :system_output, :stack_trace, :key, :attachment
def initialize(name:, classname:, execution_time:, status:, file: nil, system_output: nil, stack_trace: nil) def initialize(name:, classname:, execution_time:, status:, file: nil, system_output: nil, stack_trace: nil, attachment: nil)
@name = name @name = name
@classname = classname @classname = classname
@file = file @file = file
...@@ -21,6 +21,11 @@ module Gitlab ...@@ -21,6 +21,11 @@ module Gitlab
@system_output = system_output @system_output = system_output
@stack_trace = stack_trace @stack_trace = stack_trace
@key = sanitize_key_name("#{classname}_#{name}") @key = sanitize_key_name("#{classname}_#{name}")
@attachment = attachment
end
def has_attachment?
attachment.present?
end end
private private
......
# frozen_string_literal: true
FactoryBot.define do
factory :test_case, class: 'Gitlab::Ci::Reports::TestCase' do
name { "test-1" }
classname { "trace" }
file { "spec/trace_spec.rb" }
execution_time { 1.23 }
status { "success" }
system_output { nil }
attachment { nil }
trait :with_attachment do
attachment { "some/path.png" }
end
skip_create
initialize_with do
new(
name: name,
classname: classname,
file: file,
execution_time: execution_time,
status: status,
system_output: system_output,
attachment: attachment
)
end
end
end
...@@ -205,6 +205,75 @@ describe Gitlab::Ci::Parsers::Test::Junit do ...@@ -205,6 +205,75 @@ describe Gitlab::Ci::Parsers::Test::Junit do
end end
end end
context 'when data contains an attachment tag' do
let(:junit) do
<<~EOF
<testsuites>
<testsuite>
<testcase classname='Calculator' name='sumTest1' time='0.01'>
<failure>Some failure</failure>
<system-out>[[ATTACHMENT|some/path.png]]</system-out>
</testcase>
</testsuite>
</testsuites>
EOF
end
it 'add attachment to a test case' do
expect { subject }.not_to raise_error
expect(test_cases[0].has_attachment?).to be_truthy
expect(test_cases[0].attachment).to eq("some/path.png")
end
end
context 'when data contains multiple attachments tag' do
let(:junit) do
<<~EOF
<testsuites>
<testsuite>
<testcase classname='Calculator' name='sumTest1' time='0.01'>
<failure>Some failure</failure>
<system-out>
[[ATTACHMENT|some/path.png]]
[[ATTACHMENT|some/path.html]]
</system-out>
</testcase>
</testsuite>
</testsuites>
EOF
end
it 'adds the first match attachment to a test case' do
expect { subject }.not_to raise_error
expect(test_cases[0].has_attachment?).to be_truthy
expect(test_cases[0].attachment).to eq("some/path.png")
end
end
context 'when data does not match attachment tag regex' do
let(:junit) do
<<~EOF
<testsuites>
<testsuite>
<testcase classname='Calculator' name='sumTest1' time='0.01'>
<failure>Some failure</failure>
<system-out>[[attachment]some/path.png]]</system-out>
</testcase>
</testsuite>
</testsuites>
EOF
end
it 'does not add attachment to a test case' do
expect { subject }.not_to raise_error
expect(test_cases[0].has_attachment?).to be_falsy
expect(test_cases[0].attachment).to be_nil
end
end
private private
def flattened_test_cases(test_suite) def flattened_test_cases(test_suite)
......
...@@ -88,5 +88,17 @@ describe Gitlab::Ci::Reports::TestCase do ...@@ -88,5 +88,17 @@ describe Gitlab::Ci::Reports::TestCase do
expect { test_case }.to raise_error(ArgumentError) expect { test_case }.to raise_error(ArgumentError)
end end
end end
context 'when attachment is present' do
let(:attachment_test_case) { build(:test_case, :with_attachment) }
it "initializes the attachment if present" do
expect(attachment_test_case.attachment).to eq("some/path.png")
end
it '#has_attachment?' do
expect(attachment_test_case.has_attachment?).to be_truthy
end
end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment