summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzciński <ayufan@ayufan.eu>2018-07-17 18:00:59 +0200
committerKamil Trzciński <ayufan@ayufan.eu>2018-07-17 18:00:59 +0200
commite2670a3c642ba33e79202fc9adb044a78260c515 (patch)
tree9a5c82ab9cb3d4fb6063eb4dc9f8dbee92ce29e7
parent5ea46ce5cd6d0f74802216d1c63d274a48d3cd08 (diff)
downloadgitlab-ce-e2670a3c642ba33e79202fc9adb044a78260c515.tar.gz
Expose all data with API on Merge Request
-rw-r--r--app/controllers/projects/merge_requests_controller.rb15
-rw-r--r--app/models/ci/pipeline.rb8
-rw-r--r--app/models/merge_request.rb20
-rw-r--r--app/serializers/merge_request_widget_entity.rb6
-rw-r--r--app/serializers/test_case_entity.rb6
-rw-r--r--app/serializers/test_results_comparer_entity.rb3
-rw-r--r--app/serializers/test_results_comparer_serializer.rb3
-rw-r--r--app/serializers/test_suite_comparer_entity.rb6
-rw-r--r--config/routes/project.rb1
-rw-r--r--lib/gitlab/ci/reports/test_results_comparer.rb24
-rw-r--r--lib/gitlab/ci/reports/test_suite.rb6
-rw-r--r--lib/gitlab/ci/reports/test_suite_comparer.rb41
12 files changed, 120 insertions, 19 deletions
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 7d20e0494bb..46d9911546c 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -99,6 +99,14 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
}
end
+ def test_results
+ test_results = @merge_request.compared_test_results
+
+ render json: TestResultsComparerSerializer
+ .new(project: @project, current_user: @current_user)
+ .represent(test_results)
+ end
+
def edit
define_edit_vars
end
@@ -224,13 +232,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
render json: environments
end
- def test_results
- # we would likely use Grape Entities: so Serializer and Entity
- # so this is pseudo-code
- render merge_request.test_results, with: MergeRequests::TestResults
- end
-
-
def rebase
RebaseWorker.perform_async(@merge_request.id, current_user.id)
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 1e8e76c8a9d..0538f6f0ece 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -603,9 +603,13 @@ module Ci
@latest_builds_with_artifacts ||= builds.latest.with_artifacts_archive.to_a
end
+ def has_test_results?
+ builds.with_test_reports.any?
+ end
+
def test_results
- Gitlab::Ci::Build::Artifacts::TestResults.new.tap do |test_results|
- builds.with_test_reports.each do |build|
+ Gitlab::Ci::Reports::TestResults.new.tap do |test_results|
+ builds.with_test_reports.includes(:job_artifacts_junit).each do |build|
build.collect_test_results(test_results)
end
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 717bfb4d578..5a3ad3f60ce 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -1009,18 +1009,14 @@ class MergeRequest < ActiveRecord::Base
.order(id: :desc)
end
- def test_results
- TestResultsComparer.new.tap do |test_results_comparer|
- test_results_comparer.compare(base_test_results, head_test_results)
- end
+ def has_test_results?
+ actual_head_pipeline&.has_test_results?
end
- def base_test_results
- base_pipeline&.test_results
- end
+ def compared_test_results
+ return unless actual_head_pipeline
- def head_test_results
- head_pipeline&.test_results
+ Gitlab::Ci::Reports::TestResultsComparer.new(base_pipeline&.test_results, actual_head_pipeline&.test_results)
end
def all_commits
@@ -1135,6 +1131,12 @@ class MergeRequest < ActiveRecord::Base
true
end
+ def base_pipeline
+ @base_pipeline ||= project.pipelines
+ .order(id: :desc)
+ .find_by(sha: diff_base_sha)
+ end
+
def discussions_rendered_on_frontend?
true
end
diff --git a/app/serializers/merge_request_widget_entity.rb b/app/serializers/merge_request_widget_entity.rb
index a78bd77cf7c..fd9f9dcc9af 100644
--- a/app/serializers/merge_request_widget_entity.rb
+++ b/app/serializers/merge_request_widget_entity.rb
@@ -225,6 +225,12 @@ class MergeRequestWidgetEntity < IssuableEntity
end
end
+ expose :test_results_path do |merge_request|
+ if merge_request.has_test_results?
+ test_results_project_merge_request_path(merge_request.project, merge_request, format: :json)
+ end
+ end
+
private
delegate :current_user, to: :request
diff --git a/app/serializers/test_case_entity.rb b/app/serializers/test_case_entity.rb
new file mode 100644
index 00000000000..8213b6d4179
--- /dev/null
+++ b/app/serializers/test_case_entity.rb
@@ -0,0 +1,6 @@
+class TestCaseEntity < Grape::Entity
+ expose :name
+ expose :time, as: :execution_time
+ expose :failure_reason, as: :system_output
+ # TODO: stack_trace
+end
diff --git a/app/serializers/test_results_comparer_entity.rb b/app/serializers/test_results_comparer_entity.rb
new file mode 100644
index 00000000000..2e17ecb7ee2
--- /dev/null
+++ b/app/serializers/test_results_comparer_entity.rb
@@ -0,0 +1,3 @@
+class TestResultsComparerEntity < Grape::Entity
+ expose :suites, using: TestSuiteComparerEntity
+end
diff --git a/app/serializers/test_results_comparer_serializer.rb b/app/serializers/test_results_comparer_serializer.rb
new file mode 100644
index 00000000000..53983d63b0d
--- /dev/null
+++ b/app/serializers/test_results_comparer_serializer.rb
@@ -0,0 +1,3 @@
+class TestResultsComparerSerializer < BaseSerializer
+ entity TestResultsComparerEntity
+end
diff --git a/app/serializers/test_suite_comparer_entity.rb b/app/serializers/test_suite_comparer_entity.rb
new file mode 100644
index 00000000000..af4ef90786d
--- /dev/null
+++ b/app/serializers/test_suite_comparer_entity.rb
@@ -0,0 +1,6 @@
+class TestSuiteComparerEntity < Grape::Entity
+ expose :name
+ expose :new_failures, using: TestCaseEntity
+ expose :resolved_failures, using: TestCaseEntity
+ expose :existing_failures, using: TestCaseEntity
+end
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 5057e937941..be0c1feca62 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -109,6 +109,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
post :assign_related_issues
get :discussions, format: :json
post :rebase
+ get :test_results
scope constraints: { format: nil }, action: :show do
get :commits, defaults: { tab: 'commits' }
diff --git a/lib/gitlab/ci/reports/test_results_comparer.rb b/lib/gitlab/ci/reports/test_results_comparer.rb
new file mode 100644
index 00000000000..a60917b30f7
--- /dev/null
+++ b/lib/gitlab/ci/reports/test_results_comparer.rb
@@ -0,0 +1,24 @@
+module Gitlab
+ module Ci
+ module Reports
+ class TestResultsComparer
+ include Gitlab::Utils::StrongMemoize
+
+ attr_reader :base_results, :head_results
+
+ def initialize(base_results, head_results)
+ @base_results = base_results || TestResults.new
+ @head_results = head_results
+ end
+
+ def suites
+ strong_memoize(:suites) do
+ head_results.suites.map do |name, test_suite|
+ TestSuiteComparer.new(name, base_results.suites[name], test_suite)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/reports/test_suite.rb b/lib/gitlab/ci/reports/test_suite.rb
index d2ac4ebb361..e51f526a489 100644
--- a/lib/gitlab/ci/reports/test_suite.rb
+++ b/lib/gitlab/ci/reports/test_suite.rb
@@ -6,13 +6,17 @@ module Gitlab
attr_reader :test_statuses
attr_reader :total_time
- def initialize(name)
+ def initialize(name = nil)
@name = name
@test_statuses = {}
@total_time = 0.0
end
TestCase::STATUSES.each do |result_type|
+ define_method("#{result_type}") do
+ test_statuses[result_type.to_sym] || {}
+ end
+
define_method("#{result_type}_count") do
test_statuses[result_type.to_sym]&.length.to_i
end
diff --git a/lib/gitlab/ci/reports/test_suite_comparer.rb b/lib/gitlab/ci/reports/test_suite_comparer.rb
new file mode 100644
index 00000000000..fc25b7a57f4
--- /dev/null
+++ b/lib/gitlab/ci/reports/test_suite_comparer.rb
@@ -0,0 +1,41 @@
+module Gitlab
+ module Ci
+ module Reports
+ class TestSuiteComparer
+ include Gitlab::Utils::StrongMemoize
+
+ attr_reader :name, :base_suite, :head_suite
+
+ def initialize(name, base_suite, head_suite)
+ @name = name
+ @base_suite = base_suite || TestSuite.new
+ @head_suite = head_suite
+ end
+
+ def new_failures
+ strong_memoize(:new_failures) do
+ head_suite.failed.reject do |key, _|
+ base_suite.failed.include?(key)
+ end.values
+ end
+ end
+
+ def existing_failures
+ strong_memoize(:existing_failures) do
+ head_suite.failed.select do |key, _|
+ base_suite.failed.include?(key)
+ end.values
+ end
+ end
+
+ def resolved_failures
+ strong_memoize(:resolved_failures) do
+ head_suite.success.select do |key, _|
+ base_suite.failed.include?(key)
+ end.values
+ end
+ end
+ end
+ end
+ end
+end