knapsack_pro 1.11.0 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 640a408f0a698ec1f064a7857699aeaf5ec27c72a3b30e96a0dfc80655473549
4
- data.tar.gz: b8a305a9e170cf0f015be62a85c0415bfe3ba76c1255122fdc0c1b0c46a8d934
3
+ metadata.gz: e9136de69ec2946c504045fcc1d87f265d0a72813ca9b08005822a1a3d1204f0
4
+ data.tar.gz: 84e21fb2cd6a32b8cbdd08f2ca47d8f97613783e6d4aa08fa821c96c98b63cc9
5
5
  SHA512:
6
- metadata.gz: 7e6ecaf953291bf583006846a3511162f7896f5e0ad374dcf861c8aa99dc017f2d102bf0a85b96133b24afc4a3ce99632aaded1384e853a6cd6c2a7d48c77c0d
7
- data.tar.gz: 0350dafb658f2d965bd46728f0f18ae1d3dc0e44639eb1d54969c6f203bdc82f2d7653da63ec71fe7de9fe0013b8faf1e5142ef26dac7b702342f012449b7f6c
6
+ metadata.gz: 0bc36feebf7c2e4548fdece973557f7babe6ac31b0faf504d1e80fa99a4b472c324eed71b90eb4c2619cc785aca9251fe1124cd179d50e578220778475e9b154
7
+ data.tar.gz: ecb801b9ad989c9106ccbc74aa421ac4a2fbbc164188eb80bd3a82fc5fdc191ee20365707041c00ffefbe6a6ac6635d6c2e278c3fb10261daa4c8a7c156f32e5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ### 1.12.0
4
+
5
+ * Add Queue Mode for Cucumber
6
+
7
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/87
8
+
9
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v1.11.0...v1.12.0
10
+
3
11
  ### 1.11.0
4
12
 
5
13
  * Add support for `KNAPSACK_PRO_TEST_FILE_LIST` environment variable to run explicitly listed tests
