Commit fcd59f2d authored by Thong Kuah's avatar Thong Kuah

Merge branch 'mc/backstage/artifact-junit-pipeline-endpoint' into 'master'

Expose test_reports in PipelineDetailsEntity

See merge request gitlab-org/gitlab!18022
parents 00f4426b 768d4f55
# frozen_string_literal: true # frozen_string_literal: true
class Projects::PipelinesController < Projects::ApplicationController class Projects::PipelinesController < Projects::ApplicationController
include ::Gitlab::Utils::StrongMemoize
before_action :whitelist_query_limiting, only: [:create, :retry] before_action :whitelist_query_limiting, only: [:create, :retry]
before_action :pipeline, except: [:index, :new, :create, :charts] before_action :pipeline, except: [:index, :new, :create, :charts]
before_action :set_pipeline_path, only: [:show] before_action :set_pipeline_path, only: [:show]
...@@ -151,6 +153,19 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -151,6 +153,19 @@ class Projects::PipelinesController < Projects::ApplicationController
@counts[:failed] = @project.all_pipelines.failed.count(:all) @counts[:failed] = @project.all_pipelines.failed.count(:all)
end end
def test_report
return unless Feature.enabled?(:junit_pipeline_view, project)
if pipeline_test_report == :error
render json: { status: :error_parsing_report }
return
end
render json: TestReportSerializer
.new(current_user: @current_user)
.represent(pipeline_test_report)
end
private private
def serialize_pipelines def serialize_pipelines
...@@ -217,6 +232,14 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -217,6 +232,14 @@ class Projects::PipelinesController < Projects::ApplicationController
view_context.limited_counter_with_delimiter(finder.execute) view_context.limited_counter_with_delimiter(finder.execute)
end end
def pipeline_test_report
strong_memoize(:pipeline_test_report) do
@pipeline.test_reports
rescue Gitlab::Ci::Parsers::ParserError
:error
end
end
end end
Projects::PipelinesController.prepend_if_ee('EE::Projects::PipelinesController') Projects::PipelinesController.prepend_if_ee('EE::Projects::PipelinesController')
# frozen_string_literal: true
class TestReportEntity < Grape::Entity
expose :total_time
expose :total_count
expose :success_count
expose :failed_count
expose :skipped_count
expose :error_count
expose :test_suites, using: TestSuiteEntity do |report|
report.test_suites.values
end
end
# frozen_string_literal: true
class TestReportSerializer < BaseSerializer
entity TestReportEntity
end
# frozen_string_literal: true
class TestSuiteEntity < Grape::Entity
expose :name
expose :total_time
expose :total_count
expose :success_count
expose :failed_count
expose :skipped_count
expose :error_count
expose :test_cases, using: TestCaseEntity do |test_suite|
test_suite.test_cases.values.flat_map(&:values)
end
end
...@@ -387,6 +387,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do ...@@ -387,6 +387,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
get :builds get :builds
get :failures get :failures
get :status get :status
get :test_report
Gitlab.ee do Gitlab.ee do
get :security get :security
......
...@@ -398,6 +398,76 @@ describe Projects::PipelinesController do ...@@ -398,6 +398,76 @@ describe Projects::PipelinesController do
end end
end end
describe 'GET test_report.json' do
subject(:get_test_report_json) do
post :test_report, params: {
namespace_id: project.namespace,
project_id: project,
id: pipeline.id
},
format: :json
end
context 'when feature is enabled' do
before do
stub_feature_flags(junit_pipeline_view: true)
end
context 'when pipeline does not have a test report' do
let(:pipeline) { create(:ci_pipeline, project: project) }
it 'renders an empty test report' do
get_test_report_json
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['total_count']).to eq(0)
end
end
context 'when pipeline has a test report' do
let(:pipeline) { create(:ci_pipeline, :with_test_reports, project: project) }
it 'renders the test report' do
get_test_report_json
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['total_count']).to eq(4)
end
end
context 'when pipeline has corrupt test reports' do
let(:pipeline) { create(:ci_pipeline, project: project) }
before do
job = create(:ci_build, pipeline: pipeline)
create(:ci_job_artifact, :junit_with_corrupted_data, job: job, project: project)
end
it 'renders the test reports' do
get_test_report_json
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['status']).to eq('error_parsing_report')
end
end
end
context 'when feature is disabled' do
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
before do
stub_feature_flags(junit_pipeline_view: false)
end
it 'renders empty response' do
get_test_report_json
expect(response).to have_gitlab_http_status(:no_content)
expect(response.body).to be_empty
end
end
end
describe 'GET latest' do describe 'GET latest' do
let(:branch_main) { project.repository.branches[0] } let(:branch_main) { project.repository.branches[0] }
let(:branch_secondary) { project.repository.branches[1] } let(:branch_secondary) { project.repository.branches[1] }
......
# frozen_string_literal: true
require 'spec_helper'
describe TestReportEntity do
let(:pipeline) { create(:ci_pipeline, :with_test_reports) }
let(:entity) { described_class.new(pipeline.test_reports) }
describe '#as_json' do
subject(:as_json) { entity.as_json }
it 'contains the total time' do
expect(as_json).to include(:total_time)
end
it 'contains the counts' do
expect(as_json).to include(:total_count, :success_count, :failed_count, :skipped_count, :error_count)
end
it 'contains the test suites' do
expect(as_json).to include(:test_suites)
expect(as_json[:test_suites].count).to eq(1)
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe TestSuiteEntity do
let(:pipeline) { create(:ci_pipeline, :with_test_reports) }
let(:entity) { described_class.new(pipeline.test_reports.test_suites.values.first) }
describe '#as_json' do
subject(:as_json) { entity.as_json }
it 'contains the suite name' do
expect(as_json).to include(:name)
end
it 'contains the total time' do
expect(as_json).to include(:total_time)
end
it 'contains the counts' do
expect(as_json).to include(:total_count, :success_count, :failed_count, :skipped_count, :error_count)
end
it 'contains the test cases' do
expect(as_json).to include(:test_cases)
expect(as_json[:test_cases].count).to eq(4)
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