Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-12-10 18:10:12 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-12-10 18:10:12 +0300
commit8f143a46faf2e7b594301512757edf372c294a0c (patch)
tree8bd5957ffa44d028905ab51a7252cce6783d2e25 /spec/services/ci/test_failure_history_service_spec.rb
parent3e06afc4cd1b75b3e957e8debf5e4f1963ba18e0 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/services/ci/test_failure_history_service_spec.rb')
-rw-r--r--spec/services/ci/test_failure_history_service_spec.rb192
1 files changed, 192 insertions, 0 deletions
diff --git a/spec/services/ci/test_failure_history_service_spec.rb b/spec/services/ci/test_failure_history_service_spec.rb
new file mode 100644
index 00000000000..e858c85490d
--- /dev/null
+++ b/spec/services/ci/test_failure_history_service_spec.rb
@@ -0,0 +1,192 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::TestFailureHistoryService, :aggregate_failures do
+ describe '#execute' do
+ let(:project) { create(:project) }
+ let(:pipeline) { create(:ci_empty_pipeline, status: :created, project: project) }
+
+ subject(:execute_service) { described_class.new(pipeline).execute }
+
+ context 'when pipeline has failed builds with test reports' do
+ before do
+ # The test report has 2 test case failures
+ create(:ci_build, :failed, :test_reports, pipeline: pipeline, project: project)
+ end
+
+ it 'creates test case failures records' do
+ execute_service
+
+ expect(Ci::TestCase.count).to eq(2)
+ expect(Ci::TestCaseFailure.count).to eq(2)
+ end
+
+ context 'when feature flag for test failure history is disabled' do
+ before do
+ stub_feature_flags(test_failure_history: false)
+ end
+
+ it 'does not persist data' do
+ execute_service
+
+ expect(Ci::TestCase.count).to eq(0)
+ expect(Ci::TestCaseFailure.count).to eq(0)
+ end
+ end
+
+ context 'when pipeline is not for the default branch' do
+ before do
+ pipeline.update_column(:ref, 'new-feature')
+ end
+
+ it 'does not persist data' do
+ execute_service
+
+ expect(Ci::TestCase.count).to eq(0)
+ expect(Ci::TestCaseFailure.count).to eq(0)
+ end
+ end
+
+ context 'when test failure data have already been persisted with the same exact attributes' do
+ before do
+ execute_service
+ end
+
+ it 'does not fail but does not persist new data' do
+ expect { described_class.new(pipeline).execute }.not_to raise_error
+
+ expect(Ci::TestCase.count).to eq(2)
+ expect(Ci::TestCaseFailure.count).to eq(2)
+ end
+ end
+
+ context 'when number of failed test cases exceed the limit' do
+ before do
+ stub_const("#{described_class.name}::MAX_TRACKABLE_FAILURES", 1)
+ end
+
+ it 'does not persist data' do
+ execute_service
+
+ expect(Ci::TestCase.count).to eq(0)
+ expect(Ci::TestCaseFailure.count).to eq(0)
+ end
+ end
+
+ context 'when number of failed test cases across multiple builds exceed the limit' do
+ before do
+ stub_const("#{described_class.name}::MAX_TRACKABLE_FAILURES", 2)
+
+ # This other test report has 1 unique test case failure which brings us to 3 total failures across all builds
+ # thus exceeding the limit of 2 for MAX_TRACKABLE_FAILURES
+ create(:ci_build, :failed, :test_reports_with_duplicate_failed_test_names, pipeline: pipeline, project: project)
+ end
+
+ it 'does not persist data' do
+ execute_service
+
+ expect(Ci::TestCase.count).to eq(0)
+ expect(Ci::TestCaseFailure.count).to eq(0)
+ end
+ end
+ end
+
+ context 'when test failure data have duplicates within the same payload (happens when the JUnit report has duplicate test case names but have different failures)' do
+ before do
+ # The test report has 2 test case failures but with the same test case keys
+ create(:ci_build, :failed, :test_reports_with_duplicate_failed_test_names, pipeline: pipeline, project: project)
+ end
+
+ it 'does not fail but does not persist duplicate data' do
+ expect { execute_service }.not_to raise_error
+
+ expect(Ci::TestCase.count).to eq(1)
+ expect(Ci::TestCaseFailure.count).to eq(1)
+ end
+ end
+
+ context 'when pipeline has no failed builds with test reports' do
+ before do
+ create(:ci_build, :test_reports, pipeline: pipeline, project: project)
+ create(:ci_build, :failed, pipeline: pipeline, project: project)
+ end
+
+ it 'does not persist data' do
+ execute_service
+
+ expect(Ci::TestCase.count).to eq(0)
+ expect(Ci::TestCaseFailure.count).to eq(0)
+ end
+ end
+ end
+
+ describe '#should_track_failures?' do
+ let(:project) { create(:project, :repository) }
+ let(:pipeline) { create(:ci_empty_pipeline, status: :created, project: project, ref: project.default_branch) }
+
+ subject { described_class.new(pipeline).should_track_failures? }
+
+ before do
+ create(:ci_build, :test_reports, :failed, pipeline: pipeline, project: project)
+ create(:ci_build, :test_reports, :failed, pipeline: pipeline, project: project)
+ end
+
+ context 'when feature flag is enabled and pipeline ref is the default branch' do
+ it { is_expected.to eq(true) }
+ end
+
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(test_failure_history: false)
+ end
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when pipeline is not equal to the project default branch' do
+ before do
+ pipeline.update_column(:ref, 'some-other-branch')
+ end
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when total number of builds with failed tests exceeds the max number of trackable failures' do
+ before do
+ stub_const("#{described_class.name}::MAX_TRACKABLE_FAILURES", 1)
+ end
+
+ it { is_expected.to eq(false) }
+ end
+ end
+
+ describe '#async' do
+ let(:pipeline) { double(id: 1) }
+ let(:service) { described_class.new(pipeline) }
+
+ context 'when service should track failures' do
+ before do
+ allow(service).to receive(:should_track_failures?).and_return(true)
+ end
+
+ it 'enqueues the worker when #perform_if_needed is called' do
+ expect(Ci::TestFailureHistoryWorker).to receive(:perform_async).with(pipeline.id)
+
+ service.async.perform_if_needed
+ end
+ end
+
+ context 'when service should not track failures' do
+ before do
+ allow(service).to receive(:should_track_failures?).and_return(false)
+ end
+
+ it 'does not enqueue the worker when #perform_if_needed is called' do
+ expect(Ci::TestFailureHistoryWorker).not_to receive(:perform_async)
+
+ service.async.perform_if_needed
+ end
+ end
+ end
+end