data/README.md CHANGED
@@ -158,6 +158,7 @@ You can see list of questions for common problems and tips in below [Table of Co
158
158
  - [How to use junit formatter with knapsack_pro queue mode?](#how-to-use-junit-formatter-with-knapsack_pro-queue-mode)
159
159
  - [How to use junit formatter with knapsack_pro queue mode when CI nodes use common local drive?](#how-to-use-junit-formatter-with-knapsack_pro-queue-mode-when-ci-nodes-use-common-local-drive)
160
160
  - [Why `tmp/rspec_final_results.xml` is corrupted when I use junit formatter with knapsack_pro queue mode?](#why-tmprspec_final_resultsxml-is-corrupted-when-i-use-junit-formatter-with-knapsack_pro-queue-mode)
161
+ - [How to use junit formatter with knapsack_pro queue mode in Cucumber?](#how-to-use-junit-formatter-with-knapsack_pro-queue-mode-in-cucumber)
161
162
  - [How to use JSON formatter for RSpec?](#how-to-use-json-formatter-for-rspec)
162
163
  - [How to use RSpec JSON formatter with knapsack_pro Queue Mode?](#how-to-use-rspec-json-formatter-with-knapsack_pro-queue-mode)
163
164
  - [How to use RSpec JSON formatter with knapsack_pro Queue Mode when CI nodes use common local drive?](#how-to-use-rspec-json-formatter-with-knapsack_pro-queue-mode-when-ci-nodes-use-common-local-drive)
@@ -165,6 +166,7 @@ You can see list of questions for common problems and tips in below [Table of Co
165
166
  - [What is optimal order of test commands?](#what-is-optimal-order-of-test-commands)
166
167
  - [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)
167
168
  - [How to call `before(:suite)` and `after(:suite)` RSpec hooks only once in Queue Mode?](#how-to-call-beforesuite-and-aftersuite-rspec-hooks-only-once-in-queue-mode)
169
+ - [What hooks are supported in Queue Mode?](#what-hooks-are-supported-in-queue-mode)
168
170
  - [How to run knapsack_pro with parallel_tests gem?](#how-to-run-knapsack_pro-with-parallel_tests-gem)
169
171
  - [parallel_tests with knapsack_pro on parallel CI nodes](#parallel_tests-with-knapsack_pro-on-parallel-ci-nodes)
170
172
  - [parallel_tests with knapsack_pro on single CI machine](#parallel_tests-with-knapsack_pro-on-single-ci-machine)
@@ -175,8 +177,8 @@ You can see list of questions for common problems and tips in below [Table of Co
175
177
  - [How to run only RSpec feature tests or non feature tests?](#how-to-run-only-rspec-feature-tests-or-non-feature-tests)
176
178
  - [How to exclude tests from running them?](#how-to-exclude-tests-from-running-them)
177
179
  - [How to run a specific list of test files or only some tests from test file?](#how-to-run-a-specific-list-of-test-files-or-only-some-tests-from-test-file)
178
- - [How to use CodeClimate with knapsack_pro?](#how-to-use-codeclimate-with-knapsack_pro)
179
180
  - [How to run knapsack_pro only on a few parallel CI nodes instead of all?](#how-to-run-knapsack_pro-only-on-a-few-parallel-ci-nodes-instead-of-all)
181
+ - [How to use CodeClimate with knapsack_pro?](#how-to-use-codeclimate-with-knapsack_pro)
180
182
  - [How to use simplecov in Queue Mode?](#how-to-use-simplecov-in-queue-mode)
181
183
  - [Do I need to use separate API token for Queue Mode and Regular Mode?](#do-i-need-to-use-separate-api-token-for-queue-mode-and-regular-mode)
182
184
  - [How to stop running tests on the first failed test (fail fast tests in RSpec)?](#how-to-stop-running-tests-on-the-first-failed-test-fail-fast-tests-in-rspec)
@@ -437,9 +439,12 @@ See how it works and what problems can be solved with Queue Mode https://youtu.b
437
439
 
438
440
  ### How to use queue mode?
439
441
 
440
- Please use a separate API token for queue mode from one used already for regular mode.
442
+ Please don't use the same API token to run tests in Regular Mode and Queue Mode at the same time for your daily work.
441
443
 
442
- Use this command to run queue mode:
444
+ Only when you setup your project for the first time use the same API token and please record whole test suite with Regular Mode then change knapsack pro command to Queue Mode and keep using the same API token.
445
+ Thanks to that your first CI build run in Queue Mode will use timing data recorded with Regular Mode to run tests in Queue Mode faster for the very first run.
446
+
447
+ Use this command to run Queue Mode:
443
448
 
444
449
  ```bash
445
450
  # RSpec >= 3.x
@@ -447,16 +452,19 @@ bundle exec rake knapsack_pro:queue:rspec
447
452
 
448
453
  # Minitest
449
454
  bundle exec rake knapsack_pro:queue:minitest
455
+
456
+ # Cucumber
457
+ bundle exec rake knapsack_pro:queue:cucumber
450
458
  ```
451
459
 
452
- If the above command fails then you may need to explicitly pass an argument to require the `rails_helper` file or `spec_helper` in case you are not doing this in some of your test files:
460
+ If the above command fails for RSpec then you may need to explicitly pass an argument to require the `rails_helper` file or `spec_helper` in case you are not doing this in some of your test files:
453
461
 
454
462
  ```bash
455
463
  bundle exec rake "knapsack_pro:queue:rspec[--require rails_helper]"
456
464
  ```
457
465
 
458
- Note: when you run queue mode command for the first time it might be slower.
459
- The second build should have a more optimal test suite split.
466
+ Note: when you run Queue Mode command for the first time without recording tests first in Regular Mode then CI build might be slower (especially for Cucumber).
467
+ The second CI build should have optimal test suite split with faster tests distribution across CI nodes in Queue Mode.
460
468
 
461
469
  __Please ensure you have explicitly set `RAILS_ENV=test` on your CI nodes.__
462
470
 
@@ -544,6 +552,7 @@ At this moment the queue mode works for:
544
552
 
545
553
  * RSpec
546
554
  * Minitest
555
+ * Cucumber
547
556
 
548
557
  ## Extra configuration for CI server
549
558
 
@@ -668,6 +677,7 @@ You can install knapsack_pro globally and use binary. For instance:
668
677
  knapsack_pro rspec "--tag custom_tag_name --profile"
669
678
  knapsack_pro queue:rspec "--tag custom_tag_name --profile"
670
679
  knapsack_pro cucumber "--name feature"
680
+ knapsack_pro queue:cucumber "--name feature"
671
681
  knapsack_pro minitest "--verbose --pride"
672
682
  knapsack_pro queue:minitest "--verbose"
673
683
  knapsack_pro test_unit "--verbose"
@@ -801,6 +811,13 @@ Here is another example for CircleCI 2.0 platform.
801
811
  # export word is important here!
802
812
  export RAILS_ENV=test
803
813
  bundle exec rake "knapsack_pro:queue:minitest[--verbose]"
814
+
815
+ - run:
816
+ name: Cucumber via knapsack_pro Queue Mode
817
+ command: |
818
+ # export word is important here!
819
+ export RAILS_ENV=test
820
+ bundle exec rake knapsack_pro:queue:cucumber
804
821
  ```
805
822
 
806
823
  Please remember to add additional containers for your project in CircleCI settings.
@@ -1064,6 +1081,7 @@ test:
1064
1081
  # Knapsack Pro Queue Mode (dynamic test suite split)
1065
1082
  # bundle exec rake knapsack_pro:queue:rspec
1066
1083
  # bundle exec rake knapsack_pro:queue:minitest
1084
+ # bundle exec rake knapsack_pro:queue:cucumber
1067
1085
  ```
1068
1086
 
1069
1087
  Here you can find info [how to configure the GitLab parallel CI nodes](https://docs.gitlab.com/ee/ci/yaml/#parallel).
@@ -1087,6 +1105,8 @@ test_ci_node_0:
1087
1105
  - export KNAPSACK_PRO_CI_NODE_INDEX=0
1088
1106
  # Cucumber tests in Knapsack Pro Regular Mode (deterministic test suite split)
1089
1107
  - bundle exec rake knapsack_pro:cucumber
1108
+ # or use Cucumber tests in Knapsack Pro Queue Mode (dynamic test suite split)
1109
+ - bundle exec rake knapsack_pro:queue:cucumber
1090
1110
  # RSpec tests in Knapsack Pro Queue Mode (dynamic test suite split)
1091
1111
  # It will autobalance build because it is executed after Cucumber tests.
1092
1112
  - bundle exec rake knapsack_pro:queue:rspec
@@ -1097,6 +1117,7 @@ test_ci_node_1:
1097
1117
  script:
1098
1118
  - export KNAPSACK_PRO_CI_NODE_INDEX=1
1099
1119
  - bundle exec rake knapsack_pro:cucumber
1120
+ - bundle exec rake knapsack_pro:queue:cucumber
1100
1121
  - bundle exec rake knapsack_pro:queue:rspec
1101
1122
  ```
1102
1123
 
@@ -1112,6 +1133,9 @@ Configure test pipelines (1/2 used)
1112
1133
  # Cucumber tests in Knapsack Pro Regular Mode (deterministic test suite split)
1113
1134
  KNAPSACK_PRO_CI_NODE_TOTAL=2 KNAPSACK_PRO_CI_NODE_INDEX=0 bundle exec rake knapsack_pro:cucumber
1114
1135
 
1136
+ # or use Cucumber tests in Knapsack Pro Queue Mode (dynamic test suite split)
1137
+ KNAPSACK_PRO_CI_NODE_TOTAL=2 KNAPSACK_PRO_CI_NODE_INDEX=0 bundle exec rake knapsack_pro:queue:cucumber
1138
+
1115
1139
  # RSpec tests in Knapsack Pro Queue Mode (dynamic test suite split)
1116
1140
  # It will autobalance build because it is executed after Cucumber tests.
1117
1141
  KNAPSACK_PRO_CI_NODE_TOTAL=2 KNAPSACK_PRO_CI_NODE_INDEX=0 bundle exec rake knapsack_pro:queue:rspec
@@ -1125,6 +1149,9 @@ Configure test pipelines (2/2 used)
1125
1149
  # Cucumber tests in Knapsack Pro Regular Mode (deterministic test suite split)
1126
1150
  KNAPSACK_PRO_CI_NODE_TOTAL=2 KNAPSACK_PRO_CI_NODE_INDEX=1 bundle exec rake knapsack_pro:cucumber
1127
1151
 
1152
+ # or use Cucumber tests in Knapsack Pro Queue Mode (dynamic test suite split)
1153
+ KNAPSACK_PRO_CI_NODE_TOTAL=2 KNAPSACK_PRO_CI_NODE_INDEX=1 bundle exec rake knapsack_pro:queue:cucumber
1154
+
1128
1155
  # RSpec tests in Knapsack Pro Queue Mode (dynamic test suite split)
1129
1156
  # It will autobalance build because it is executed after Cucumber tests.
1130
1157
  KNAPSACK_PRO_CI_NODE_TOTAL=2 KNAPSACK_PRO_CI_NODE_INDEX=1 bundle exec rake knapsack_pro:queue:rspec
@@ -2016,6 +2043,15 @@ end
2016
2043
  The `tmp/rspec_final_results.xml` might be corrupted due syntax error in your test suite. First check if your test suite is green.
2017
2044
  Another reason might be that you did not configure the junit formatter as shown in the example for Queue Mode. Please check above 2 questions & answers explaing that.
2018
2045
 
2046
+ ###### How to use junit formatter with knapsack_pro queue mode in Cucumber?
2047
+
2048
+ Please provide in `--out` argument directory path where xml files for each test file will be created. It must be a directory in order to work in Queue Mode because in Queue Mode the Cucumber test runner is executed multiple times.
2049
+ Each time for set of tests fetched from Queue so it means multiple xml files will be created in junit format.
2050
+
2051
+ ```bash
2052
+ bundle exec rake "knapsack_pro:queue:cucumber[--format junit --out tmp/test-reports/cucumber/queue_mode/]"
2053
+ ```
2054
+
2019
2055
  #### How to use JSON formatter for RSpec?
2020
2056
 
2021
2057
  ##### How to use RSpec JSON formatter with knapsack_pro Queue Mode?
@@ -2160,6 +2196,61 @@ KnapsackPro::Hooks::Queue.after_queue do |queue_id|
2160
2196
  end
2161
2197
  ```
2162
2198
 
2199
+ #### What hooks are supported in Queue Mode?
2200
+
2201
+ * RSpec in knapsack_pro Queue Mode supports hooks:
2202
+
2203
+ ```ruby
2204
+ # spec_helper.rb or rails_helper.rb
2205
+ KnapsackPro::Hooks::Queue.before_queue do |queue_id|
2206
+ print 'Before Queue Hook - run before test suite'
2207
+ end
2208
+
2209
+ # this will be run after set of tests fetched from Queue has been executed
2210
+ KnapsackPro::Hooks::Queue.after_subset_queue do |queue_id, subset_queue_id|
2211
+ print 'After Subset Queue Hook - run after subset of test suite'
2212
+ end
2213
+
2214
+ KnapsackPro::Hooks::Queue.after_queue do |queue_id|
2215
+ print 'After Queue Hook - run after test suite'
2216
+ end
2217
+ ```
2218
+
2219
+ * Minitest in knapsack_pro Queue Mode supports hooks:
2220
+
2221
+ ```ruby
2222
+ # test/test_helper.rb
2223
+ KnapsackPro::Hooks::Queue.before_queue do |queue_id|
2224
+ print 'Before Queue Hook - run before test suite'
2225
+ end
2226
+
2227
+ KnapsackPro::Hooks::Queue.after_subset_queue do |queue_id, subset_queue_id|
2228
+ print 'After Subset Queue Hook - run after subset of test suite'
2229
+ end
2230
+
2231
+ KnapsackPro::Hooks::Queue.after_queue do |queue_id|
2232
+ print 'After Queue Hook - run after test suite'
2233
+ end
2234
+ ```
2235
+
2236
+ * Cucumber in knapsack_pro Queue Mode supports hooks:
2237
+
2238
+ ```ruby
2239
+ # features/support/knapsack_pro.rb
2240
+ KnapsackPro::Hooks::Queue.before_queue do |queue_id|
2241
+ print 'Before Queue Hook - run before test suite'
2242
+ end
2243
+
2244
+ KnapsackPro::Hooks::Queue.after_subset_queue do |queue_id, subset_queue_id|
2245
+ print 'After Subset Queue Hook - run after subset of test suite'
2246
+ end
2247
+
2248
+ # this hook is not supported and won't run
2249
+ KnapsackPro::Hooks::Queue.after_queue do |queue_id|
2250
+ print 'After Queue Hook - run after test suite'
2251
+ end
2252
+ ```
2253
+
2163
2254
  #### How to run knapsack_pro with parallel_tests gem?
2164
2255
 
2165
2256
  ##### parallel_tests with knapsack_pro on parallel CI nodes
@@ -2436,12 +2527,6 @@ Note when you set `KNAPSACK_PRO_TEST_FILE_LIST` then below environment variables
2436
2527
  * `KNAPSACK_PRO_TEST_FILE_PATTERN`
2437
2528
  * `KNAPSACK_PRO_TEST_FILE_EXCLUDE_PATTERN`
2438
2529
 
2439
- #### How to use CodeClimate with knapsack_pro?
2440
-
2441
- You can check CodeClimate docs about [parallel tests](https://docs.codeclimate.com/docs/configuring-test-coverage#section-parallel-tests) and [multiple test suites](https://docs.codeclimate.com/docs/configuring-test-coverage#section-multiple-test-suites).
2442
-
2443
- You can also read our article [how to merge CodeClimate reports for parallel jobs (CI nodes)](https://docs.knapsackpro.com/2019/how-to-merge-codeclimate-reports-for-parallel-jobs-ci-nodes).
2444
-
2445
2530
  #### How to run knapsack_pro only on a few parallel CI nodes instead of all?
2446
2531
 
2447
2532
  You may want to run knapsack_pro only on a few CI nodes when you would like to run a different job on other CI nodes.
@@ -2462,6 +2547,12 @@ On the 3rd CI node, you can run other things like linters etc.
2462
2547
  If you would like to check what is the CI node total ENV variable name exposed by your CI provider you can check that in your CI provider environment variables docs
2463
2548
  or preview the [ENV variables that knapsack_pro can read](https://github.com/KnapsackPro/knapsack_pro-ruby/tree/master/lib/knapsack_pro/config/ci) for supported CI providers.
2464
2549
 
2550
+ #### How to use CodeClimate with knapsack_pro?
2551
+
2552
+ You can check articles about CodeClimate configuration with knapsack_pro gem:
2553
+ * [CodeClimate and CircleCI 2.0 parallel builds config for RSpec with SimpleCov and JUnit formatter](https://docs.knapsackpro.com/2019/codeclimate-and-circleci-2-0-parallel-builds-config-for-rspec-with-simplecov-and-junit-formatter)
2554
+ * [How to merge CodeClimate reports for parallel jobs (CI nodes) on Semaphore CI 2.0](https://docs.knapsackpro.com/2019/how-to-merge-codeclimate-reports-for-parallel-jobs-ci-nodes).
2555
+
2465
2556
  #### How to use simplecov in Queue Mode?
2466
2557
 
2467
2558
  If you would like to make [simplecov](https://github.com/colszowka/simplecov) gem work with knapsack_pro Queue Mode to correctly track code coverage for parallel CI nodes please do:
data/bin/knapsack_pro CHANGED
@@ -9,6 +9,7 @@ MAP = {
9
9
  'rspec' => KnapsackPro::Runners::RSpecRunner,
10
10
  'queue:rspec' => KnapsackPro::Runners::Queue::RSpecRunner,
11
11
  'cucumber' => KnapsackPro::Runners::CucumberRunner,
12
+ 'queue:cucumber' => KnapsackPro::Runners::Queue::CucumberRunner,
12
13
  'minitest' => KnapsackPro::Runners::MinitestRunner,
13
14
  'queue:minitest' => KnapsackPro::Runners::Queue::MinitestRunner,
14
15
  'test_unit' => KnapsackPro::Runners::TestUnitRunner,
@@ -53,6 +53,25 @@ module KnapsackPro
53
53
  end
54
54
  end
55
55
 
56
+ def bind_before_queue_hook
57
+ Around do |object, block|
58
+ unless ENV['KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED']
59
+ KnapsackPro::Hooks::Queue.call_before_queue
60
+ ENV['KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED'] = 'true'
61
+ end
62
+ block.call
63
+ end
64
+ end
65
+
66
+ def bind_queue_mode
67
+ super
68
+
69
+ ::Kernel.at_exit do
70
+ KnapsackPro::Hooks::Queue.call_after_subset_queue
71
+ KnapsackPro::Report.save_subset_queue_to_file
72
+ end
73
+ end
74
+
56
75
  private
57
76
 
58
77
  def Around(*tag_expressions, &proc)
@@ -47,7 +47,7 @@ module KnapsackPro
47
47
  if test_files.size > 0 && measured_test_files.size == 0
48
48
  KnapsackPro.logger.warn("#{test_files.size} test files were executed on this CI node but the recorded time was lost due to:")
49
49
  KnapsackPro.logger.warn("1. Probably you have a code (i.e. RSpec hooks) that clears tmp directory in your project. Please ensure you do not remove the content of tmp/knapsack_pro/queue/ directory between tests run.")
50
- KnapsackPro.logger.warn("2. Another reason might be that you forgot to add Knapsack::Adapters::RspecAdapter.bind in your rails_helper.rb or spec_helper.rb. Please follow the installation guide again: https://docs.knapsackpro.com/integration/")
50
+ KnapsackPro.logger.warn("2. Another reason might be that you forgot to add Knapsack::Adapters::RSpecAdapter.bind in your rails_helper.rb or spec_helper.rb. Please follow the installation guide again: https://docs.knapsackpro.com/integration/")
51
51
  KnapsackPro.logger.warn("3. All your tests are empty test files, are pending tests or have syntax error and could not be executed hence no measured time execution by knapsack_pro.")
52
52
  end
53
53
 
@@ -0,0 +1,96 @@
1
+ module KnapsackPro
2
+ module Runners
3
+ module Queue
4
+ class CucumberRunner < BaseRunner
5
+ def self.run(args)
6
+ require 'cucumber/rake/task'
7
+
8
+ ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_cucumber
9
+ ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true'
10
+ ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id
11
+
12
+ runner = new(KnapsackPro::Adapters::CucumberAdapter)
13
+
14
+ accumulator = {
15
+ status: :next,
16
+ runner: runner,
17
+ can_initialize_queue: true,
18
+ args: args,
19
+ exitstatus: 0,
20
+ all_test_file_paths: [],
21
+ }
22
+ while accumulator[:status] == :next
23
+ accumulator = run_tests(accumulator)
24
+ end
25
+
26
+ Kernel.exit(accumulator[:exitstatus])
27
+ end
28
+
29
+ def self.run_tests(accumulator)
30
+ runner = accumulator.fetch(:runner)
31
+ can_initialize_queue = accumulator.fetch(:can_initialize_queue)
32
+ args = accumulator.fetch(:args)
33
+ exitstatus = accumulator.fetch(:exitstatus)
34
+ all_test_file_paths = accumulator.fetch(:all_test_file_paths)
35
+
36
+ test_file_paths = runner.test_file_paths(
37
+ can_initialize_queue: can_initialize_queue,
38
+ executed_test_files: all_test_file_paths
39
+ )
40
+
41
+ if test_file_paths.empty?
42
+ KnapsackPro::Hooks::Queue.call_after_queue
43
+
44
+ KnapsackPro::Report.save_node_queue_to_api
45
+
46
+ return {
47
+ status: :completed,
48
+ exitstatus: exitstatus,
49
+ }
50
+ else
51
+ subset_queue_id = KnapsackPro::Config::EnvGenerator.set_subset_queue_id
52
+ ENV['KNAPSACK_PRO_SUBSET_QUEUE_ID'] = subset_queue_id
53
+
54
+ KnapsackPro.tracker.reset!
55
+ KnapsackPro.tracker.set_prerun_tests(test_file_paths)
56
+
57
+ all_test_file_paths += test_file_paths
58
+
59
+ result_exitstatus = cucumber_run(runner, test_file_paths, args)
60
+ exitstatus = 1 if result_exitstatus != 0
61
+
62
+ # KnapsackPro::Hooks::Queue.call_after_subset_queue
63
+ # KnapsackPro::Report.save_subset_queue_to_file
64
+ # are called in adapter: lib/knapsack_pro/adapters/cucumber_adapter.rb
65
+
66
+ return {
67
+ status: :next,
68
+ runner: runner,
69
+ can_initialize_queue: false,
70
+ args: args,
71
+ exitstatus: exitstatus,
72
+ all_test_file_paths: all_test_file_paths,
73
+ }
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ def self.cucumber_run(runner, test_file_paths, args)
80
+ stringify_test_file_paths = KnapsackPro::TestFilePresenter.stringify_paths(test_file_paths)
81
+
82
+ cmd = %Q[bundle exec cucumber #{args} --require #{runner.test_dir} -- #{stringify_test_file_paths}]
83
+
84
+ Kernel.system(cmd)
85
+
86
+ # it must be set here so when we call next time above cmd we won't run again:
87
+ # KnapsackPro::Hooks::Queue.call_before_queue
88
+ # which is defined in lib/knapsack_pro/adapters/cucumber_adapter.rb
89
+ ENV['KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED'] = 'true'
90
+
91
+ $?.exitstatus
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -1,3 +1,3 @@
1
1
  module KnapsackPro
2
- VERSION = '1.11.0'
2
+ VERSION = '1.12.0'
3
3
  end
data/lib/knapsack_pro.rb CHANGED
@@ -64,6 +64,7 @@ require_relative 'knapsack_pro/runners/test_unit_runner'
64
64
  require_relative 'knapsack_pro/runners/spinach_runner'
65
65
  require_relative 'knapsack_pro/runners/queue/base_runner'
66
66
  require_relative 'knapsack_pro/runners/queue/rspec_runner'
67
+ require_relative 'knapsack_pro/runners/queue/cucumber_runner'
67
68
  require_relative 'knapsack_pro/runners/queue/minitest_runner'
68
69
  require_relative 'knapsack_pro/crypto/encryptor'
69
70
  require_relative 'knapsack_pro/crypto/branch_encryptor'
@@ -0,0 +1,9 @@
1
+ require 'knapsack_pro'
2
+
3
+ namespace :knapsack_pro do
4
+ namespace :queue do
5
+ task :cucumber, [:cucumber_args] do |_, args|
6
+ KnapsackPro::Runners::Queue::CucumberRunner.run(args[:cucumber_args])
7
+ end
8
+ end
9
+ end
@@ -168,5 +168,52 @@ describe KnapsackPro::Adapters::CucumberAdapter do
168
168
  end
169
169
  end
170
170
  end
171
+
172
+ describe '#bind_before_queue_hook' do
173
+ let(:block) { double }
174
+ let(:scenario) { double(:scenario) }
175
+
176
+ context 'when KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED is not set' do
177
+ before { stub_const("ENV", {}) }
178
+
179
+ it do
180
+ expect(subject).to receive(:Around).and_yield(scenario, block)
181
+
182
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_before_queue)
183
+ expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED', 'true')
184
+
185
+ expect(block).to receive(:call)
186
+
187
+ subject.bind_before_queue_hook
188
+ end
189
+ end
190
+
191
+ context 'when KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED is set' do
192
+ before { stub_const("ENV", { 'KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED' => 'true' }) }
193
+
194
+ it do
195
+ expect(subject).to receive(:Around).and_yield(scenario, block)
196
+
197
+ expect(KnapsackPro::Hooks::Queue).not_to receive(:call_before_queue)
198
+
199
+ expect(block).to receive(:call)
200
+
201
+ subject.bind_before_queue_hook
202
+ end
203
+ end
204
+ end
205
+
206
+ describe '#bind_queue_mode' do
207
+ it do
208
+ expect(subject).to receive(:bind_before_queue_hook)
209
+ expect(subject).to receive(:bind_time_tracker)
210
+
211
+ expect(::Kernel).to receive(:at_exit).and_yield
212
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_subset_queue)
213
+ expect(KnapsackPro::Report).to receive(:save_subset_queue_to_file)
214
+
215
+ subject.bind_queue_mode
216
+ end
217
+ end
171
218
  end
172
219
  end
@@ -103,7 +103,7 @@ describe KnapsackPro::Report do
103
103
  expect(KnapsackPro).to receive(:logger).exactly(4).and_return(logger)
104
104
  expect(logger).to receive(:warn).with('2 test files were executed on this CI node but the recorded time was lost due to:')
105
105
  expect(logger).to receive(:warn).with('1. Probably you have a code (i.e. RSpec hooks) that clears tmp directory in your project. Please ensure you do not remove the content of tmp/knapsack_pro/queue/ directory between tests run.')
106
- expect(logger).to receive(:warn).with('2. Another reason might be that you forgot to add Knapsack::Adapters::RspecAdapter.bind in your rails_helper.rb or spec_helper.rb. Please follow the installation guide again: https://docs.knapsackpro.com/integration/')
106
+ expect(logger).to receive(:warn).with('2. Another reason might be that you forgot to add Knapsack::Adapters::RSpecAdapter.bind in your rails_helper.rb or spec_helper.rb. Please follow the installation guide again: https://docs.knapsackpro.com/integration/')
107
107
  expect(logger).to receive(:warn).with('3. All your tests are empty test files, are pending tests or have syntax error and could not be executed hence no measured time execution by knapsack_pro.')
108
108
 
109
109
  expect(described_class).to receive(:create_build_subset).with(
@@ -0,0 +1,168 @@
1
+ describe KnapsackPro::Runners::Queue::CucumberRunner do
2
+ describe '.run' do
3
+ let(:test_suite_token_cucumber) { 'fake-token' }
4
+ let(:queue_id) { 'fake-queue-id' }
5
+ let(:test_dir) { 'fake-features-dir' }
6
+ let(:runner) do
7
+ instance_double(described_class, test_dir: test_dir)
8
+ end
9
+
10
+ subject { described_class.run(args) }
11
+
12
+ before do
13
+ expect(described_class).to receive(:require).with('cucumber/rake/task')
14
+
15
+ expect(KnapsackPro::Config::Env).to receive(:test_suite_token_cucumber).and_return(test_suite_token_cucumber)
16
+ expect(KnapsackPro::Config::EnvGenerator).to receive(:set_queue_id).and_return(queue_id)
17
+
18
+ expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_TEST_SUITE_TOKEN', test_suite_token_cucumber)
19
+ expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_QUEUE_RECORDING_ENABLED', 'true')
20
+ expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_QUEUE_ID', queue_id)
21
+
22
+ expect(described_class).to receive(:new).with(KnapsackPro::Adapters::CucumberAdapter).and_return(runner)
23
+ end
24
+
25
+ context 'when args provided' do
26
+ let(:args) { '--retry 5 --no-strict-flaky' }
27
+
28
+ it do
29
+ expected_exitstatus = 0
30
+ expected_accumulator = {
31
+ status: :completed,
32
+ exitstatus: expected_exitstatus
33
+ }
34
+ accumulator = {
35
+ status: :next,
36
+ runner: runner,
37
+ can_initialize_queue: true,
38
+ args: args,
39
+ exitstatus: 0,
40
+ all_test_file_paths: [],
41
+ }
42
+ expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
43
+
44
+ expect(Kernel).to receive(:exit).with(expected_exitstatus)
45
+
46
+ subject
47
+ end
48
+ end
49
+
50
+ context 'when args not provided' do
51
+ let(:args) { nil }
52
+
53
+ it do
54
+ expected_exitstatus = 0
55
+ expected_accumulator = {
56
+ status: :completed,
57
+ exitstatus: expected_exitstatus
58
+ }
59
+ accumulator = {
60
+ status: :next,
61
+ runner: runner,
62
+ can_initialize_queue: true,
63
+ args: nil,
64
+ exitstatus: 0,
65
+ all_test_file_paths: [],
66
+ }
67
+ expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
68
+
69
+ expect(Kernel).to receive(:exit).with(expected_exitstatus)
70
+
71
+ subject
72
+ end
73
+ end
74
+ end
75
+
76
+ describe '.run_tests' do
77
+ let(:test_dir) { 'fake-features-dir' }
78
+ let(:runner) do
79
+ instance_double(described_class, test_dir: test_dir)
80
+ end
81
+ let(:can_initialize_queue) { double(:can_initialize_queue) }
82
+ let(:args) { '--retry 5 --no-strict-flaky' }
83
+ let(:exitstatus) { 0 }
84
+ let(:all_test_file_paths) { [] }
85
+ let(:accumulator) do
86
+ {
87
+ runner: runner,
88
+ can_initialize_queue: can_initialize_queue,
89
+ args: args,
90
+ exitstatus: exitstatus,
91
+ all_test_file_paths: all_test_file_paths,
92
+ }
93
+ end
94
+
95
+ subject { described_class.run_tests(accumulator) }
96
+
97
+ before do
98
+ expect(runner).to receive(:test_file_paths).with(can_initialize_queue: can_initialize_queue, executed_test_files: all_test_file_paths).and_return(test_file_paths)
99
+ end
100
+
101
+ context 'when test files exist' do
102
+ let(:test_file_paths) { ['features/a.feature', 'features/b.feature'] }
103
+
104
+ before do
105
+ subset_queue_id = 'fake-subset-queue-id'
106
+ expect(KnapsackPro::Config::EnvGenerator).to receive(:set_subset_queue_id).and_return(subset_queue_id)
107
+
108
+ expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_SUBSET_QUEUE_ID', subset_queue_id)
109
+
110
+ tracker = instance_double(KnapsackPro::Tracker)
111
+ expect(KnapsackPro).to receive(:tracker).twice.and_return(tracker)
112
+ expect(tracker).to receive(:reset!)
113
+ expect(tracker).to receive(:set_prerun_tests).with(test_file_paths)
114
+
115
+ # .cucumber_run
116
+ expect(Kernel).to receive(:system).with('bundle exec cucumber --retry 5 --no-strict-flaky --require fake-features-dir -- "features/a.feature" "features/b.feature"')
117
+
118
+ expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED', 'true')
119
+
120
+ expect($?).to receive(:exitstatus).and_return(exitstatus)
121
+ end
122
+
123
+ context 'when tests are passing' do
124
+ let(:exitstatus) { 0 }
125
+
126
+ it 'returns exit code 0' do
127
+ expect(subject).to eq({
128
+ status: :next,
129
+ runner: runner,
130
+ can_initialize_queue: false,
131
+ args: args,
132
+ exitstatus: exitstatus,
133
+ all_test_file_paths: test_file_paths,
134
+ })
135
+ end
136
+ end
137
+
138
+ context 'when tests are failing' do
139
+ let(:exitstatus) { 1 }
140
+
141
+ it 'returns exit code 1' do
142
+ expect(subject).to eq({
143
+ status: :next,
144
+ runner: runner,
145
+ can_initialize_queue: false,
146
+ args: args,
147
+ exitstatus: 1, # tests failed
148
+ all_test_file_paths: test_file_paths,
149
+ })
150
+ end
151
+ end
152
+ end
153
+
154
+ context "when test files don't exist" do
155
+ let(:test_file_paths) { [] }
156
+
157
+ it 'returns exit code 0' do
158
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
159
+ expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
160
+
161
+ expect(subject).to eq({
162
+ status: :completed,
163
+ exitstatus: exitstatus,
164
+ })
165
+ end
166
+ end
167
+ end
168
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knapsack_pro
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.0
4
+ version: 1.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-17 00:00:00.000000000 Z
11
+ date: 2019-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -270,6 +270,7 @@ files:
270
270
  - lib/knapsack_pro/runners/cucumber_runner.rb
271
271
  - lib/knapsack_pro/runners/minitest_runner.rb
272
272
  - lib/knapsack_pro/runners/queue/base_runner.rb
273
+ - lib/knapsack_pro/runners/queue/cucumber_runner.rb
273
274
  - lib/knapsack_pro/runners/queue/minitest_runner.rb
274
275
  - lib/knapsack_pro/runners/queue/rspec_runner.rb
275
276
  - lib/knapsack_pro/runners/rspec_runner.rb
@@ -288,6 +289,7 @@ files:
288
289
  - lib/tasks/encrypted_branch_names.rake
289
290
  - lib/tasks/encrypted_test_file_names.rake
290
291
  - lib/tasks/minitest.rake
292
+ - lib/tasks/queue/cucumber.rake
291
293
  - lib/tasks/queue/minitest.rake
292
294
  - lib/tasks/queue/rspec.rake
293
295
  - lib/tasks/rspec.rake
@@ -349,6 +351,7 @@ files:
349
351
  - spec/knapsack_pro/runners/cucumber_runner_spec.rb
350
352
  - spec/knapsack_pro/runners/minitest_runner_spec.rb
351
353
  - spec/knapsack_pro/runners/queue/base_runner_spec.rb
354
+ - spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb
352
355
  - spec/knapsack_pro/runners/queue/minitest_runner_spec.rb
353
356
  - spec/knapsack_pro/runners/queue/rspec_runner_spec.rb
354
357
  - spec/knapsack_pro/runners/rspec_runner_spec.rb
@@ -459,6 +462,7 @@ test_files:
459
462
  - spec/knapsack_pro/runners/cucumber_runner_spec.rb
460
463
  - spec/knapsack_pro/runners/minitest_runner_spec.rb
461
464
  - spec/knapsack_pro/runners/queue/base_runner_spec.rb
465
+ - spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb
462
466
  - spec/knapsack_pro/runners/queue/minitest_runner_spec.rb
463
467
  - spec/knapsack_pro/runners/queue/rspec_runner_spec.rb
464
468
  - spec/knapsack_pro/runners/rspec_runner_spec.rb