2021-12-11 22:18:48 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2023-01-13 00:05:48 +05:30
|
|
|
require 'fast_spec_helper'
|
2021-12-11 22:18:48 +05:30
|
|
|
require_relative '../../scripts/pipeline_test_report_builder'
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
RSpec.describe PipelineTestReportBuilder, feature_category: :tooling do
|
2021-12-11 22:18:48 +05:30
|
|
|
let(:report_file) { 'spec/fixtures/scripts/test_report.json' }
|
|
|
|
let(:output_file_path) { 'tmp/previous_test_results/output_file.json' }
|
2023-04-23 21:23:45 +05:30
|
|
|
let(:options) do
|
|
|
|
described_class::DEFAULT_OPTIONS.merge(
|
2021-12-11 22:18:48 +05:30
|
|
|
target_project: 'gitlab-org/gitlab',
|
2023-05-27 22:25:52 +05:30
|
|
|
current_pipeline_id: '42',
|
2021-12-11 22:18:48 +05:30
|
|
|
mr_id: '999',
|
|
|
|
instance_base_url: 'https://gitlab.com',
|
|
|
|
output_file_path: output_file_path
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
let(:previous_pipeline_url) { '/pipelines/previous' }
|
2021-12-11 22:18:48 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
let(:previous_pipeline) do
|
2021-12-11 22:18:48 +05:30
|
|
|
{
|
|
|
|
'status' => 'failed',
|
2023-04-23 21:23:45 +05:30
|
|
|
'id' => 1,
|
|
|
|
'web_url' => previous_pipeline_url
|
2021-12-11 22:18:48 +05:30
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
let(:latest_pipeline_url) { '/pipelines/latest' }
|
|
|
|
|
|
|
|
let(:latest_pipeline) do
|
2021-12-11 22:18:48 +05:30
|
|
|
{
|
|
|
|
'status' => 'running',
|
2023-04-23 21:23:45 +05:30
|
|
|
'id' => 3,
|
|
|
|
'web_url' => latest_pipeline_url
|
2021-12-11 22:18:48 +05:30
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
let(:mr_pipelines) { [latest_pipeline, previous_pipeline] }
|
2021-12-11 22:18:48 +05:30
|
|
|
|
|
|
|
let(:failed_build_id) { 9999 }
|
|
|
|
|
|
|
|
let(:failed_builds_for_pipeline) do
|
|
|
|
[
|
|
|
|
{
|
|
|
|
'id' => failed_build_id,
|
|
|
|
'stage' => 'test'
|
|
|
|
}
|
|
|
|
]
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:test_report_for_build) do
|
|
|
|
{
|
|
|
|
"name": "rspec-ee system pg11 geo",
|
|
|
|
"failed_count": 41,
|
|
|
|
"test_cases": [
|
|
|
|
{
|
|
|
|
"status": "failed",
|
|
|
|
"name": "example",
|
|
|
|
"classname": "ee.spec.features.geo_node_spec",
|
|
|
|
"file": "./ee/spec/features/geo_node_spec.rb",
|
|
|
|
"execution_time": 6.324748,
|
|
|
|
"system_output": {
|
|
|
|
"__content__": "\n",
|
|
|
|
"message": "RSpec::Core::MultipleExceptionError",
|
|
|
|
"type": "RSpec::Core::MultipleExceptionError"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
subject { described_class.new(options) }
|
|
|
|
|
2021-12-11 22:18:48 +05:30
|
|
|
before do
|
|
|
|
allow(subject).to receive(:pipelines_for_mr).and_return(mr_pipelines)
|
|
|
|
allow(subject).to receive(:failed_builds_for_pipeline).and_return(failed_builds_for_pipeline)
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#previous_pipeline' do
|
|
|
|
let(:fork_pipeline_url) { 'fork_pipeline_url' }
|
|
|
|
let(:fork_pipeline) do
|
|
|
|
{
|
|
|
|
'status' => 'failed',
|
2023-04-23 21:23:45 +05:30
|
|
|
'id' => 2,
|
2021-12-11 22:18:48 +05:30
|
|
|
'web_url' => fork_pipeline_url
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(subject).to receive(:test_report_for_build).and_return(test_report_for_build)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'pipeline in a fork project' do
|
2023-04-23 21:23:45 +05:30
|
|
|
let(:mr_pipelines) { [latest_pipeline, fork_pipeline] }
|
2021-12-11 22:18:48 +05:30
|
|
|
|
|
|
|
it 'returns fork pipeline' do
|
|
|
|
expect(subject.previous_pipeline).to eq(fork_pipeline)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'pipeline in target project' do
|
|
|
|
it 'returns failed pipeline' do
|
2023-04-23 21:23:45 +05:30
|
|
|
expect(subject.previous_pipeline).to eq(previous_pipeline)
|
2021-12-11 22:18:48 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
describe '#test_report_for_pipeline' do
|
|
|
|
context 'for previous pipeline' do
|
|
|
|
let(:failed_build_uri) { "#{previous_pipeline_url}/tests/suite.json?build_ids[]=#{failed_build_id}" }
|
2021-12-11 22:18:48 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
before do
|
|
|
|
allow(subject).to receive(:fetch).with(failed_build_uri).and_return(test_report_for_build)
|
2021-12-11 22:18:48 +05:30
|
|
|
end
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
it 'fetches builds from pipeline related to MR' do
|
|
|
|
expected = { "suites" => [test_report_for_build.merge('job_url' => "/jobs/#{failed_build_id}")] }.to_json
|
|
|
|
expect(subject.test_report_for_pipeline).to eq(expected)
|
2021-12-11 22:18:48 +05:30
|
|
|
end
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
context 'canonical pipeline' do
|
|
|
|
context 'no previous pipeline' do
|
|
|
|
let(:mr_pipelines) { [] }
|
2021-12-11 22:18:48 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
it 'returns empty hash' do
|
|
|
|
expect(subject.test_report_for_pipeline).to eq("{}")
|
|
|
|
end
|
2021-12-11 22:18:48 +05:30
|
|
|
end
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
context 'no failed test builds' do
|
|
|
|
let(:failed_builds_for_pipeline) do
|
|
|
|
[
|
|
|
|
{
|
|
|
|
'id' => 9999,
|
|
|
|
'stage' => 'prepare'
|
|
|
|
}
|
|
|
|
]
|
|
|
|
end
|
2021-12-11 22:18:48 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
it 'returns a hash with an empty "suites" array' do
|
|
|
|
expect(subject.test_report_for_pipeline).to eq({ suites: [] }.to_json)
|
|
|
|
end
|
2021-12-11 22:18:48 +05:30
|
|
|
end
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
context 'failed pipeline and failed test builds' do
|
|
|
|
before do
|
|
|
|
allow(subject).to receive(:fetch).with(failed_build_uri).and_return(test_report_for_build)
|
|
|
|
end
|
2022-08-13 15:12:31 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
it 'returns populated test list for suites' do
|
|
|
|
actual = subject.test_report_for_pipeline
|
|
|
|
expected = {
|
|
|
|
'suites' => [test_report_for_build]
|
|
|
|
}.to_json
|
2021-12-11 22:18:48 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
expect(actual).to eq(expected)
|
|
|
|
end
|
2021-12-11 22:18:48 +05:30
|
|
|
end
|
2022-08-13 15:12:31 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
context 'when receiving a server error' do
|
|
|
|
let(:response) { instance_double('Net::HTTPResponse') }
|
|
|
|
let(:error) { Net::HTTPServerException.new('server error', response) }
|
|
|
|
let(:test_report_for_pipeline) { subject.test_report_for_pipeline }
|
2022-08-13 15:12:31 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
before do
|
|
|
|
allow(response).to receive(:code).and_return(response_code)
|
|
|
|
allow(subject).to receive(:fetch).with(failed_build_uri).and_raise(error)
|
|
|
|
end
|
2022-08-13 15:12:31 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
context 'when response code is 404' do
|
|
|
|
let(:response_code) { 404 }
|
2022-08-13 15:12:31 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
it 'continues without the missing reports' do
|
|
|
|
expected = { suites: [] }.to_json
|
2022-08-13 15:12:31 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
expect { test_report_for_pipeline }.not_to raise_error
|
|
|
|
expect(test_report_for_pipeline).to eq(expected)
|
|
|
|
end
|
2022-08-13 15:12:31 +05:30
|
|
|
end
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
context 'when response code is unexpected' do
|
|
|
|
let(:response_code) { 500 }
|
2022-08-13 15:12:31 +05:30
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
it 'raises HTTPServerException' do
|
|
|
|
expect { test_report_for_pipeline }.to raise_error(error)
|
|
|
|
end
|
2022-08-13 15:12:31 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2021-12-11 22:18:48 +05:30
|
|
|
end
|
2023-04-23 21:23:45 +05:30
|
|
|
|
|
|
|
context 'for latest pipeline' do
|
|
|
|
let(:failed_build_uri) { "#{latest_pipeline_url}/tests/suite.json?build_ids[]=#{failed_build_id}" }
|
2023-05-27 22:25:52 +05:30
|
|
|
let(:current_pipeline_uri) do
|
|
|
|
"#{options[:api_endpoint]}/projects/#{options[:target_project]}/pipelines/#{options[:current_pipeline_id]}"
|
|
|
|
end
|
2023-04-23 21:23:45 +05:30
|
|
|
|
|
|
|
subject { described_class.new(options.merge(pipeline_index: :latest)) }
|
|
|
|
|
|
|
|
it 'fetches builds from pipeline related to MR' do
|
2023-05-27 22:25:52 +05:30
|
|
|
expect(subject).to receive(:fetch).with(current_pipeline_uri).and_return(mr_pipelines[0])
|
2023-04-23 21:23:45 +05:30
|
|
|
expect(subject).to receive(:fetch).with(failed_build_uri).and_return(test_report_for_build)
|
|
|
|
|
|
|
|
subject.test_report_for_pipeline
|
|
|
|
end
|
|
|
|
end
|
2021-12-11 22:18:48 +05:30
|
|
|
end
|
|
|
|
end
|