Commit 30d84b0e authored by Mark Lapierre's avatar Mark Lapierre Committed by Peter Leitzen

Add test report API route

This adds a route to get the JSON test report content as it's
available via the UI.

Includes request specs and a minor update to the description
of an existing related controller spec.

Adds documentation

Notes API access in CI docs
parent ccd02e1a
---
title: Add test report API route
merge_request: 24648
author:
type: added
......@@ -130,6 +130,62 @@ Example of response
]
```
### Get a pipeline's test report
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/202525) in GitLab 13.0.
CAUTION: **Caution:**
This API route is part of the [JUnit test report](../ci/junit_test_reports.md) feature. It is protected by a [feature flag](../development/feature_flags/index.md) that is **disabled** due to performance issues with very large data sets. See [the documentation for the feature](../ci/junit_test_reports.md#enabling-the-feature) for further details.
```plaintext
GET /projects/:id/pipelines/:pipeline_id/test_report
```
| Attribute | Type | Required | Description |
|------------|---------|----------|---------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `pipeline_id` | integer | yes | The ID of a pipeline |
Sample request:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/pipelines/46/test_report"
```
Sample response:
```json
{
"total_time": 5,
"total_count": 1,
"success_count": 1,
"failed_count": 0,
"skipped_count": 0,
"error_count": 0,
"test_suites": [
{
"name": "Secure",
"total_time": 5,
"total_count": 1,
"success_count": 1,
"failed_count": 0,
"skipped_count": 0,
"error_count": 0,
"test_cases": [
{
"status": "success",
"name": "Security Reports can create an auto-remediation MR",
"classname": "vulnerability_management_spec",
"execution_time": 5,
"system_output": null,
"stack_trace": null
}
]
}
]
}
```
## Create a new pipeline
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/7209) in GitLab 8.14
......
......@@ -237,6 +237,8 @@ You can view all the known test suites and click on each of these to see further
details, including the cases that makeup the suite. Cases are ordered by status,
with failed showing at the top, skipped next and successful cases last.
You can also retrieve the reports via the [GitLab API](../api/pipelines.md#get-a-pipelines-test-report).
### Enabling the feature
This feature comes with the `:junit_pipeline_view` feature flag disabled by default. This
......
......@@ -108,6 +108,21 @@ module API
present pipeline.variables, with: Entities::Variable
end
desc 'Gets the test report for a given pipeline' do
detail 'This feature was introduced in GitLab 13.0. Disabled by default behind feature flag `junit_pipeline_view`'
success TestReportEntity
end
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
get ':id/pipelines/:pipeline_id/test_report' do
not_found! unless Feature.enabled?(:junit_pipeline_view, user_project)
authorize! :read_build, pipeline
present pipeline.test_reports, with: TestReportEntity
end
desc 'Deletes a pipeline' do
detail 'This feature was introduced in GitLab 11.6'
http_codes [[204, 'Pipeline was deleted'], [403, 'Forbidden']]
......
......@@ -714,4 +714,73 @@ describe API::Pipelines do
end
end
end
describe 'GET /projects/:id/pipelines/:pipeline_id/test_report' do
context 'authorized user' do
subject { get api("/projects/#{project.id}/pipelines/#{pipeline.id}/test_report", user) }
let(:pipeline) { create(:ci_pipeline, project: project) }
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
it 'returns an empty test report' do
subject
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 'returns the test report' do
subject
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
before do
job = create(:ci_build, pipeline: pipeline)
create(:ci_job_artifact, :junit_with_corrupted_data, job: job, project: project)
end
it 'returns a suite_error' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['test_suites'].first['suite_error']).to eq('JUnit XML parsing failed: 1:1: FATAL: Document is empty')
end
end
end
context 'when feature is disabled' do
before do
stub_feature_flags(junit_pipeline_view: false)
end
it 'renders empty response' do
subject
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
context 'unauthorized user' do
it 'does not return project pipelines' do
get api("/projects/#{project.id}/pipelines/#{pipeline.id}/test_report", non_member)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq '404 Project Not Found'
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