From 8ce3a69f21dba82c25f480634c68753067d9aa7b Mon Sep 17 00:00:00 2001 From: ArturT Date: Sun, 21 May 2017 20:34:10 +0200 Subject: [PATCH 1/8] Remove unnecessary assigment --- lib/knapsack_pro/runners/queue/rspec_runner.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/knapsack_pro/runners/queue/rspec_runner.rb b/lib/knapsack_pro/runners/queue/rspec_runner.rb index 3481de32..03d5b7ab 100644 --- a/lib/knapsack_pro/runners/queue/rspec_runner.rb +++ b/lib/knapsack_pro/runners/queue/rspec_runner.rb @@ -9,7 +9,7 @@ def self.run(args) ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_rspec ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true' - ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id + KnapsackPro::Config::EnvGenerator.set_queue_id runner = new(KnapsackPro::Adapters::RSpecAdapter) @@ -39,7 +39,6 @@ def self.run_tests(runner, can_initialize_queue, args, exitstatus, all_test_file exit(exitstatus) else subset_queue_id = KnapsackPro::Config::EnvGenerator.set_subset_queue_id - ENV['KNAPSACK_PRO_SUBSET_QUEUE_ID'] = subset_queue_id all_test_file_paths += test_file_paths cli_args = args + test_file_paths From 39cdfb9bd0b602562512a558089246480227b3a3 Mon Sep 17 00:00:00 2001 From: ArturT Date: Mon, 22 May 2017 07:40:50 +0200 Subject: [PATCH 2/8] Add hook after_subset_queue --- lib/knapsack_pro.rb | 1 + lib/knapsack_pro/hooks/queue.rb | 21 +++++++++++++++++++ .../runners/queue/rspec_runner.rb | 4 +++- 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 lib/knapsack_pro/hooks/queue.rb diff --git a/lib/knapsack_pro.rb b/lib/knapsack_pro.rb index 087ab8d6..f4deea29 100644 --- a/lib/knapsack_pro.rb +++ b/lib/knapsack_pro.rb @@ -8,6 +8,7 @@ require 'securerandom' require_relative 'knapsack_pro/version' require_relative 'knapsack_pro/extensions/time' +require_relative 'knapsack_pro/hooks/queue' require_relative 'knapsack_pro/utils' require_relative 'knapsack_pro/logger_wrapper' require_relative 'knapsack_pro/config/ci/base' diff --git a/lib/knapsack_pro/hooks/queue.rb b/lib/knapsack_pro/hooks/queue.rb new file mode 100644 index 00000000..7509449c --- /dev/null +++ b/lib/knapsack_pro/hooks/queue.rb @@ -0,0 +1,21 @@ +module KnapsackPro + module Hooks + class Queue + class << self + attr_reader :after_subset_queue + + def after_subset_queue(&block) + @after_subset_queue ||= block + end + + def call_after_subset_queue + return unless after_subset_queue + after_subset_queue.call( + KnapsackPro::Config::Env.queue_id, + KnapsackPro::Config::Env.subset_queue_id + ) + end + end + end + end +end diff --git a/lib/knapsack_pro/runners/queue/rspec_runner.rb b/lib/knapsack_pro/runners/queue/rspec_runner.rb index 03d5b7ab..a51e7964 100644 --- a/lib/knapsack_pro/runners/queue/rspec_runner.rb +++ b/lib/knapsack_pro/runners/queue/rspec_runner.rb @@ -38,7 +38,7 @@ def self.run_tests(runner, can_initialize_queue, args, exitstatus, all_test_file KnapsackPro::Report.save_node_queue_to_api exit(exitstatus) else - subset_queue_id = KnapsackPro::Config::EnvGenerator.set_subset_queue_id + KnapsackPro::Config::EnvGenerator.set_subset_queue_id all_test_file_paths += test_file_paths cli_args = args + test_file_paths @@ -50,6 +50,8 @@ def self.run_tests(runner, can_initialize_queue, args, exitstatus, all_test_file exitstatus = exit_code if exit_code != 0 RSpec.world.example_groups.clear + KnapsackPro::Hooks::Queue.call_after_subset_queue + run_tests(runner, false, args, exitstatus, all_test_file_paths) end end From dd5180d2dc87ed48f750637a1402e7dcdb13434a Mon Sep 17 00:00:00 2001 From: ArturT Date: Fri, 26 May 2017 12:31:58 +0200 Subject: [PATCH 3/8] Add test for hooks queue --- lib/knapsack_pro/hooks/queue.rb | 4 ++++ spec/knapsack_pro/hooks/queue_spec.rb | 29 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 spec/knapsack_pro/hooks/queue_spec.rb diff --git a/lib/knapsack_pro/hooks/queue.rb b/lib/knapsack_pro/hooks/queue.rb index 7509449c..fea166b7 100644 --- a/lib/knapsack_pro/hooks/queue.rb +++ b/lib/knapsack_pro/hooks/queue.rb @@ -4,6 +4,10 @@ class Queue class << self attr_reader :after_subset_queue + def reset_after_subset_queue + @after_subset_queue = nil + end + def after_subset_queue(&block) @after_subset_queue ||= block end diff --git a/spec/knapsack_pro/hooks/queue_spec.rb b/spec/knapsack_pro/hooks/queue_spec.rb new file mode 100644 index 00000000..ce549c47 --- /dev/null +++ b/spec/knapsack_pro/hooks/queue_spec.rb @@ -0,0 +1,29 @@ +describe KnapsackPro::Hooks::Queue do + describe '.call_after_subset_queue' do + subject { described_class.call_after_subset_queue } + + context 'when callback is not set' do + before do + described_class.reset_after_subset_queue + end + + it { should be_nil } + end + + context 'when callback is set' do + let(:queue_id) { double } + let(:subset_queue_id) { double } + + before do + expect(KnapsackPro::Config::Env).to receive(:queue_id).and_return(queue_id) + expect(KnapsackPro::Config::Env).to receive(:subset_queue_id).and_return(subset_queue_id) + + described_class.after_subset_queue do |q_id, subset_q_id| + [:fake_value, q_id, subset_q_id] + end + end + + it { should eq [:fake_value, queue_id, subset_queue_id] } + end + end +end From ce11ea1c905d78a92fd4be45d1f0222e50232b04 Mon Sep 17 00:00:00 2001 From: ArturT Date: Fri, 26 May 2017 12:53:32 +0200 Subject: [PATCH 4/8] Keep explicitly overridden ENVs to ensure the tests work --- lib/knapsack_pro/runners/queue/rspec_runner.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/knapsack_pro/runners/queue/rspec_runner.rb b/lib/knapsack_pro/runners/queue/rspec_runner.rb index a51e7964..337afbfb 100644 --- a/lib/knapsack_pro/runners/queue/rspec_runner.rb +++ b/lib/knapsack_pro/runners/queue/rspec_runner.rb @@ -9,7 +9,7 @@ def self.run(args) ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_rspec ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true' - KnapsackPro::Config::EnvGenerator.set_queue_id + ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id runner = new(KnapsackPro::Adapters::RSpecAdapter) @@ -38,7 +38,8 @@ def self.run_tests(runner, can_initialize_queue, args, exitstatus, all_test_file KnapsackPro::Report.save_node_queue_to_api exit(exitstatus) else - KnapsackPro::Config::EnvGenerator.set_subset_queue_id + subset_queue_id = KnapsackPro::Config::EnvGenerator.set_subset_queue_id + ENV['KNAPSACK_PRO_SUBSET_QUEUE_ID'] = subset_queue_id all_test_file_paths += test_file_paths cli_args = args + test_file_paths From 8fdfd74ccc04004d8270a2332a79af456ebc4e5d Mon Sep 17 00:00:00 2001 From: ArturT Date: Fri, 26 May 2017 12:53:37 +0200 Subject: [PATCH 5/8] Fix spec --- spec/knapsack_pro/runners/queue/rspec_runner_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb b/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb index 78a7fbd2..cf2332f8 100644 --- a/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +++ b/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb @@ -99,6 +99,8 @@ expect(RSpec).to receive_message_chain(:world, :example_groups, :clear) + expect(KnapsackPro::Hooks::Queue).to receive(:call_after_subset_queue) + # second call of run_tests because of recursion expect(runner).to receive(:test_file_paths).with(can_initialize_queue: false).and_return([]) end From 086c9f0547d81cdaf2810932a940676b7b565960 Mon Sep 17 00:00:00 2001 From: ArturT Date: Fri, 26 May 2017 13:18:01 +0200 Subject: [PATCH 6/8] Add example how to use junit formatter with queue mode --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b53736aa..f0d1b6b9 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,8 @@ The knapsack_pro has also [queue mode](#queue-mode) to get optimal test suite sp - [B. Use tags to mark set of tests in particular test file](#b-use-tags-to-mark-set-of-tests-in-particular-test-file) - [How to make knapsack_pro works for forked repositories of my project?](#how-to-make-knapsack_pro-works-for-forked-repositories-of-my-project) - [How to use junit formatter?](#how-to-use-junit-formatter) + - [How to use junit formatter with knapsack_pro regular mode?](#how-to-use-junit-formatter-with-knapsack_pro-regular-mode) + - [How to use junit formatter with knapsack_pro queue mode?](#how-to-use-junit-formatter-with-knapsack_pro-queue-mode) - [How many API keys I need?](#how-many-api-keys-i-need) - [What is optimal order of test commands?](#what-is-optimal-order-of-test-commands) - [How to set `before(:suite)` and `after(:suite)` RSpec hooks in Queue Mode (Percy.io example)?](#how-to-set-beforesuite-and-aftersuite-rspec-hooks-in-queue-mode-percyio-example) @@ -1075,16 +1077,32 @@ Remember to follow other steps required for your CI provider. #### How to use junit formatter? +##### How to use junit formatter with knapsack_pro regular mode? + You can use junit formatter for rspec thanks to gem [rspec_junit_formatter](https://github.com/sj26/rspec_junit_formatter). Here you can find example how to generate `rspec.xml` file with junit format and at the same time show normal documentation format output for RSpec. # Regular Mode bundle exec rake "knapsack_pro:rspec[--format documentation --format RspecJunitFormatter --out tmp/rspec.xml]" +##### How to use junit formatter with knapsack_pro queue mode? + +You can use junit formatter for rspec thanks to gem [rspec_junit_formatter](https://github.com/sj26/rspec_junit_formatter). + # Queue Mode - # The xml report will contain all tests executed across intermediate test subset runs based on queue bundle exec rake "knapsack_pro:queue:rspec[--format documentation --format RspecJunitFormatter --out tmp/rspec.xml]" +The xml report will contain all tests executed across intermediate test subset runs based on work queue. You need to add after subset queue hook to rename `rspec.xml` to `rspec_final_results.xml` thanks to that the final results file will contain only single xml tag with all tests executed on the CI node. This is related to the way how queue mode works. Detailed explanation is in the [issue](https://github.com/KnapsackPro/knapsack_pro-ruby/issues/40). + + # spec_helper.rb or rails_helper.rb + KnapsackPro::Hooks::Queue.after_subset_queue do |queue_id, subset_queue_id| + # TODO This must be the same path as value for rspec --out argument + old_file_xml_file = 'tmp/rspec.xml' + # move results to new_xml_file so the results won't accumulate with duplicated xml tags in old_file_xml_file + new_xml_file = 'tmp/rspec_final_results.xml' + FileUtils.mv(old_file_xml_file, new_xml_file) + end + #### How many API keys I need? Basically you need as many API keys as you have steps in your build. From ed2b26297082ecc5d7a79d920bef4358b14d0ef5 Mon Sep 17 00:00:00 2001 From: ArturT Date: Fri, 26 May 2017 13:20:06 +0200 Subject: [PATCH 7/8] old_xml_file typo --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f0d1b6b9..3d44c2b5 100644 --- a/README.md +++ b/README.md @@ -1097,10 +1097,10 @@ The xml report will contain all tests executed across intermediate test subset r # spec_helper.rb or rails_helper.rb KnapsackPro::Hooks::Queue.after_subset_queue do |queue_id, subset_queue_id| # TODO This must be the same path as value for rspec --out argument - old_file_xml_file = 'tmp/rspec.xml' - # move results to new_xml_file so the results won't accumulate with duplicated xml tags in old_file_xml_file + old_xml_file = 'tmp/rspec.xml' + # move results to new_xml_file so the results won't accumulate with duplicated xml tags in old_xml_file new_xml_file = 'tmp/rspec_final_results.xml' - FileUtils.mv(old_file_xml_file, new_xml_file) + FileUtils.mv(old_xml_file, new_xml_file) end #### How many API keys I need? From c54aac8c30219a7eb94adf36dc6c048b08deaef0 Mon Sep 17 00:00:00 2001 From: ArturT Date: Fri, 26 May 2017 13:26:08 +0200 Subject: [PATCH 8/8] Update change log --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42e5b2ee..21bc6d2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ * TODO +### 0.41.0 + +* Add after subset queue hook and example how to use JUnit formatter in Queue Mode. + + https://github.com/KnapsackPro/knapsack_pro-ruby/pull/41 + +https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v0.40.0...v0.41.0 + ### 0.40.0 * Replace rake task installer `knapsack_pro:install` with online installation guide. Remove `tty-prompt` gem dependency.