summaryrefslogtreecommitdiff
path: root/qa/spec
diff options
context:
space:
mode:
Diffstat (limited to 'qa/spec')
-rw-r--r--qa/spec/runtime/env_spec.rb52
-rw-r--r--qa/spec/scenario/test/integration/object_storage_spec.rb9
-rw-r--r--qa/spec/spec_helper.rb1
-rw-r--r--qa/spec/specs/helpers/context_selector_spec.rb294
-rw-r--r--qa/spec/specs/helpers/quarantine_spec.rb175
-rw-r--r--qa/spec/support/helpers/stub_env.rb2
6 files changed, 297 insertions, 236 deletions
diff --git a/qa/spec/runtime/env_spec.rb b/qa/spec/runtime/env_spec.rb
index 5a98721466f..8218ab428b0 100644
--- a/qa/spec/runtime/env_spec.rb
+++ b/qa/spec/runtime/env_spec.rb
@@ -341,56 +341,4 @@ RSpec.describe QA::Runtime::Env do
end
end
end
-
- describe '.context_matches?' do
- it 'returns true when url has .com' do
- QA::Runtime::Scenario.define(:gitlab_address, "https://staging.gitlab.com")
-
- expect(described_class.dot_com?).to be_truthy
- end
-
- it 'returns false when url does not have .com' do
- QA::Runtime::Scenario.define(:gitlab_address, "https://gitlab.test")
-
- expect(described_class.dot_com?).to be_falsey
- end
-
- context 'with arguments' do
- it 'returns true when :subdomain is set' do
- QA::Runtime::Scenario.define(:gitlab_address, "https://staging.gitlab.com")
-
- expect(described_class.dot_com?(subdomain: :staging)).to be_truthy
- end
-
- it 'matches multiple subdomains' do
- QA::Runtime::Scenario.define(:gitlab_address, "https://staging.gitlab.com")
-
- expect(described_class.context_matches?(subdomain: [:release, :staging])).to be_truthy
- expect(described_class.context_matches?(:production, subdomain: [:release, :staging])).to be_truthy
- end
-
- it 'matches :production' do
- QA::Runtime::Scenario.define(:gitlab_address, "https://gitlab.com/")
-
- expect(described_class.context_matches?(:production)).to be_truthy
- end
-
- it 'doesnt match with mismatching switches' do
- QA::Runtime::Scenario.define(:gitlab_address, 'https://gitlab.test')
-
- aggregate_failures do
- expect(described_class.context_matches?(tld: '.net')).to be_falsey
- expect(described_class.context_matches?(:production)).to be_falsey
- expect(described_class.context_matches?(subdomain: [:staging])).to be_falsey
- expect(described_class.context_matches?(domain: 'example')).to be_falsey
- end
- end
- end
-
- it 'returns false for mismatching' do
- QA::Runtime::Scenario.define(:gitlab_address, "https://staging.gitlab.com")
-
- expect(described_class.context_matches?(:production)).to be_falsey
- end
- end
end
diff --git a/qa/spec/scenario/test/integration/object_storage_spec.rb b/qa/spec/scenario/test/integration/object_storage_spec.rb
deleted file mode 100644
index 235dd495687..00000000000
--- a/qa/spec/scenario/test/integration/object_storage_spec.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.describe QA::Scenario::Test::Integration::ObjectStorage do
- describe '#perform' do
- it_behaves_like 'a QA scenario class' do
- let(:tags) { [:object_storage] }
- end
- end
-end
diff --git a/qa/spec/spec_helper.rb b/qa/spec/spec_helper.rb
index 16d86ef6ed2..631ebf65893 100644
--- a/qa/spec/spec_helper.rb
+++ b/qa/spec/spec_helper.rb
@@ -22,6 +22,7 @@ RSpec.configure do |config|
config.include ::Matchers
QA::Specs::Helpers::Quarantine.configure_rspec
+ QA::Specs::Helpers::ContextSelector.configure_rspec
config.before do |example|
QA::Runtime::Logger.debug("\nStarting test: #{example.full_description}\n")
diff --git a/qa/spec/specs/helpers/context_selector_spec.rb b/qa/spec/specs/helpers/context_selector_spec.rb
new file mode 100644
index 00000000000..16b6c6601b1
--- /dev/null
+++ b/qa/spec/specs/helpers/context_selector_spec.rb
@@ -0,0 +1,294 @@
+# frozen_string_literal: true
+
+require 'rspec/core/sandbox'
+
+RSpec.configure do |c|
+ c.around do |ex|
+ RSpec::Core::Sandbox.sandboxed do |config|
+ # If there is an example-within-an-example, we want to make sure the inner example
+ # does not get a reference to the outer example (the real spec) if it calls
+ # something like `pending`
+ config.before(:context) { RSpec.current_example = nil }
+
+ config.color_mode = :off
+
+ ex.run
+ end
+ end
+end
+
+RSpec.describe QA::Specs::Helpers::ContextSelector do
+ include Helpers::StubENV
+ include QA::Specs::Helpers::RSpec
+
+ before do
+ QA::Runtime::Scenario.define(:gitlab_address, 'https://staging.gitlab.com')
+ described_class.configure_rspec
+ end
+
+ describe '.context_matches?' do
+ it 'returns true when url has .com' do
+ QA::Runtime::Scenario.define(:gitlab_address, "https://staging.gitlab.com")
+
+ expect(described_class.dot_com?).to be_truthy
+ end
+
+ it 'returns false when url does not have .com' do
+ QA::Runtime::Scenario.define(:gitlab_address, "https://gitlab.test")
+
+ expect(described_class.dot_com?).to be_falsey
+ end
+
+ context 'with arguments' do
+ it 'returns true when :subdomain is set' do
+ QA::Runtime::Scenario.define(:gitlab_address, "https://staging.gitlab.com")
+
+ expect(described_class.dot_com?(subdomain: :staging)).to be_truthy
+ end
+
+ it 'matches multiple subdomains' do
+ QA::Runtime::Scenario.define(:gitlab_address, "https://staging.gitlab.com")
+
+ expect(described_class.context_matches?(subdomain: [:release, :staging])).to be_truthy
+ expect(described_class.context_matches?(:production, subdomain: [:release, :staging])).to be_truthy
+ end
+
+ it 'matches :production' do
+ QA::Runtime::Scenario.define(:gitlab_address, "https://gitlab.com/")
+
+ expect(described_class.context_matches?(:production)).to be_truthy
+ end
+
+ it 'doesnt match with mismatching switches' do
+ QA::Runtime::Scenario.define(:gitlab_address, 'https://gitlab.test')
+
+ aggregate_failures do
+ expect(described_class.context_matches?(tld: '.net')).to be_falsey
+ expect(described_class.context_matches?(:production)).to be_falsey
+ expect(described_class.context_matches?(subdomain: [:staging])).to be_falsey
+ expect(described_class.context_matches?(domain: 'example')).to be_falsey
+ end
+ end
+ end
+
+ it 'returns false for mismatching' do
+ QA::Runtime::Scenario.define(:gitlab_address, "https://staging.gitlab.com")
+
+ expect(described_class.context_matches?(:production)).to be_falsey
+ end
+ end
+
+ describe 'description and context blocks' do
+ context 'with environment set' do
+ it 'can apply to contexts or descriptions' do
+ group = describe_successfully 'Runs in staging', only: { subdomain: :staging } do
+ it('runs in staging') {}
+ end
+
+ expect(group.examples[0].execution_result.status).to eq(:passed)
+ end
+ end
+
+ context 'with different environment set' do
+ before do
+ QA::Runtime::Scenario.define(:gitlab_address, 'https://gitlab.com')
+ described_class.configure_rspec
+ end
+
+ it 'does not run against production' do
+ group = describe_successfully 'Runs in staging', :something, only: { subdomain: :staging } do
+ it('runs in staging') {}
+ end
+
+ expect(group.examples[0].execution_result.status).to eq(:pending)
+ end
+ end
+ end
+
+ it 'runs only in staging' do
+ group = describe_successfully do
+ it('runs in staging', only: { subdomain: :staging }) {}
+ it('doesnt run in staging', only: :production) {}
+ it('runs in staging also', only: { subdomain: %i[release staging] }) {}
+ it('runs in any env') {}
+ end
+
+ expect(group.examples[0].execution_result.status).to eq(:passed)
+ expect(group.examples[1].execution_result.status).to eq(:pending)
+ expect(group.examples[2].execution_result.status).to eq(:passed)
+ expect(group.examples[3].execution_result.status).to eq(:passed)
+ end
+
+ context 'custom env' do
+ before do
+ QA::Runtime::Scenario.define(:gitlab_address, 'https://release.gitlab.net')
+ end
+
+ it 'runs on a custom environment' do
+ group = describe_successfully do
+ it('runs on release gitlab net', only: { tld: '.net', subdomain: :release, domain: 'gitlab' }) {}
+ it('does not run on release', only: :production) {}
+ end
+
+ expect(group.examples.first.execution_result.status).to eq(:passed)
+ expect(group.examples.last.execution_result.status).to eq(:pending)
+ end
+ end
+
+ context 'production' do
+ before do
+ QA::Runtime::Scenario.define(:gitlab_address, 'https://gitlab.com/')
+ end
+
+ it 'runs on production' do
+ group = describe_successfully do
+ it('runs on prod', only: :production) {}
+ it('does not run in prod', only: { subdomain: :staging }) {}
+ it('runs in prod and staging', only: { subdomain: /(staging.)?/, domain: 'gitlab' }) {}
+ end
+
+ expect(group.examples[0].execution_result.status).to eq(:passed)
+ expect(group.examples[1].execution_result.status).to eq(:pending)
+ expect(group.examples[2].execution_result.status).to eq(:passed)
+ end
+ end
+
+ it 'outputs a message for invalid environments' do
+ group = describe_successfully do
+ it('will skip', only: :production) {}
+ end
+
+ expect(group.examples.first.execution_result.pending_message).to match(/[Tt]est.*not compatible.*environment/)
+ end
+
+ context 'with pipeline constraints' do
+ context 'without CI_PROJECT_NAME set' do
+ before do
+ stub_env('CI_PROJECT_NAME', nil)
+ described_class.configure_rspec
+ end
+
+ it 'runs on any pipeline' do
+ group = describe_successfully do
+ it('runs given a single named pipeline', only: { pipeline: :nightly }) {}
+ it('runs given an array of pipelines', only: { pipeline: [:canary, :not_nightly] }) {}
+ end
+
+ aggregate_failures do
+ expect(group.examples[0].execution_result.status).to eq(:passed)
+ expect(group.examples[1].execution_result.status).to eq(:passed)
+ end
+ end
+ end
+
+ context 'when a pipeline triggered from the default branch runs in gitlab-qa' do
+ before do
+ stub_env('CI_PROJECT_NAME', 'gitlab-qa')
+ described_class.configure_rspec
+ end
+
+ it 'runs on default branch pipelines' do
+ group = describe_successfully do
+ it('runs on master pipeline given a single pipeline', only: { pipeline: :master }) {}
+ it('runs in master given an array of pipelines', only: { pipeline: [:canary, :master] }) {}
+ it('does not run in non-default pipelines', only: { pipeline: [:nightly, :not_nightly, :not_master] }) {}
+ end
+
+ aggregate_failures do
+ expect(group.examples[0].execution_result.status).to eq(:passed)
+ expect(group.examples[1].execution_result.status).to eq(:passed)
+ expect(group.examples[2].execution_result.status).to eq(:pending)
+ end
+ end
+ end
+
+ context 'with CI_PROJECT_NAME set' do
+ before do
+ stub_env('CI_PROJECT_NAME', 'NIGHTLY')
+ described_class.configure_rspec
+ end
+
+ it 'runs on designated pipeline' do
+ group = describe_successfully do
+ it('runs on nightly', only: { pipeline: :nightly }) {}
+ it('does not run in not_nightly', only: { pipeline: :not_nightly }) {}
+ it('runs on nightly given an array', only: { pipeline: [:canary, :nightly] }) {}
+ it('does not run in not_nightly given an array', only: { pipeline: [:not_nightly, :canary] }) {}
+ end
+
+ aggregate_failures do
+ expect(group.examples[0].execution_result.status).to eq(:passed)
+ expect(group.examples[1].execution_result.status).to eq(:pending)
+ expect(group.examples[2].execution_result.status).to eq(:passed)
+ expect(group.examples[3].execution_result.status).to eq(:pending)
+ end
+ end
+ end
+ end
+
+ context 'when excluding contexts' do
+ context 'with job constraints' do
+ context 'without CI_JOB_NAME set' do
+ before do
+ stub_env('CI_JOB_NAME', nil)
+ described_class.configure_rspec
+ end
+
+ it 'runs in any job' do
+ group = describe_successfully do
+ it('runs given a single named job', exclude: { job: 'ee:instance-image' }) {}
+ it('runs given a single regex pattern', exclude: { job: '.*:instance-image' }) {}
+ it('runs given an array of jobs', exclude: { job: %w[ee:instance-image qa-schedules-browser_ui-3_create] }) {}
+ it('runs given an array of regex patterns', exclude: { job: %w[ee:.* qa-schedules-browser_ui.*] }) {}
+ it('runs given a mix of strings and regex patterns', exclude: { job: %w[ee:instance-image qa-schedules-browser_ui.*] }) {}
+ end
+
+ aggregate_failures do
+ group.examples.each do |example|
+ expect(example.execution_result.status).to eq(:passed)
+ end
+ end
+ end
+ end
+
+ context 'with CI_JOB_NAME set' do
+ before do
+ stub_env('CI_JOB_NAME', 'ee:instance-image')
+ described_class.configure_rspec
+ end
+
+ it 'does not run in the specified job' do
+ group = describe_successfully do
+ it('skips given a single named job', exclude: { job: 'ee:instance-image' }) {}
+ it('skips given a single regex pattern', exclude: { job: '.*:instance-image' }) {}
+ it('skips given an array of jobs', exclude: { job: %w[ee:instance-image qa-schedules-browser_ui-3_create] }) {}
+ it('skips given an array of regex patterns', exclude: { job: %w[ee:.* qa-schedules-browser_ui.*] }) {}
+ it('skips given a mix of strings and regex patterns', exclude: { job: %w[ee:instance-image qa-schedules-browser_ui.*] }) {}
+ end
+
+ aggregate_failures do
+ group.examples.each do |example|
+ expect(example.execution_result.status).to eq(:pending)
+ end
+ end
+ end
+
+ it 'runs in jobs that do not match' do
+ group = describe_successfully do
+ it('runs given a single named job', exclude: { job: 'ce:instance-image' }) {}
+ it('runs given a single regex pattern', exclude: { job: '.*:instance-image-quarantine' }) {}
+ it('runs given an array of jobs', exclude: { job: %w[ce:instance-image qa-schedules-browser_ui-3_create] }) {}
+ it('runs given an array of regex patterns', exclude: { job: %w[ce:.* qa-schedules-browser_ui.*] }) {}
+ it('runs given a mix of strings and regex patterns', exclude: { job: %w[ce:instance-image qa-schedules-browser_ui.*] }) {}
+ end
+
+ aggregate_failures do
+ group.examples.each do |example|
+ expect(example.execution_result.status).to eq(:passed)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/spec/specs/helpers/quarantine_spec.rb b/qa/spec/specs/helpers/quarantine_spec.rb
index 694c320ce3d..45754a09b17 100644
--- a/qa/spec/specs/helpers/quarantine_spec.rb
+++ b/qa/spec/specs/helpers/quarantine_spec.rb
@@ -2,25 +2,6 @@
require 'rspec/core/sandbox'
-# We need a reporter for internal tests that's different from the reporter for
-# external tests otherwise the results will be mixed up. We don't care about
-# most reporting, but we do want to know if a test fails
-class RaiseOnFailuresReporter < RSpec::Core::NullReporter
- def self.example_failed(example)
- raise example.exception
- end
-end
-
-# We use an example group wrapper to prevent the state of internal tests
-# expanding into the global state
-# See: https://github.com/rspec/rspec-core/issues/2603
-def describe_successfully(*args, &describe_body)
- example_group = RSpec.describe(*args, &describe_body)
- ran_successfully = example_group.run RaiseOnFailuresReporter
- expect(ran_successfully).to eq true
- example_group
-end
-
RSpec.configure do |c|
c.around do |ex|
RSpec::Core::Sandbox.sandboxed do |config|
@@ -38,6 +19,7 @@ end
RSpec.describe QA::Specs::Helpers::Quarantine do
include Helpers::StubENV
+ include QA::Specs::Helpers::RSpec
describe '.skip_or_run_quarantined_contexts' do
context 'with no tag focused' do
@@ -336,159 +318,4 @@ RSpec.describe QA::Specs::Helpers::Quarantine do
end
end
end
-
- describe 'running against specific environments or pipelines' do
- before do
- QA::Runtime::Scenario.define(:gitlab_address, 'https://staging.gitlab.com')
- described_class.configure_rspec
- end
-
- describe 'description and context blocks' do
- context 'with environment set' do
- it 'can apply to contexts or descriptions' do
- group = describe_successfully 'Runs in staging', only: { subdomain: :staging } do
- it('runs in staging') {}
- end
-
- expect(group.examples[0].execution_result.status).to eq(:passed)
- end
- end
-
- context 'with different environment set' do
- before do
- QA::Runtime::Scenario.define(:gitlab_address, 'https://gitlab.com')
- described_class.configure_rspec
- end
-
- it 'does not run against production' do
- group = describe_successfully 'Runs in staging', :something, only: { subdomain: :staging } do
- it('runs in staging') {}
- end
-
- expect(group.examples[0].execution_result.status).to eq(:pending)
- end
- end
- end
-
- it 'runs only in staging' do
- group = describe_successfully do
- it('runs in staging', only: { subdomain: :staging }) {}
- it('doesnt run in staging', only: :production) {}
- it('runs in staging also', only: { subdomain: %i[release staging] }) {}
- it('runs in any env') {}
- end
-
- expect(group.examples[0].execution_result.status).to eq(:passed)
- expect(group.examples[1].execution_result.status).to eq(:pending)
- expect(group.examples[2].execution_result.status).to eq(:passed)
- expect(group.examples[3].execution_result.status).to eq(:passed)
- end
-
- context 'custom env' do
- before do
- QA::Runtime::Scenario.define(:gitlab_address, 'https://release.gitlab.net')
- end
-
- it 'runs on a custom environment' do
- group = describe_successfully do
- it('runs on release gitlab net', only: { tld: '.net', subdomain: :release, domain: 'gitlab' }) {}
- it('does not run on release', only: :production) {}
- end
-
- expect(group.examples.first.execution_result.status).to eq(:passed)
- expect(group.examples.last.execution_result.status).to eq(:pending)
- end
- end
-
- context 'production' do
- before do
- QA::Runtime::Scenario.define(:gitlab_address, 'https://gitlab.com/')
- end
-
- it 'runs on production' do
- group = describe_successfully do
- it('runs on prod', only: :production) {}
- it('does not run in prod', only: { subdomain: :staging }) {}
- it('runs in prod and staging', only: { subdomain: /(staging.)?/, domain: 'gitlab' }) {}
- end
-
- expect(group.examples[0].execution_result.status).to eq(:passed)
- expect(group.examples[1].execution_result.status).to eq(:pending)
- expect(group.examples[2].execution_result.status).to eq(:passed)
- end
- end
-
- it 'outputs a message for invalid environments' do
- group = describe_successfully do
- it('will skip', only: :production) {}
- end
-
- expect(group.examples.first.execution_result.pending_message).to match(/[Tt]est.*not compatible.*environment/)
- end
-
- context 'with pipeline constraints' do
- context 'without CI_PROJECT_NAME set' do
- before do
- stub_env('CI_PROJECT_NAME', nil)
- described_class.configure_rspec
- end
-
- it 'runs on any pipeline' do
- group = describe_successfully do
- it('runs given a single named pipeline', only: { pipeline: :nightly }) {}
- it('runs given an array of pipelines', only: { pipeline: [:canary, :not_nightly] }) {}
- end
-
- aggregate_failures do
- expect(group.examples[0].execution_result.status).to eq(:passed)
- expect(group.examples[1].execution_result.status).to eq(:passed)
- end
- end
- end
-
- context 'when a pipeline triggered from the default branch runs in gitlab-qa' do
- before do
- stub_env('CI_PROJECT_NAME', 'gitlab-qa')
- described_class.configure_rspec
- end
-
- it 'runs on default branch pipelines' do
- group = describe_successfully do
- it('runs on master pipeline given a single pipeline', only: { pipeline: :master }) {}
- it('runs in master given an array of pipelines', only: { pipeline: [:canary, :master] }) {}
- it('does not run in non-default pipelines', only: { pipeline: [:nightly, :not_nightly, :not_master] }) {}
- end
-
- aggregate_failures do
- expect(group.examples[0].execution_result.status).to eq(:passed)
- expect(group.examples[1].execution_result.status).to eq(:passed)
- expect(group.examples[2].execution_result.status).to eq(:pending)
- end
- end
- end
-
- context 'with CI_PROJECT_NAME set' do
- before do
- stub_env('CI_PROJECT_NAME', 'NIGHTLY')
- described_class.configure_rspec
- end
-
- it 'runs on designated pipeline' do
- group = describe_successfully do
- it('runs on nightly', only: { pipeline: :nightly }) {}
- it('does not run in not_nightly', only: { pipeline: :not_nightly }) {}
- it('runs on nightly given an array', only: { pipeline: [:canary, :nightly] }) {}
- it('does not run in not_nightly given an array', only: { pipeline: [:not_nightly, :canary] }) {}
- end
-
- aggregate_failures do
- expect(group.examples[0].execution_result.status).to eq(:passed)
- expect(group.examples[1].execution_result.status).to eq(:pending)
- expect(group.examples[2].execution_result.status).to eq(:passed)
- expect(group.examples[3].execution_result.status).to eq(:pending)
- end
- end
- end
- end
- end
end
diff --git a/qa/spec/support/helpers/stub_env.rb b/qa/spec/support/helpers/stub_env.rb
index 8ad864dbec8..de8d2f47adf 100644
--- a/qa/spec/support/helpers/stub_env.rb
+++ b/qa/spec/support/helpers/stub_env.rb
@@ -15,7 +15,7 @@ module Helpers
private
- STUBBED_KEY = '__STUBBED__'.freeze
+ STUBBED_KEY = '__STUBBED__'
def add_stubbed_value(key, value)
allow(ENV).to receive(:[]).with(key).and_return(value)