diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-18 23:02:30 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-18 23:02:30 +0300 |
commit | 41fe97390ceddf945f3d967b8fdb3de4c66b7dea (patch) | |
tree | 9c8d89a8624828992f06d892cd2f43818ff5dcc8 /qa/spec | |
parent | 0804d2dc31052fb45a1efecedc8e06ce9bc32862 (diff) |
Add latest changes from gitlab-org/gitlab@14-9-stable-eev14.9.0-rc42
Diffstat (limited to 'qa/spec')
-rw-r--r-- | qa/spec/page/logging_spec.rb | 19 | ||||
-rw-r--r-- | qa/spec/resource/api_fabricator_spec.rb | 47 | ||||
-rw-r--r-- | qa/spec/resource/reusable_collection_spec.rb | 22 | ||||
-rw-r--r-- | qa/spec/runtime/env_spec.rb | 32 | ||||
-rw-r--r-- | qa/spec/runtime/logger_spec.rb | 30 | ||||
-rw-r--r-- | qa/spec/spec_helper.rb | 13 | ||||
-rw-r--r-- | qa/spec/specs/allure_report_spec.rb | 5 | ||||
-rw-r--r-- | qa/spec/support/formatters/allure_metadata_formatter_spec.rb | 3 | ||||
-rw-r--r-- | qa/spec/support/formatters/test_stats_formatter_spec.rb | 20 | ||||
-rw-r--r-- | qa/spec/support/loglinking_spec.rb | 185 | ||||
-rw-r--r-- | qa/spec/support/page_error_checker_spec.rb | 66 | ||||
-rw-r--r-- | qa/spec/support/repeater_spec.rb | 6 | ||||
-rw-r--r-- | qa/spec/tools/reliable_report_spec.rb | 2 | ||||
-rw-r--r-- | qa/spec/tools/test_resources_data_processor_spec.rb | 28 |
14 files changed, 375 insertions, 103 deletions
diff --git a/qa/spec/page/logging_spec.rb b/qa/spec/page/logging_spec.rb index 98326ecd343..054332eea29 100644 --- a/qa/spec/page/logging_spec.rb +++ b/qa/spec/page/logging_spec.rb @@ -4,11 +4,10 @@ require 'capybara/dsl' RSpec.describe QA::Support::Page::Logging do let(:page) { double.as_null_object } + let(:logger) { Gitlab::QA::TestLogger.logger(level: ::Logger::DEBUG, source: 'QA Tests') } before do - logger = ::Logger.new $stdout - logger.level = ::Logger::DEBUG - QA::Runtime::Logger.logger = logger + allow(QA::Runtime::Logger).to receive(:logger).and_return(logger) allow(Capybara).to receive(:current_session).and_return(page) allow(page).to receive(:find).and_return(page) @@ -59,7 +58,7 @@ RSpec.describe QA::Support::Page::Logging do it 'logs find_element with class' do expect { subject.find_element(:element, class: 'active') } - .to output(/finding :element with args {:class=>\"active\"}/).to_stdout_from_any_process + .to output(/finding :element with args {:class=>"active"}/).to_stdout_from_any_process end it 'logs click_element' do @@ -74,40 +73,40 @@ RSpec.describe QA::Support::Page::Logging do it 'logs has_element?' do expect { subject.has_element?(:element) } - .to output(/has_element\? :element \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).to_stdout_from_any_process + .to output(/has_element\? :element \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/o).to_stdout_from_any_process end it 'logs has_element? with text' do expect { subject.has_element?(:element, text: "some text") } - .to output(/has_element\? :element with text \"some text\" \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).to_stdout_from_any_process + .to output(/has_element\? :element with text "some text" \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/o).to_stdout_from_any_process end it 'logs has_no_element?' do allow(page).to receive(:has_no_css?).and_return(true) expect { subject.has_no_element?(:element) } - .to output(/has_no_element\? :element \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).to_stdout_from_any_process + .to output(/has_no_element\? :element \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/o).to_stdout_from_any_process end it 'logs has_no_element? with text' do allow(page).to receive(:has_no_css?).and_return(true) expect { subject.has_no_element?(:element, text: "more text") } - .to output(/has_no_element\? :element with text \"more text\" \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).to_stdout_from_any_process + .to output(/has_no_element\? :element with text "more text" \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/o).to_stdout_from_any_process end it 'logs has_text?' do allow(page).to receive(:has_text?).and_return(true) expect { subject.has_text? 'foo' } - .to output(/has_text\?\('foo', wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned true/).to_stdout_from_any_process + .to output(/has_text\?\('foo', wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned true/o).to_stdout_from_any_process end it 'logs has_no_text?' do allow(page).to receive(:has_no_text?).with('foo', any_args).and_return(true) expect { subject.has_no_text? 'foo' } - .to output(/has_no_text\?\('foo', wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned true/).to_stdout_from_any_process + .to output(/has_no_text\?\('foo', wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned true/o).to_stdout_from_any_process end it 'logs finished_loading?' do diff --git a/qa/spec/resource/api_fabricator_spec.rb b/qa/spec/resource/api_fabricator_spec.rb index 69a95c92332..ec9907916eb 100644 --- a/qa/spec/resource/api_fabricator_spec.rb +++ b/qa/spec/resource/api_fabricator_spec.rb @@ -108,15 +108,58 @@ RSpec.describe QA::Resource::ApiFabricator do context 'when the POST fails' do let(:post_response) { { error: "Name already taken." } } - let(:raw_post) { double('Raw POST response', code: 400, body: post_response.to_json) } + let(:raw_post) { double('Raw POST response', code: 400, body: post_response.to_json, headers: {}) } it 'raises a ResourceFabricationFailedError exception' do expect(api_request).to receive(:new).with(api_client_instance, subject.api_post_path).and_return(double(url: resource_web_url)) expect(subject).to receive(:post).with(resource_web_url, subject.api_post_body).and_return(raw_post) + allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(nil) - expect { subject.fabricate_via_api! }.to raise_error(described_class::ResourceFabricationFailedError, "Fabrication of FooBarResource using the API failed (400) with `#{raw_post}`.") + expect { subject.fabricate_via_api! }.to raise_error do |error| + expect(error.class).to eql(described_class::ResourceFabricationFailedError) + expect(error.to_s).to eql(<<~ERROR.chomp) + Fabrication of FooBarResource using the API failed (400) with `#{raw_post}`.\n + ERROR + end expect(subject.api_resource).to be_nil end + + it 'logs a correlation id' do + response = double('Raw POST response', code: 400, body: post_response.to_json, headers: { x_request_id: 'foobar' }) + allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(nil) + + expect(api_request).to receive(:new).with(api_client_instance, subject.api_post_path).and_return(double(url: resource_web_url)) + expect(subject).to receive(:post).with(resource_web_url, subject.api_post_body).and_return(response) + + expect { subject.fabricate_via_api! }.to raise_error do |error| + expect(error.class).to eql(described_class::ResourceFabricationFailedError) + expect(error.to_s).to eql(<<~ERROR.chomp) + Fabrication of FooBarResource using the API failed (400) with `#{raw_post}`. + Correlation Id: foobar + ERROR + end + end + + it 'logs a sentry url from staging' do + response = double('Raw POST response', code: 400, body: post_response.to_json, headers: { x_request_id: 'foobar' }) + cookies = [{ name: 'Foo', value: 'Bar' }, { name: 'gitlab_canary', value: 'true' }] + + allow(Capybara.current_session).to receive_message_chain(:driver, :browser, :manage, :all_cookies).and_return(cookies) + allow(QA::Runtime::Scenario).to receive(:attributes).and_return({ gitlab_address: 'https://staging.gitlab.com' }) + + expect(api_request).to receive(:new).with(api_client_instance, subject.api_post_path).and_return(double(url: resource_web_url)) + expect(subject).to receive(:post).with(resource_web_url, subject.api_post_body).and_return(response) + + expect { subject.fabricate_via_api! }.to raise_error do |error| + expect(error.class).to eql(described_class::ResourceFabricationFailedError) + expect(error.to_s).to eql(<<~ERROR.chomp) + Fabrication of FooBarResource using the API failed (400) with `#{raw_post}`. + Correlation Id: foobar + Sentry Url: https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg-cny&query=correlation_id%3A%22foobar%22 + Kibana Url: https://nonprod-log.gitlab.net/app/discover#/?_a=(query:(language:kuery,query:'json.correlation_id%20:%20foobar')) + ERROR + end + end end end diff --git a/qa/spec/resource/reusable_collection_spec.rb b/qa/spec/resource/reusable_collection_spec.rb index 9116462b396..cb2df6931d0 100644 --- a/qa/spec/resource/reusable_collection_spec.rb +++ b/qa/spec/resource/reusable_collection_spec.rb @@ -20,6 +20,10 @@ RSpec.describe QA::Resource::ReusableCollection do end def exists?() end + + def reload! + Struct.new(:api_resource).new({ marked_for_deletion_on: false }) + end end end @@ -88,8 +92,22 @@ RSpec.describe QA::Resource::ReusableCollection do it 'removes each instance of each resource class' do described_class.remove_all_via_api! - expect(a_resource_instance.removed).to be true - expect(another_resource_instance.removed).to be true + expect(a_resource_instance.removed).to be_truthy + expect(another_resource_instance.removed).to be_truthy + end + + context 'when a resource is marked for deletion' do + before do + marked_for_deletion = Struct.new(:api_resource).new({ marked_for_deletion_on: true }) + + allow(a_resource_instance).to receive(:reload!).and_return(marked_for_deletion) + allow(another_resource_instance).to receive(:reload!).and_return(marked_for_deletion) + end + + it 'does not remove the resource' do + expect(a_resource_instance.removed).to be_falsey + expect(another_resource_instance.removed).to be_falsy + end end end diff --git a/qa/spec/runtime/env_spec.rb b/qa/spec/runtime/env_spec.rb index 0f752ad96b7..22603497019 100644 --- a/qa/spec/runtime/env_spec.rb +++ b/qa/spec/runtime/env_spec.rb @@ -360,36 +360,4 @@ RSpec.describe QA::Runtime::Env do end end end - - describe '.test_resources_created_filepath' do - context 'when not in CI' do - before do - allow(described_class).to receive(:running_in_ci?).and_return(false) - end - - it 'returns default path if QA_TEST_RESOURCES_CREATED_FILEPATH is not defined' do - stub_env('QA_TEST_RESOURCES_CREATED_FILEPATH', nil) - - expect(described_class.test_resources_created_filepath).to include('tmp/test-resources.json') - end - - it 'returns path if QA_TEST_RESOURCES_CREATED_FILEPATH is defined' do - stub_env('QA_TEST_RESOURCES_CREATED_FILEPATH', 'path/to_file') - - expect(described_class.test_resources_created_filepath).to eq('path/to_file') - end - end - - context 'when in CI' do - before do - allow(described_class).to receive(:running_in_ci?).and_return(true) - allow(SecureRandom).to receive(:hex).with(3).and_return('abc123') - stub_env('QA_TEST_RESOURCES_CREATED_FILEPATH', nil) - end - - it 'returns path with random hex in file name' do - expect(described_class.test_resources_created_filepath).to include('tmp/test-resources-abc123.json') - end - end - end end diff --git a/qa/spec/runtime/logger_spec.rb b/qa/spec/runtime/logger_spec.rb index a888bf1452b..f0fcfa0564e 100644 --- a/qa/spec/runtime/logger_spec.rb +++ b/qa/spec/runtime/logger_spec.rb @@ -1,33 +1,7 @@ # frozen_string_literal: true RSpec.describe QA::Runtime::Logger do - before do - logger = Logger.new $stdout - logger.level = ::Logger::DEBUG - described_class.logger = logger - end - - it 'logs debug' do - expect { described_class.debug('test') }.to output(/DEBUG -- : test/).to_stdout_from_any_process - end - - it 'logs info' do - expect { described_class.info('test') }.to output(/INFO -- : test/).to_stdout_from_any_process - end - - it 'logs warn' do - expect { described_class.warn('test') }.to output(/WARN -- : test/).to_stdout_from_any_process - end - - it 'logs error' do - expect { described_class.error('test') }.to output(/ERROR -- : test/).to_stdout_from_any_process - end - - it 'logs fatal' do - expect { described_class.fatal('test') }.to output(/FATAL -- : test/).to_stdout_from_any_process - end - - it 'logs unknown' do - expect { described_class.unknown('test') }.to output(/ANY -- : test/).to_stdout_from_any_process + it 'returns logger instance' do + expect(described_class.logger).to be_an_instance_of(::Logger) end end diff --git a/qa/spec/spec_helper.rb b/qa/spec/spec_helper.rb index 2a6acd6d014..655b0088feb 100644 --- a/qa/spec/spec_helper.rb +++ b/qa/spec/spec_helper.rb @@ -2,12 +2,6 @@ require_relative '../qa' -require 'securerandom' -require 'pathname' -require 'active_support/core_ext/hash' -require 'active_support/core_ext/object/blank' -require 'rainbow/refinement' - require_relative 'qa_deprecation_toolkit_env' QaDeprecationToolkitEnv.configure! @@ -36,7 +30,7 @@ RSpec.configure do |config| end config.prepend_before do |example| - QA::Runtime::Logger.debug("\nStarting test: #{example.full_description}\n") + QA::Runtime::Logger.info("Starting test: #{Rainbow(example.full_description).bright}") QA::Runtime::Example.current = example # Reset fabrication counters tracked in resource base @@ -75,14 +69,15 @@ RSpec.configure do |config| config.after(:suite) do |suite| # Write all test created resources to JSON file - QA::Tools::TestResourceDataProcessor.write_to_file + QA::Tools::TestResourceDataProcessor.write_to_file(suite.reporter.failed_examples.any?) # If requested, confirm that resources were used appropriately (e.g., not left with changes that interfere with # further reuse) QA::Resource::ReusableCollection.validate_resource_reuse if QA::Runtime::Env.validate_resource_reuse? # If any tests failed, leave the resources behind to help troubleshoot, otherwise remove them. - QA::Resource::ReusableCollection.remove_all_via_api! unless suite.reporter.failed_examples.present? + # Do not remove the shared resource on live environments + QA::Resource::ReusableCollection.remove_all_via_api! if !suite.reporter.failed_examples.present? && !QA::Runtime::Env.running_on_dot_com? end config.append_after(:suite) do diff --git a/qa/spec/specs/allure_report_spec.rb b/qa/spec/specs/allure_report_spec.rb index 06b09106140..86ceaf51cbb 100644 --- a/qa/spec/specs/allure_report_spec.rb +++ b/qa/spec/specs/allure_report_spec.rb @@ -76,9 +76,10 @@ describe QA::Runtime::AllureReport do end it 'adds rspec and metadata formatter' do + expect(rspec_config).to have_received(:add_formatter).with( + QA::Support::Formatters::AllureMetadataFormatter + ).ordered expect(rspec_config).to have_received(:add_formatter).with(AllureRspecFormatter).ordered - expect(rspec_config).to have_received(:add_formatter) - .with(QA::Support::Formatters::AllureMetadataFormatter).ordered end it 'configures attachments saving' do diff --git a/qa/spec/support/formatters/allure_metadata_formatter_spec.rb b/qa/spec/support/formatters/allure_metadata_formatter_spec.rb index 631d2eda54f..d84e190fd56 100644 --- a/qa/spec/support/formatters/allure_metadata_formatter_spec.rb +++ b/qa/spec/support/formatters/allure_metadata_formatter_spec.rb @@ -14,6 +14,7 @@ describe QA::Support::Formatters::AllureMetadataFormatter do add_link: nil, attempts: 0, file_path: 'file/path/spec.rb', + execution_result: instance_double("RSpec::Core::Example::ExecutionResult", status: :passed), metadata: { testcase: 'testcase', quarantine: { issue: 'issue' } @@ -31,7 +32,7 @@ describe QA::Support::Formatters::AllureMetadataFormatter do end it "adds additional data to report" do - formatter.example_started(rspec_example_notification) + formatter.example_finished(rspec_example_notification) aggregate_failures do expect(rspec_example).to have_received(:issue).with('Quarantine issue', 'issue') diff --git a/qa/spec/support/formatters/test_stats_formatter_spec.rb b/qa/spec/support/formatters/test_stats_formatter_spec.rb index 84fc3b83185..518c7407ba6 100644 --- a/qa/spec/support/formatters/test_stats_formatter_spec.rb +++ b/qa/spec/support/formatters/test_stats_formatter_spec.rb @@ -60,7 +60,8 @@ describe QA::Support::Formatters::TestStatsFormatter do retry_attempts: 0, job_url: ci_job_url, pipeline_url: ci_pipeline_url, - pipeline_id: ci_pipeline_id + pipeline_id: ci_pipeline_id, + merge_request_iid: nil } } end @@ -157,6 +158,23 @@ describe QA::Support::Formatters::TestStatsFormatter do end end + context 'with context quarantined spec' do + let(:quarantined) { 'false' } + + it 'exports data to influxdb with correct qurantine tag' do + run_spec do + it( + 'spec', + quarantine: { only: { job: 'praefect' } }, + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234' + ) {} + end + + expect(influx_write_api).to have_received(:write).once + expect(influx_write_api).to have_received(:write).with(data: [data]) + end + end + context 'with staging full run' do let(:run_type) { 'staging-full' } diff --git a/qa/spec/support/loglinking_spec.rb b/qa/spec/support/loglinking_spec.rb new file mode 100644 index 00000000000..cba8a139767 --- /dev/null +++ b/qa/spec/support/loglinking_spec.rb @@ -0,0 +1,185 @@ +# frozen_string_literal: true + +RSpec.describe QA::Support::Loglinking do + describe '.failure_metadata' do + context 'return nil string' do + it 'if correlation_id is empty' do + expect(QA::Support::Loglinking.failure_metadata('')).to eq(nil) + end + it 'if correlation_id is nil' do + expect(QA::Support::Loglinking.failure_metadata(nil)).to eq(nil) + end + end + + context 'return error string' do + it 'with sentry URL' do + allow(QA::Support::Loglinking).to receive(:sentry_url).and_return('https://sentry.address/?environment=bar') + allow(QA::Support::Loglinking).to receive(:kibana_url).and_return(nil) + + expect(QA::Support::Loglinking.failure_metadata('foo123')).to eql(<<~ERROR.chomp) + Correlation Id: foo123 + Sentry Url: https://sentry.address/?environment=bar&query=correlation_id%3A%22foo123%22 + ERROR + end + + it 'with kibana URL' do + allow(QA::Support::Loglinking).to receive(:sentry_url).and_return(nil) + allow(QA::Support::Loglinking).to receive(:kibana_url).and_return('https://kibana.address/') + + expect(QA::Support::Loglinking.failure_metadata('foo123')).to eql(<<~ERROR.chomp) + Correlation Id: foo123 + Kibana Url: https://kibana.address/app/discover#/?_a=(query:(language:kuery,query:'json.correlation_id%20:%20foo123')) + ERROR + end + end + end + + describe '.sentry_url' do + let(:url_hash) do + { + :staging => 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg', + :staging_canary => 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg-cny', + :staging_ref => 'https://sentry.gitlab.net/gitlab/staging-ref/?environment=gstg-ref', + :pre => 'https://sentry.gitlab.net/gitlab/pregitlabcom/?environment=pre', + :canary => 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd', + :production => 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd-cny', + :foo => nil, + nil => nil + } + end + + it 'returns sentry URL if environment found' do + url_hash.each do |environment, url| + allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(environment) + + expect(QA::Support::Loglinking.sentry_url).to eq(url) + end + end + end + + describe '.kibana_url' do + let(:url_hash) do + { + :staging => 'https://nonprod-log.gitlab.net/', + :staging_canary => 'https://nonprod-log.gitlab.net/', + :staging_ref => nil, + :pre => nil, + :canary => 'https://log.gprd.gitlab.net/', + :production => 'https://log.gprd.gitlab.net/', + :foo => nil, + nil => nil + } + end + + it 'returns kibana URL if environment found' do + url_hash.each do |environment, url| + allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(environment) + + expect(QA::Support::Loglinking.kibana_url).to eq(url) + end + end + end + + describe '.logging_environment' do + let(:staging_address) { 'https://staging.gitlab.com' } + let(:staging_ref_address) { 'https://staging-ref.gitlab.com' } + let(:production_address) { 'https://www.gitlab.com' } + let(:pre_prod_address) { 'https://pre.gitlab.com' } + let(:logging_env_array) do + [ + { + address: staging_address, + canary: false, + expected_env: :staging + }, + { + address: staging_address, + canary: true, + expected_env: :staging_canary + }, + { + address: staging_ref_address, + canary: true, + expected_env: :staging_ref + }, + { + address: production_address, + canary: false, + expected_env: :production + }, + { + address: production_address, + canary: true, + expected_env: :canary + }, + { + address: pre_prod_address, + canary: true, + expected_env: :pre + }, + { + address: 'https://foo.com', + canary: true, + expected_env: nil + } + ] + end + + it 'returns logging environment if environment found' do + logging_env_array.each do |logging_env_hash| + allow(QA::Runtime::Scenario).to receive(:attributes).and_return({ gitlab_address: logging_env_hash[:address] }) + allow(QA::Support::Loglinking).to receive(:canary?).and_return(logging_env_hash[:canary]) + + expect(QA::Support::Loglinking.logging_environment).to eq(logging_env_hash[:expected_env]) + end + end + end + + describe '.logging_environment?' do + context 'returns boolean' do + it 'returns true if logging_environment is not nil' do + allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(:staging) + + expect(QA::Support::Loglinking.logging_environment?).to eq(true) + end + + it 'returns false if logging_environment is nil' do + allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(nil) + + expect(QA::Support::Loglinking.logging_environment?).to eq(false) + end + end + end + + describe '.cookies' do + let(:cookies) { [{ name: 'Foo', value: 'Bar' }, { name: 'gitlab_canary', value: 'true' }] } + + it 'returns browser cookies' do + allow(Capybara.current_session).to receive_message_chain(:driver, :browser, :manage, :all_cookies).and_return(cookies) + + expect(QA::Support::Loglinking.cookies).to eq({ "Foo" => { name: "Foo", value: "Bar" }, "gitlab_canary" => { name: "gitlab_canary", value: "true" } }) + end + end + + describe '.canary?' do + context 'gitlab_canary cookie is present' do + it 'and true returns true' do + allow(QA::Support::Loglinking).to receive(:cookies).and_return({ 'gitlab_canary' => { name: 'gitlab_canary', value: 'true' } }) + + expect(QA::Support::Loglinking.canary?).to eq(true) + end + it 'and not true returns false' do + allow(QA::Support::Loglinking).to receive(:cookies).and_return({ 'gitlab_canary' => { name: 'gitlab_canary', value: 'false' } }) + + expect(QA::Support::Loglinking.canary?).to eq(false) + end + end + context 'gitlab_canary cookie is not present' do + it 'returns false' do + allow(QA::Support::Loglinking).to receive(:cookies).and_return({ 'foo' => { name: 'foo', path: '/pathname' } }) + + expect(QA::Support::Loglinking.canary?).to eq(false) + end + end + end +end diff --git a/qa/spec/support/page_error_checker_spec.rb b/qa/spec/support/page_error_checker_spec.rb index 764b6110e08..b9b085fa7b9 100644 --- a/qa/spec/support/page_error_checker_spec.rb +++ b/qa/spec/support/page_error_checker_spec.rb @@ -8,16 +8,28 @@ RSpec.describe QA::Support::PageErrorChecker do describe '.report!' do context 'reports errors' do let(:expected_chrome_error) do + "Error Code 500\n\n"\ "chrome errors\n\n"\ - "Path: #{test_path}" + "Path: #{test_path}\n\n"\ + "Logging: foo123" end let(:expected_basic_error) do + "Error Code 500\n\n"\ + "foo status\n\n"\ + "Path: #{test_path}\n\n"\ + "Logging: foo123" + end + + let(:expected_basic_404) do + "Error Code 404\n\n"\ "foo status\n\n"\ "Path: #{test_path}" end it 'reports error message on chrome browser' do + allow(QA::Support::PageErrorChecker).to receive(:parse_five_c_page_request_id).and_return('foo123') + allow(QA::Support::Loglinking).to receive(:failure_metadata).with('foo123').and_return('Logging: foo123') allow(QA::Support::PageErrorChecker).to receive(:return_chrome_errors).and_return('chrome errors') allow(page).to receive(:current_path).and_return(test_path) allow(QA::Runtime::Env).to receive(:browser).and_return(:chrome) @@ -26,12 +38,64 @@ RSpec.describe QA::Support::PageErrorChecker do end it 'reports basic message on non-chrome browser' do + allow(QA::Support::PageErrorChecker).to receive(:parse_five_c_page_request_id).and_return('foo123') + allow(QA::Support::Loglinking).to receive(:failure_metadata).with('foo123').and_return('Logging: foo123') allow(QA::Support::PageErrorChecker).to receive(:status_code_report).and_return('foo status') allow(page).to receive(:current_path).and_return(test_path) allow(QA::Runtime::Env).to receive(:browser).and_return(:firefox) expect { QA::Support::PageErrorChecker.report!(page, 500) }.to raise_error(RuntimeError, expected_basic_error) end + + it 'does not report failure metadata on non 500 error' do + allow(QA::Support::PageErrorChecker).to receive(:parse_five_c_page_request_id).and_return('foo123') + + expect(QA::Support::Loglinking).not_to receive(:failure_metadata) + + allow(QA::Support::PageErrorChecker).to receive(:status_code_report).and_return('foo status') + allow(page).to receive(:current_path).and_return(test_path) + allow(QA::Runtime::Env).to receive(:browser).and_return(:firefox) + + expect { QA::Support::PageErrorChecker.report!(page, 404) }.to raise_error(RuntimeError, expected_basic_404) + end + end + end + + describe '.parse_five_c_page_request_id' do + context 'parse correlation ID' do + require 'nokogiri' + before do + nokogiri_parse = Class.new do + def self.parse(str) + Nokogiri::HTML.parse(str) + end + end + stub_const('NokogiriParse', nokogiri_parse) + end + let(:error_500_str) do + "<html><body><div><p><code>"\ + "req678"\ + "</code></p></div></body></html>" + end + + let(:error_500_no_code_str) do + "<html><body>"\ + "The code you are looking for is not here"\ + "</body></html>" + end + + it 'returns code is present' do + allow(page).to receive(:html).and_return(error_500_str) + allow(Nokogiri::HTML).to receive(:parse).with(error_500_str).and_return(NokogiriParse.parse(error_500_str)) + + expect(QA::Support::PageErrorChecker.parse_five_c_page_request_id(page).to_str).to eq('req678') + end + it 'returns nil if not present' do + allow(page).to receive(:html).and_return(error_500_no_code_str) + allow(Nokogiri::HTML).to receive(:parse).with(error_500_no_code_str).and_return(NokogiriParse.parse(error_500_no_code_str)) + + expect(QA::Support::PageErrorChecker.parse_five_c_page_request_id(page)).to be_nil + end end end diff --git a/qa/spec/support/repeater_spec.rb b/qa/spec/support/repeater_spec.rb index 4fa3bcde5e7..96e780fc9bd 100644 --- a/qa/spec/support/repeater_spec.rb +++ b/qa/spec/support/repeater_spec.rb @@ -3,12 +3,6 @@ require 'active_support/core_ext/integer/time' RSpec.describe QA::Support::Repeater do - before do - logger = ::Logger.new $stdout - logger.level = ::Logger::DEBUG - QA::Runtime::Logger.logger = logger - end - subject do Module.new do extend QA::Support::Repeater diff --git a/qa/spec/tools/reliable_report_spec.rb b/qa/spec/tools/reliable_report_spec.rb index 85b2590d3aa..318b0833f62 100644 --- a/qa/spec/tools/reliable_report_spec.rb +++ b/qa/spec/tools/reliable_report_spec.rb @@ -167,7 +167,7 @@ describe QA::Tools::ReliableReport do payload: { title: "Reliable e2e test report", description: issue_body, - labels: "Quality,test,type::maintenance,reliable test report,automation:devops-mapping-disable" + labels: "Quality,test,type::maintenance,reliable test report,automation:ml" } ) expect(slack_notifier).to have_received(:post).with( diff --git a/qa/spec/tools/test_resources_data_processor_spec.rb b/qa/spec/tools/test_resources_data_processor_spec.rb index 5117d1d367f..2ae43974a0c 100644 --- a/qa/spec/tools/test_resources_data_processor_spec.rb +++ b/qa/spec/tools/test_resources_data_processor_spec.rb @@ -43,18 +43,30 @@ RSpec.describe QA::Tools::TestResourceDataProcessor do end describe '.write_to_file' do - let(:resources_file) { Pathname.new(Faker::File.file_name(dir: 'tmp', ext: 'json')) } + using RSpec::Parameterized::TableSyntax - before do - stub_env('QA_TEST_RESOURCES_CREATED_FILEPATH', resources_file) - - allow(File).to receive(:write) + where(:ci, :suite_failed, :file_path) do + true | true | 'root/tmp/failed-test-resources-random.json' + true | false | 'root/tmp/test-resources-random.json' + false | true | 'root/tmp/failed-test-resources.json' + false | false | 'root/tmp/test-resources.json' end - it 'writes applicable resources to file' do - processor.write_to_file + with_them do + let(:resources_file) { Pathname.new(file_path) } + + before do + allow(QA::Runtime::Env).to receive(:running_in_ci?).and_return(ci) + allow(File).to receive(:write) + allow(QA::Runtime::Path).to receive(:qa_root).and_return('root') + allow(SecureRandom).to receive(:hex).with(any_args).and_return('random') + end + + it 'writes applicable resources to file' do + processor.write_to_file(suite_failed) - expect(File).to have_received(:write).with(resources_file, JSON.pretty_generate(result)) + expect(File).to have_received(:write).with(resources_file, JSON.pretty_generate(result)) + end end end end |