diff options
-rw-r--r-- | .rubocop.yml | 2 | ||||
-rw-r--r-- | lib/gitlab/ci/reports/test_case.rb | 23 | ||||
-rw-r--r-- | qa/qa/page/base.rb | 17 | ||||
-rw-r--r-- | qa/qa/page/main/login.rb | 2 | ||||
-rw-r--r-- | qa/qa/page/main/menu.rb | 2 | ||||
-rw-r--r-- | qa/qa/page/validatable.rb | 2 | ||||
-rw-r--r-- | qa/qa/runtime/env.rb | 4 | ||||
-rw-r--r-- | qa/spec/spec_helper.rb | 3 | ||||
-rw-r--r-- | spec/factories/ci/test_case.rb | 7 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/reports/test_case_spec.rb | 62 |
10 files changed, 60 insertions, 64 deletions
diff --git a/.rubocop.yml b/.rubocop.yml index 1418a72c88a..62f5af0a8dd 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -221,14 +221,12 @@ Gitlab/DuplicateSpecLocation: - ee/spec/services/merge_requests/create_service_spec.rb - ee/spec/services/merge_requests/refresh_service_spec.rb - ee/spec/services/merge_requests/update_service_spec.rb - - ee/spec/services/system_hooks_service_spec.rb - ee/spec/helpers/ee/auth_helper_spec.rb - ee/spec/models/ee/namespace_spec.rb - ee/spec/services/ee/issues/create_service_spec.rb - ee/spec/services/ee/merge_requests/create_service_spec.rb - ee/spec/services/ee/merge_requests/refresh_service_spec.rb - ee/spec/services/ee/merge_requests/update_service_spec.rb - - ee/spec/services/ee/system_hooks_service_spec.rb Cop/InjectEnterpriseEditionModule: Enabled: true diff --git a/lib/gitlab/ci/reports/test_case.rb b/lib/gitlab/ci/reports/test_case.rb index d95941059ff..75898745366 100644 --- a/lib/gitlab/ci/reports/test_case.rb +++ b/lib/gitlab/ci/reports/test_case.rb @@ -12,20 +12,19 @@ module Gitlab attr_reader :name, :classname, :execution_time, :status, :file, :system_output, :stack_trace, :key, :attachment, :job - # rubocop: disable Metrics/ParameterLists - def initialize(name:, classname:, execution_time:, status:, file: nil, system_output: nil, stack_trace: nil, attachment: nil, job: nil) - @name = name - @classname = classname - @file = file - @execution_time = execution_time.to_f - @status = status - @system_output = system_output - @stack_trace = stack_trace + def initialize(params) + @name = params.fetch(:name) + @classname = params.fetch(:classname) + @file = params.fetch(:file, nil) + @execution_time = params.fetch(:execution_time).to_f + @status = params.fetch(:status) + @system_output = params.fetch(:system_output, nil) + @stack_trace = params.fetch(:stack_trace, nil) + @attachment = params.fetch(:attachment, nil) + @job = params.fetch(:job, nil) + @key = sanitize_key_name("#{classname}_#{name}") - @attachment = attachment - @job = job end - # rubocop: enable Metrics/ParameterLists def has_attachment? attachment.present? diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb index 22b0021ea77..4ccf9e2f168 100644 --- a/qa/qa/page/base.rb +++ b/qa/qa/page/base.rb @@ -16,6 +16,10 @@ module QA def_delegators :evaluator, :view, :views + def initialize + @retry_later_backoff = QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME + end + def assert_no_element(name) assert_no_selector(element_selector_css(name)) end @@ -259,6 +263,19 @@ module QA visit find_element(name)['href'] end + def wait_if_retry_later + return if @retry_later_backoff > QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME * 5 + + if has_css?('body', text: 'Retry later', wait: 0) + QA::Runtime::Logger.warn("`Retry later` error occurred. Sleeping for #{@retry_later_backoff} seconds...") + sleep @retry_later_backoff + refresh + @retry_later_backoff += QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME + + wait_if_retry_later + end + end + def self.path raise NotImplementedError end diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb index 72884e97185..0638097a7b7 100644 --- a/qa/qa/page/main/login.rb +++ b/qa/qa/page/main/login.rb @@ -152,6 +152,8 @@ module QA private def sign_in_using_gitlab_credentials(user:, skip_page_validation: false) + wait_if_retry_later + switch_to_sign_in_tab if has_sign_in_tab? switch_to_standard_tab if has_standard_tab? diff --git a/qa/qa/page/main/menu.rb b/qa/qa/page/main/menu.rb index 8ad30632fa1..6af18cb1d2b 100644 --- a/qa/qa/page/main/menu.rb +++ b/qa/qa/page/main/menu.rb @@ -77,6 +77,8 @@ module QA def sign_out retry_until do + wait_if_retry_later + break true unless signed_in? within_user_menu do diff --git a/qa/qa/page/validatable.rb b/qa/qa/page/validatable.rb index 3c4d9ad68aa..f09a9aa9943 100644 --- a/qa/qa/page/validatable.rb +++ b/qa/qa/page/validatable.rb @@ -8,6 +8,8 @@ module QA def validate_elements_present! base_page = self.new + base_page.wait_if_retry_later + elements.each do |element| next unless element.required? diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb index 722648857ea..d8a3fe93bc0 100644 --- a/qa/qa/runtime/env.rb +++ b/qa/qa/runtime/env.rb @@ -43,6 +43,10 @@ module QA ENV['GITLAB_QA_ADMIN_ACCESS_TOKEN'] end + def ci_project_name + ENV['CI_PROJECT_NAME'] + end + def debug? enabled?(ENV['QA_DEBUG'], default: false) end diff --git a/qa/spec/spec_helper.rb b/qa/spec/spec_helper.rb index 1336bea16bc..0f818b9f89a 100644 --- a/qa/spec/spec_helper.rb +++ b/qa/spec/spec_helper.rb @@ -63,8 +63,9 @@ RSpec.configure do |config| config.display_try_failure_messages = true if ENV['CI'] && !QA::Runtime::Env.disable_rspec_retry? + non_quarantine_retries = QA::Runtime::Env.ci_project_name =~ /staging|canary|production/ ? 3 : 2 config.around do |example| - retry_times = example.metadata.key?(:quarantine) ? 1 : 2 + retry_times = example.metadata.key?(:quarantine) ? 1 : non_quarantine_retries example.run_with_retry retry: retry_times end end diff --git a/spec/factories/ci/test_case.rb b/spec/factories/ci/test_case.rb index dc0e7c762ab..bb1508c0d75 100644 --- a/spec/factories/ci/test_case.rb +++ b/spec/factories/ci/test_case.rb @@ -6,17 +6,18 @@ FactoryBot.define do classname { "trace" } file { "spec/trace_spec.rb" } execution_time { 1.23 } - status { "success" } + status { Gitlab::Ci::Reports::TestCase::STATUS_SUCCESS } system_output { nil } attachment { nil } association :job, factory: :ci_build trait :failed do - status { "failed" } + status { Gitlab::Ci::Reports::TestCase::STATUS_FAILED } + system_output { "Failure/Error: is_expected.to eq(300) expected: 300 got: -100" } end trait :with_attachment do - status { "failed" } + status { Gitlab::Ci::Reports::TestCase::STATUS_FAILED } attachment { "some/path.png" } end diff --git a/spec/lib/gitlab/ci/reports/test_case_spec.rb b/spec/lib/gitlab/ci/reports/test_case_spec.rb index 69fe05d573e..c0652288cca 100644 --- a/spec/lib/gitlab/ci/reports/test_case_spec.rb +++ b/spec/lib/gitlab/ci/reports/test_case_spec.rb @@ -4,21 +4,12 @@ require 'spec_helper' describe Gitlab::Ci::Reports::TestCase do describe '#initialize' do - let(:test_case) { described_class.new(**params)} + let(:test_case) { described_class.new(params)} context 'when both classname and name are given' do context 'when test case is passed' do - let(:params) do - { - name: 'test-1', - classname: 'trace', - file: 'spec/trace_spec.rb', - execution_time: 1.23, - status: described_class::STATUS_SUCCESS, - system_output: nil, - job: build(:ci_build) - } - end + let(:job) { build(:ci_build) } + let(:params) { attributes_for(:test_case).merge!(job: job) } it 'initializes an instance' do expect { test_case }.not_to raise_error @@ -34,16 +25,8 @@ describe Gitlab::Ci::Reports::TestCase do end context 'when test case is failed' do - let(:params) do - { - name: 'test-1', - classname: 'trace', - file: 'spec/trace_spec.rb', - execution_time: 1.23, - status: described_class::STATUS_FAILED, - system_output: "Failure/Error: is_expected.to eq(300) expected: 300 got: -100" - } - end + let(:job) { build(:ci_build) } + let(:params) { attributes_for(:test_case, :failed).merge!(job: job) } it 'initializes an instance' do expect { test_case }.not_to raise_error @@ -59,36 +42,23 @@ describe Gitlab::Ci::Reports::TestCase do end end - context 'when classname is missing' do - let(:params) do - { - name: 'test-1', - file: 'spec/trace_spec.rb', - execution_time: 1.23, - status: described_class::STATUS_SUCCESS, - system_output: nil - } - end + shared_examples 'param is missing' do |param| + let(:job) { build(:ci_build) } + let(:params) { attributes_for(:test_case).merge!(job: job) } it 'raises an error' do - expect { test_case }.to raise_error(ArgumentError) + params.delete(param) + + expect { test_case }.to raise_error(KeyError) end end - context 'when name is missing' do - let(:params) do - { - classname: 'trace', - file: 'spec/trace_spec.rb', - execution_time: 1.23, - status: described_class::STATUS_SUCCESS, - system_output: nil - } - end + context 'when classname is missing' do + it_behaves_like 'param is missing', :classname + end - it 'raises an error' do - expect { test_case }.to raise_error(ArgumentError) - end + context 'when name is missing' do + it_behaves_like 'param is missing', :name end context 'when attachment is present' do |