diff options
author | Mark Lapierre <mlapierre@gitlab.com> | 2019-07-09 15:40:46 +0000 |
---|---|---|
committer | Lin Jen-Shin <godfat@godfat.org> | 2019-07-09 15:40:46 +0000 |
commit | 7d97102f72d6e85546cd317a96655ca3b20d34d2 (patch) | |
tree | de197c36949dda50ac874ee97ca35dbf285a6bf2 /qa/spec | |
parent | ebcf92c585f063f48270c38ef9a8745bbe23c804 (diff) | |
download | gitlab-ce-7d97102f72d6e85546cd317a96655ca3b20d34d2.tar.gz |
Run tests in parallel via parallel_tests
Uses the parallel_tests gem to execute tests in multiple processes
simultaneously on the same machine.
Adds the `--parallel` CLI option that instructs the QA framework
to use the parallel_tests executable.
Tests need access to global state contained in `Runtime::Scenario`
so when `--parallel` is invoked `Runtime::Scenario` is serialized
to an environment variable, which is passed to parallel_tests,
and then deserialized in `spec_helper`.
Diffstat (limited to 'qa/spec')
-rw-r--r-- | qa/spec/page/logging_spec.rb | 8 | ||||
-rw-r--r-- | qa/spec/spec_helper.rb | 4 | ||||
-rw-r--r-- | qa/spec/specs/parallel_runner_spec.rb | 58 | ||||
-rw-r--r-- | qa/spec/specs/runner_spec.rb | 8 |
4 files changed, 70 insertions, 8 deletions
diff --git a/qa/spec/page/logging_spec.rb b/qa/spec/page/logging_spec.rb index 0f1ed039149..92a4f7b40e6 100644 --- a/qa/spec/page/logging_spec.rb +++ b/qa/spec/page/logging_spec.rb @@ -91,26 +91,26 @@ describe QA::Support::Page::Logging do it 'logs has_element?' do expect { subject.has_element?(:element) } - .to output(/has_element\? :element \(wait: 2\) returned: true/).to_stdout_from_any_process + .to output(/has_element\? :element \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).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: 2\) 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/).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: 2\) returned: true/).to_stdout_from_any_process + .to output(/has_no_element\? :element \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).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: 2\) 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/).to_stdout_from_any_process end it 'logs has_text?' do diff --git a/qa/spec/spec_helper.rb b/qa/spec/spec_helper.rb index f25dbf3a8ab..21bfd2876a9 100644 --- a/qa/spec/spec_helper.rb +++ b/qa/spec/spec_helper.rb @@ -8,6 +8,10 @@ if ENV['CI'] && QA::Runtime::Env.knapsack? && !ENV['NO_KNAPSACK'] Knapsack::Adapters::RSpecAdapter.bind end +QA::Runtime::Browser.configure! + +QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes) if QA::Runtime::Env.runtime_scenario_attributes + %w[helpers shared_examples].each do |d| Dir[::File.join(__dir__, d, '**', '*.rb')].each { |f| require f } end diff --git a/qa/spec/specs/parallel_runner_spec.rb b/qa/spec/specs/parallel_runner_spec.rb new file mode 100644 index 00000000000..67d94a1f648 --- /dev/null +++ b/qa/spec/specs/parallel_runner_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +describe QA::Specs::ParallelRunner do + include Helpers::StubENV + + before do + allow(QA::Runtime::Scenario).to receive(:attributes).and_return(parallel: true) + stub_env('GITLAB_QA_ACCESS_TOKEN', 'skip_token_creation') + end + + it 'passes args to parallel_tests' do + expect_cli_arguments(['--tag', '~orchestrated', *QA::Specs::Runner::DEFAULT_TEST_PATH_ARGS]) + + subject.run(['--tag', '~orchestrated', *QA::Specs::Runner::DEFAULT_TEST_PATH_ARGS]) + end + + it 'passes a given test path to parallel_tests and adds a separator' do + expect_cli_arguments(%w[-- qa/specs/features/foo]) + + subject.run(%w[qa/specs/features/foo]) + end + + it 'passes tags and test paths to parallel_tests and adds a separator' do + expect_cli_arguments(%w[--tag smoke -- qa/specs/features/foo qa/specs/features/bar]) + + subject.run(%w[--tag smoke qa/specs/features/foo qa/specs/features/bar]) + end + + it 'passes tags and test paths with separators to parallel_tests' do + expect_cli_arguments(%w[-- --tag smoke -- qa/specs/features/foo qa/specs/features/bar]) + + subject.run(%w[-- --tag smoke -- qa/specs/features/foo qa/specs/features/bar]) + end + + it 'passes supported environment variables' do + # Test only env vars starting with GITLAB because some of the others + # affect how the runner behaves, and we're not concerned with those + # behaviors in this test + gitlab_env_vars = QA::Runtime::Env::ENV_VARIABLES.reject { |v| !v.start_with?('GITLAB') } + + gitlab_env_vars.each do |k, v| + stub_env(k, v) + end + + gitlab_env_vars['QA_RUNTIME_SCENARIO_ATTRIBUTES'] = '{"parallel":true}' + + expect_cli_arguments([], gitlab_env_vars) + + subject.run([]) + end + + def expect_cli_arguments(arguments, env = { 'QA_RUNTIME_SCENARIO_ATTRIBUTES' => '{"parallel":true}' }) + cmd = "bundle exec parallel_test -t rspec --combine-stderr --serialize-stdout -- #{arguments.join(' ')}" + expect(Open3).to receive(:popen2e) + .with(hash_including(env), cmd) + .and_return(0) + end +end diff --git a/qa/spec/specs/runner_spec.rb b/qa/spec/specs/runner_spec.rb index f94145d148e..6c533c6dc7d 100644 --- a/qa/spec/specs/runner_spec.rb +++ b/qa/spec/specs/runner_spec.rb @@ -58,11 +58,11 @@ describe QA::Specs::Runner do end end - context 'when "-- qa/specs/features/foo" is set as options' do - subject { described_class.new.tap { |runner| runner.options = %w[-- qa/specs/features/foo] } } + context 'when "--tag smoke" and "qa/specs/features/foo" are set as options' do + subject { described_class.new.tap { |runner| runner.options = %w[--tag smoke qa/specs/features/foo] } } - it 'passes the given tests path and excludes the orchestrated tag' do - expect_rspec_runner_arguments(['--tag', '~orchestrated', '--', 'qa/specs/features/foo']) + it 'focuses on the given tag and includes the path without excluding the orchestrated tag' do + expect_rspec_runner_arguments(['--tag', 'smoke', 'qa/specs/features/foo']) subject.perform end |