knapsack_pro 0.53.0 → 0.54.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
- SHA1:
3
- metadata.gz: 159f31c8d3ff4a4ca650cab78612e3b91eaa22ff
4
- data.tar.gz: 70c7eab12ce5ebb4cca891e8354e1ac7552ab154
2
+ SHA256:
3
+ metadata.gz: 5ca270139eec1a9a068a6038deaa4670812226c1663dd1874d4db0ea74815ce7
4
+ data.tar.gz: 96e8ed4266180dacd9e0be2c7b5b2f5cd05ec28537d895e7c6d88989fc8b98b0
5
5
  SHA512:
6
- metadata.gz: 7d9b0f159b2f853cde6fbbf0a8abb3282d63069864f4f86c3d0e18b303618d97cc0d38f451888d06059dc01d58e9b0c485cad115a95262e0ba2caf44882cadad
7
- data.tar.gz: 88c0e5d94901e187d4881faaa89c87833fb358ab335504310aab079288480d9105493fd6f73f1fbd2ec974ddf9fc3e425185b2eadf6e20900f2e9d641ce21cfe
6
+ metadata.gz: 69b834636b9d84069f44e566fd6f6e4ed80f0a9a68202b57156421fd4d34b06ed6907429a3d59265f6c306bd7c537f3cd57e9d95b2a1e2421444970da7762385
7
+ data.tar.gz: 350e5c4346a395e00e7e5cc9dcbb0ba9c7f34143b17e4174cffea1b7b1ebde1517d6e02be40dde84103916165b080008df56209623b785e7c3b62317b8646e6b
@@ -0,0 +1,38 @@
1
+ # Ruby CircleCI 2.0 configuration file
2
+ #
3
+ # Check https://circleci.com/docs/2.0/language-ruby/ for more details
4
+ #
5
+ version: 2
6
+ jobs:
7
+ build:
8
+ parallelism: 1
9
+ docker:
10
+ # specify the version you desire here
11
+ - image: circleci/ruby:2.5.0
12
+ environment:
13
+ CODECLIMATE_REPO_TOKEN: b6626e682a8e97e0c5978febc92c3526792a2d018b41b8e1b52689da37fb7d92
14
+
15
+ working_directory: ~/knapsack_pro-ruby
16
+
17
+ steps:
18
+ - checkout
19
+
20
+ # Download and cache dependencies
21
+ - restore_cache:
22
+ keys:
23
+ - v2-dependencies-bundler-{{ checksum "knapsack_pro.gemspec" }}
24
+ # fallback to using the latest cache if no exact match is found
25
+ - v2-dependencies-bundler-
26
+
27
+ - run:
28
+ name: install ruby dependencies
29
+ command: |
30
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
31
+
32
+ - save_cache:
33
+ paths:
34
+ - ./vendor/bundle
35
+ key: v2-dependencies-bundler-{{ checksum "knapsack_pro.gemspec" }}
36
+
37
+ # run tests!
38
+ - run: bundle exec rspec spec
@@ -2,6 +2,14 @@
2
2
 
3
3
  * TODO
4
4
 
5
+ ### 0.54.0
6
+
7
+ * Add Queue Mode for Minitest
8
+
9
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/60
10
+
11
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v0.53.0...v0.54.0
12
+
5
13
  ### 0.53.0
6
14
 
7
15
  * Add support for Heroku CI environment variables.
data/README.md CHANGED
@@ -111,14 +111,17 @@ The knapsack_pro has also [queue mode](#queue-mode) to get an optimal test suite
111
111
  - [Common problems](#common-problems)
112
112
  - [Why I see API error commit_hash parameter is required?](#why-i-see-api-error-commit_hash-parameter-is-required)
113
113
  - [Why I see `LoadError: cannot load such file -- spec_helper`?](#why-i-see-loaderror-cannot-load-such-file----spec_helper)
114
+ - [Why my CI build fails when I use Test::Unit even when all tests passed?](#why-my-ci-build-fails-when-i-use-testunit-even-when-all-tests-passed)
114
115
  - [Queue Mode problems](#queue-mode-problems)
115
116
  - [Why when I use Queue Mode for RSpec then my tests fail?](#why-when-i-use-queue-mode-for-rspec-then-my-tests-fail)
117
+ - [Why when I use Queue Mode for RSpec then FactoryBot/FactoryGirl tests fail?](#why-when-i-use-queue-mode-for-rspec-then-factorybotfactorygirl-tests-fail)
116
118
  - [Why I don't see collected time execution data for my build in user dashboard?](#why-i-dont-see-collected-time-execution-data-for-my-build-in-user-dashboard)
117
119
  - [Why when I use Queue Mode for RSpec and test fails then I see multiple times info about failed test in RSpec result?](#why-when-i-use-queue-mode-for-rspec-and-test-fails-then-i-see-multiple-times-info-about-failed-test-in-rspec-result)
118
120
  - [Why when I use Queue Mode for RSpec then I see multiple times the same pending tests?](#why-when-i-use-queue-mode-for-rspec-then-i-see-multiple-times-the-same-pending-tests)
119
121
  - [Does in Queue Mode the RSpec is initialized many times that causes Rails load over and over again?](#does-in-queue-mode-the-rspec-is-initialized-many-times-that-causes-rails-load-over-and-over-again)
120
122
  - [Why my tests are executed twice in queue mode? Why CI node runs whole test suite again?](#why-my-tests-are-executed-twice-in-queue-mode-why-ci-node-runs-whole-test-suite-again)
121
123
  - [How to fix capybara-screenshot fail with `SystemStackError: stack level too deep` when using Queue Mode for RSpec?](#how-to-fix-capybara-screenshot-fail-with-systemstackerror-stack-level-too-deep-when-using-queue-mode-for-rspec)
124
+ - [Parallel tests Cucumber and RSpec with Cucumber failures exit CI node early leaving fewer CI nodes to finish RSpec Queue.](#parallel-tests-cucumber-and-rspec-with-cucumber-failures-exit-ci-node-early-leaving-fewer-ci-nodes-to-finish-rspec-queue)
122
125
  - [General questions](#general-questions)
123
126
  - [How to run tests for particular CI node in your development environment](#how-to-run-tests-for-particular-ci-node-in-your-development-environment)
124
127
  - [for knapack_pro regular mode](#for-knapack_pro-regular-mode)
@@ -141,6 +144,11 @@ The knapsack_pro has also [queue mode](#queue-mode) to get an optimal test suite
141
144
  - [How to run knapsack_pro with parallel_tests gem?](#how-to-run-knapsack_pro-with-parallel_tests-gem)
142
145
  - [How to retry failed tests (flaky tests)?](#how-to-retry-failed-tests-flaky-tests)
143
146
  - [How can I run tests from multiple directories?](#how-can-i-run-tests-from-multiple-directories)
147
+ - [Why I don't see all test files being recorded in user dashboard](#why-i-dont-see-all-test-files-being-recorded-in-user-dashboard)
148
+ - [Why when I use 2 different CI providers then not all test files are executed?](#why-when-i-use-2-different-ci-providers-then-not-all-test-files-are-executed)
149
+ - [How to run only RSpec feature tests or non feature tests?](#how-to-run-only-rspec-feature-tests-or-non-feature-tests)
150
+ - [How to use CodeClimate with knapsack_pro?](#how-to-use-codeclimate-with-knapsack_pro)
151
+ - [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)
144
152
  - [Questions around data usage and security](#questions-around-data-usage-and-security)
145
153
  - [What data is sent to your servers?](#what-data-is-sent-to-your-servers)
146
154
  - [How is that data secured?](#how-is-that-data-secured)
@@ -391,8 +399,12 @@ Please use a separate API token for queue mode from one used already for regular
391
399
 
392
400
  Use this command to run queue mode:
393
401
 
402
+ # RSpec
394
403
  bundle exec rake knapsack_pro:queue:rspec
395
404
 
405
+ # Minitest
406
+ bundle exec rake knapsack_pro:queue:minitest
407
+
396
408
  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:
397
409
 
398
410
  bundle exec rake "knapsack_pro:queue:rspec[--require rails_helper]"
@@ -400,7 +412,7 @@ If the above command fails then you may need to explicitly pass an argument to r
400
412
  Note: when you run queue mode command for the first time it might be slower.
401
413
  The second build should have a more optimal test suite split.
402
414
 
403
- Please ensure you have explicitly set `RAILS_ENV=test` on your CI nodes.
415
+ __Please ensure you have explicitly set `RAILS_ENV=test` on your CI nodes.__
404
416
 
405
417
  If you use the capybara-screenshot gem then please [follow this step](#how-to-fix-capybara-screenshot-fail-with-systemstackerror-stack-level-too-deep-when-using-queue-mode-for-rspec).
406
418
 
@@ -452,13 +464,21 @@ There might be some cached test suite splits for git commits you have run in pas
452
464
 
453
465
  Thanks to that when tests on one of your node failed you can retry the node with exactly the same subset of tests that were run on the node in the first place.
454
466
 
455
- Note when fixed queue split is enabled then you can run tests in a dynamic way only once for particular commit hash and a total number of nodes and for the same branch.
467
+ * Note when fixed queue split is enabled then you can run tests in a dynamic way only once for particular commit hash and a total number of nodes and for the same branch.
468
+
469
+ * When Knapsack Pro API server has already information about previous queue split then the information will be used. You will see at the beginning of the knapsack command the log with info that queue name is nil because it was not generated this time. You will get the list of all test files that were executed on the particular CI node in the past.
456
470
 
457
- When Knapsack Pro API server has already information about previous queue split then the information will be used. You will see at the beginning of the knapsack command the log with info that queue name is nil because it was not generated this time. You will get the list of all test files that were executed on the particular CI node in the past.
471
+ ```
472
+ [knapsack_pro] {"queue_name"=>nil, "test_files"=>[{"path"=>"spec/foo_spec.rb", "time_execution"=>1.23}]}
473
+ ```
458
474
 
459
- [knapsack_pro] {"queue_name"=>nil, "test_files"=>[{"path"=>"spec/foo_spec.rb", "time_execution"=>1.23}]}
475
+ * Knapsack Pro is fault-tolerant and can withstand possible CI instance preemptions (shut down) when you use highly affordable CI nodes like [Google Cloud Preemptible VMs](https://cloud.google.com/preemptible-vms/) or [Amazon EC2 Spot Instances](https://aws.amazon.com/ec2/spot/). When you retry failed CI node or when your CI provider will do auto retry then the knapsack_pro will run tests previosly served to CI node that failed. After that it will try to consume the test files from the Queue if there are remaining test files that were not yet executed. You will see in the logs info that you retry the tests if the `queue_name` has prefix `retry-dead-ci-node`:
460
476
 
461
- To [reproduce tests executed on CI node](#for-knapsack_pro-queue-mode) in development environment please see FAQ.
477
+ ```
478
+ [knapsack_pro] {"queue_name"=>"retry-dead-ci-node:queue-id", "test_files"=>[{"path"=>"spec/foo_spec.rb", "time_execution"=>1.23}]}
479
+ ```
480
+
481
+ * To [reproduce tests executed on CI node](#for-knapsack_pro-queue-mode) in development environment please see FAQ.
462
482
 
463
483
  #### KNAPSACK_PRO_MODIFY_DEFAULT_RSPEC_FORMATTERS (hide duplicated summary of pending and failed tests)
464
484
 
@@ -581,6 +601,7 @@ You can install knapsack_pro globally and use binary. For instance:
581
601
  $ knapsack_pro queue:rspec "--tag custom_tag_name --profile"
582
602
  $ knapsack_pro cucumber "--name feature"
583
603
  $ knapsack_pro minitest "--verbose --pride"
604
+ $ knapsack_pro queue:minitest "--verbose"
584
605
  $ knapsack_pro test_unit "--verbose"
585
606
  $ knapsack_pro spinach "--arg_name value"
586
607
 
@@ -698,6 +719,13 @@ Here is another example for CircleCI 2.0 platform.
698
719
  # export word is important here!
699
720
  export RAILS_ENV=test
700
721
  bundle exec rake "knapsack_pro:queue:rspec[--format documentation]"
722
+
723
+ - run:
724
+ name: Minitest via knapsack_pro Queue Mode
725
+ command: |
726
+ # export word is important here!
727
+ export RAILS_ENV=test
728
+ bundle exec rake "knapsack_pro:queue:minitest[--verbose]"
701
729
  ```
702
730
 
703
731
  Please remember to add additional containers for your project in CircleCI settings.
@@ -901,6 +929,8 @@ KNAPSACK_PRO_CI_NODE_TOTAL=2 KNAPSACK_PRO_CI_NODE_INDEX=1 bundle exec rake knaps
901
929
 
902
930
  Remember to add API tokens like `KNAPSACK_PRO_TEST_SUITE_TOKEN_CUCUMBER` and `KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC` to `Environment` page of your project settings in Codeship.
903
931
 
932
+ If you want to use Codeship retry single CI node feature to retry just failed tests on particular CI node then you should set [`KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true`](#knapsack_pro_fixed_queue_split-remember-queue-split-on-retry-ci-node).
933
+
904
934
  #### Info for Heroku CI users
905
935
 
906
936
  You can parallelize your tests on Heroku CI by configuring `app.json`.
@@ -1045,6 +1075,10 @@ When your tests fails with:
1045
1075
 
1046
1076
  then problem might be related to the fact you specified complex `KNAPSACK_PRO_TEST_FILE_PATTERN` and knapsack_pro gem cannot detect correct main test directory with spec_helper. You should set `KNAPSACK_PRO_TEST_DIR=spec`. Please [read also example](#how-can-i-run-tests-from-multiple-directories).
1047
1077
 
1078
+ #### Why my CI build fails when I use Test::Unit even when all tests passed?
1079
+
1080
+ Please ensure you are actually using only Test::Unit runner. You may use some hybrid of Test::Unit and Minitest. Ensure you are not loading Minitest.
1081
+
1048
1082
  #### Queue Mode problems
1049
1083
 
1050
1084
  ##### Why when I use Queue Mode for RSpec then my tests fail?
@@ -1057,6 +1091,39 @@ In that case you need to resolve failed tests in a way that allows RSpec to run
1057
1091
 
1058
1092
  You can learn more about [recent RSpec team changes](https://github.com/KnapsackPro/knapsack_pro-ruby/pull/42) that was backported into knapsack_pro.
1059
1093
 
1094
+ ##### Why when I use Queue Mode for RSpec then FactoryBot/FactoryGirl tests fail?
1095
+
1096
+ You can use [knapsack_pro binary](#knapsack-pro-binary) instead of rake task version to solve problem:
1097
+
1098
+ ```
1099
+ # knapsack_pro binary for Queue Mode
1100
+ $ bundle exec knapsack_pro queue:rspec
1101
+ ```
1102
+
1103
+ Other solution is to check if your factories for FactoryBot/FactoryGirl use the same methods as Rake DSL and remove problematic part of the code.
1104
+
1105
+ The use of implicit association `task` can cause a problem.
1106
+
1107
+ ```ruby
1108
+ # won't work in knapsack_pro Queue Mode
1109
+ FactoryBot.define do
1110
+ factory :assignment do
1111
+ task
1112
+ end
1113
+ end
1114
+ ```
1115
+
1116
+ Workaround is to replace `task` with explicit association:
1117
+
1118
+ ```ruby
1119
+ # this will work in knapack_pro Queue Mode
1120
+ FactoryBot.define do
1121
+ factory :assignment do
1122
+ association :task
1123
+ end
1124
+ end
1125
+ ```
1126
+
1060
1127
  ##### Why I don't see collected time execution data for my build in user dashboard?
1061
1128
 
1062
1129
  If you go to [user dashboard](https://knapsackpro.com/dashboard) and open `Build metrics` for your API token and you open build for your last git commit you should see there info about collected time execution data from all CI nodes. If you don't see collected time execution data for CI nodes then please ensure:
@@ -1106,6 +1173,23 @@ end
1106
1173
 
1107
1174
  Here is [fix PR](https://github.com/mattheworiordan/capybara-screenshot/pull/205) to official capybara-screenshot repository and the explanation of the problem.
1108
1175
 
1176
+ ##### Parallel tests Cucumber and RSpec with Cucumber failures exit CI node early leaving fewer CI nodes to finish RSpec Queue.
1177
+
1178
+ If you run tests in 2 steps like:
1179
+
1180
+ * Step 1. `bundle exec rake knapsack_pro:cucumber` (regular mode)
1181
+ * Step 2. `bundle exec rake knapsack_pro:queue:rspec` (queue mode)
1182
+
1183
+ and your CI provider is configured to fail fast when one of the steps fails then in the case when the first step with Cucumber fails on one of CI nodes then the second step with RSpec in Queue Mode won't start on the CI node that failed fast.
1184
+
1185
+ It means the other CI nodes that will run the second step for RSpec in Queue Mode will consume the whole RSpec Queue so your whole CI build will take more than typical CI build when all Cucumber tests are green.
1186
+
1187
+ You should configure your CI provider to not fail fast the Cucumber step.
1188
+
1189
+ CI providers tips:
1190
+
1191
+ * If you use CircleCI 2.0 you can use `when=always` flag. Read more [here](https://discuss.circleci.com/t/parallel-tests-cuc-rspec-w-failures-exit-early-leaving-less-workers-to-finish/18081).
1192
+
1109
1193
  ### General questions
1110
1194
 
1111
1195
  #### How to run tests for particular CI node in your development environment
@@ -1537,6 +1621,82 @@ require_relative 'spec_helper'
1537
1621
  require 'spec_helper'
1538
1622
  ```
1539
1623
 
1624
+ #### Why I don't see all test files being recorded in user dashboard
1625
+
1626
+ If you open `Build metrics` for particular API token at [user dashboard](https://knapsackpro.com/dashboard) and you don't see all time execution data recorded for all test files then you should know that knapsack_pro does not track test files with empty content or when the test file contains only pending tests.
1627
+
1628
+ The test files with pending tests are executed so you will see it in RSpec output but just not recorded in Knapsack Pro API because there is nothing to record time for.
1629
+
1630
+ #### Why when I use 2 different CI providers then not all test files are executed?
1631
+
1632
+ Please ensure you use 2 different API token per test suite. If you use 2 CI providers for instance CircleCI and TravisCI at the same time and you run the RSpec test suite then you need to have separate API token for RSpec executed on CircleCI and a separate API token for RSpec test suite executed on the TravisCI.
1633
+
1634
+ #### How to run only RSpec feature tests or non feature tests?
1635
+
1636
+ **Option 1: RSpec tags**
1637
+
1638
+ You can run just feature tests this way. You need to generate a separate API token for it.
1639
+
1640
+ ```
1641
+ KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=$API_TOKEN_FOR_FEATURE_TESTS bundle exec rake "knapsack_pro:queue:rspec[--tag type:feature]"
1642
+ ```
1643
+
1644
+ If you would like to run only non feature tests then use negation `~type:feature`:
1645
+
1646
+ ```
1647
+ KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=$API_TOKEN_FOR_NON_FEATURE_TESTS bundle exec rake "knapsack_pro:queue:rspec[--tag ~type:feature]"
1648
+ ```
1649
+
1650
+ Note above examples are for knapack_pro Queue Mode and when you will run tests you may notice that all test files are run by RSpec but only tests specified by tag like `tag type:feature` will be executed. Basically RSpec will just load all files but run just specified tags.
1651
+
1652
+ **Option 2: specify directory pattern**
1653
+
1654
+ Another approach is to explicitly specify which files should be executed.
1655
+
1656
+ Run all specs from multiple directories except `spec/features` directory which is not listed below.
1657
+ If you would like to run additional directory please add it after comma in `KNAPSACK_PRO_TEST_FILE_PATTERN`.
1658
+ Ensure the list of directories match your spec directory structure.
1659
+
1660
+ ```
1661
+ KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=$API_TOKEN_FOR_NON_FEATURE_TESTS \
1662
+ KNAPSACK_PRO_TEST_DIR=spec \
1663
+ KNAPSACK_PRO_TEST_FILE_PATTERN="{spec/*_spec.rb,spec/controllers/**/*_spec.rb,spec/mailers/**/*_spec.rb,spec/models/**/*_spec.rb,spec/presenters/**/*_spec.rb,spec/requests/**/*_spec.rb,spec/routing/**/*_spec.rb,spec/services/**/*_spec.rb,spec/workers/**/*_spec.rb,spec/jobs/**/*_spec.rb}" \
1664
+ bundle exec rake knapsack_pro:queue:rspec
1665
+ ```
1666
+
1667
+ When you would like to run tests only from `spec/features` directory then run:
1668
+
1669
+ ```
1670
+ KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=$API_TOKEN_FOR_FEATURE_TESTS \
1671
+ KNAPSACK_PRO_TEST_DIR=spec \
1672
+ KNAPSACK_PRO_TEST_FILE_PATTERN="spec/features/**{,/*/**}/*_spec.rb" \
1673
+ bundle exec rake knapsack_pro:queue:rspec
1674
+ ```
1675
+
1676
+ #### How to use CodeClimate with knapsack_pro?
1677
+
1678
+ You can check CodeClimate docs about [parallel and multiple test suites](https://docs.codeclimate.com/docs/configuring-test-coverage#section-parallel-and-multiple-test-suites).
1679
+
1680
+ #### How to run knapsack_pro only on a few parallel CI nodes instead of all?
1681
+
1682
+ You may want to run knapack_pro only on a few CI nodes when you would like to run a different job on other CI nodes.
1683
+
1684
+ For instance, you have 3 parallel CI nodes. You would like to run knapack_pro only on two CI nodes. The last CI node you want to use for the different job like running linters etc.
1685
+
1686
+ In such case, you can override the number of total CI nodes available by your CI provider. For instance, Heroku CI provider exposes in ENV variables `CI_NODE_TOTAL=3`.
1687
+
1688
+ You can then run knapsack_pro command this way on the first and the second CI node:
1689
+
1690
+ ```
1691
+ KNAPSACK_PRO_CI_NODE_TOTAL=$((CI_NODE_TOTAL-1)) bundle exec rake knapsack_pro:rspec
1692
+ ```
1693
+
1694
+ We decrease the number of CI node total by 1 that knapack_pro can see. This way you can run tests with knapsack_pro only on two CI nodes.
1695
+ On the 3rd CI node, you can run other things like linters etc.
1696
+
1697
+ 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
1698
+ or preview the [ENV variables that knapack_pro can read](https://github.com/KnapsackPro/knapsack_pro-ruby/tree/master/lib/knapsack_pro/config/ci) for supported CI providers.
1699
+
1540
1700
  ### Questions around data usage and security
1541
1701
 
1542
1702
  #### What data is sent to your servers?
@@ -10,6 +10,7 @@ MAP = {
10
10
  'queue:rspec' => KnapsackPro::Runners::Queue::RSpecRunner,
11
11
  'cucumber' => KnapsackPro::Runners::CucumberRunner,
12
12
  'minitest' => KnapsackPro::Runners::MinitestRunner,
13
+ 'queue:minitest' => KnapsackPro::Runners::Queue::MinitestRunner,
13
14
  'test_unit' => KnapsackPro::Runners::TestUnitRunner,
14
15
  'spinach' => KnapsackPro::Runners::SpinachRunner,
15
16
  }
@@ -60,6 +60,7 @@ require_relative 'knapsack_pro/runners/test_unit_runner'
60
60
  require_relative 'knapsack_pro/runners/spinach_runner'
61
61
  require_relative 'knapsack_pro/runners/queue/base_runner'
62
62
  require_relative 'knapsack_pro/runners/queue/rspec_runner'
63
+ require_relative 'knapsack_pro/runners/queue/minitest_runner'
63
64
  require_relative 'knapsack_pro/crypto/encryptor'
64
65
  require_relative 'knapsack_pro/crypto/branch_encryptor'
65
66
  require_relative 'knapsack_pro/crypto/decryptor'
@@ -19,10 +19,7 @@ module KnapsackPro
19
19
 
20
20
  if KnapsackPro::Config::Env.queue_recording_enabled?
21
21
  KnapsackPro.logger.debug('Test suite time execution queue recording enabled.')
22
- bind_tracker_reset
23
- bind_before_queue_hook
24
- bind_time_tracker
25
- bind_save_queue_report
22
+ bind_queue_mode
26
23
  end
27
24
  end
28
25
 
@@ -45,6 +42,13 @@ module KnapsackPro
45
42
  def bind_before_queue_hook
46
43
  raise NotImplementedError
47
44
  end
45
+
46
+ def bind_queue_mode
47
+ bind_tracker_reset
48
+ bind_before_queue_hook
49
+ bind_time_tracker
50
+ bind_save_queue_report
51
+ end
48
52
  end
49
53
  end
50
54
  end
@@ -54,6 +54,34 @@ module KnapsackPro
54
54
  @@parent_of_test_dir = File.expand_path('../', test_dir_path)
55
55
  end
56
56
 
57
+ module BindQueueModeMinitestPlugin
58
+ def before_setup
59
+ super
60
+
61
+ unless ENV['KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED']
62
+ KnapsackPro::Hooks::Queue.call_before_queue
63
+ ENV['KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED'] = 'true'
64
+ end
65
+
66
+ KnapsackPro.tracker.current_test_path = KnapsackPro::Adapters::MinitestAdapter.test_path(self)
67
+ KnapsackPro.tracker.start_timer
68
+ end
69
+
70
+ def after_teardown
71
+ KnapsackPro.tracker.stop_timer
72
+
73
+ super
74
+ end
75
+ end
76
+
77
+ def bind_queue_mode
78
+ ::Minitest::Test.send(:include, BindQueueModeMinitestPlugin)
79
+
80
+ add_post_run_callback do
81
+ KnapsackPro.logger.debug(KnapsackPro::Presenter.global_time)
82
+ end
83
+ end
84
+
57
85
  private
58
86
 
59
87
  def add_post_run_callback(&block)
@@ -0,0 +1,70 @@
1
+ module KnapsackPro
2
+ module Runners
3
+ module Queue
4
+ class MinitestRunner < BaseRunner
5
+ def self.run(args)
6
+ require 'minitest'
7
+
8
+ ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_minitest
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::MinitestAdapter)
13
+
14
+ # Add test_dir to load path to make work:
15
+ # require 'test_helper'
16
+ # in test files.
17
+ $LOAD_PATH.unshift(runner.test_dir)
18
+
19
+ cli_args = (args || '').split
20
+ run_tests(runner, true, cli_args, 0, [])
21
+ end
22
+
23
+ def self.run_tests(runner, can_initialize_queue, args, exitstatus, all_test_file_paths)
24
+ test_file_paths = runner.test_file_paths(
25
+ can_initialize_queue: can_initialize_queue,
26
+ executed_test_files: all_test_file_paths
27
+ )
28
+
29
+ if test_file_paths.empty?
30
+ KnapsackPro::Hooks::Queue.call_after_queue
31
+
32
+ KnapsackPro::Report.save_node_queue_to_api
33
+ exit(exitstatus)
34
+ else
35
+ subset_queue_id = KnapsackPro::Config::EnvGenerator.set_subset_queue_id
36
+ ENV['KNAPSACK_PRO_SUBSET_QUEUE_ID'] = subset_queue_id
37
+
38
+ KnapsackPro.tracker.reset!
39
+
40
+ all_test_file_paths += test_file_paths
41
+
42
+ result = minitest_run(runner, test_file_paths, args)
43
+ exitstatus = 1 unless result
44
+
45
+ KnapsackPro::Hooks::Queue.call_after_subset_queue
46
+
47
+ KnapsackPro::Report.save_subset_queue_to_file
48
+
49
+ run_tests(runner, false, args, exitstatus, all_test_file_paths)
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def self.minitest_run(runner, test_file_paths, args)
56
+ test_file_paths.each do |test_file_path|
57
+ require "./#{test_file_path}"
58
+ end
59
+
60
+ # duplicate args because Minitest modifies args
61
+ result = Minitest.run(args.dup)
62
+
63
+ Minitest::Runnable.reset
64
+
65
+ result
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,3 +1,3 @@
1
1
  module KnapsackPro
2
- VERSION = '0.53.0'
2
+ VERSION = '0.54.0'
3
3
  end
@@ -0,0 +1,9 @@
1
+ require 'knapsack_pro'
2
+
3
+ namespace :knapsack_pro do
4
+ namespace :queue do
5
+ task :minitest, [:minitest_args] do |_, args|
6
+ KnapsackPro::Runners::Queue::MinitestRunner.run(args[:minitest_args])
7
+ end
8
+ end
9
+ end
@@ -2,6 +2,10 @@ module FakeMinitest
2
2
  class Test < ::Minitest::Test
3
3
  include KnapsackPro::Adapters::MinitestAdapter::BindTimeTrackerMinitestPlugin
4
4
  end
5
+
6
+ class TestQueueMode < ::Minitest::Test
7
+ include KnapsackPro::Adapters::MinitestAdapter::BindQueueModeMinitestPlugin
8
+ end
5
9
  end
6
10
 
7
11
  describe KnapsackPro::Adapters::MinitestAdapter do
@@ -83,6 +87,47 @@ describe KnapsackPro::Adapters::MinitestAdapter do
83
87
  end
84
88
  end
85
89
 
90
+ describe 'BindQueueModeMinitestPlugin' do
91
+ let(:tracker) { instance_double(KnapsackPro::Tracker) }
92
+
93
+ subject { ::FakeMinitest::TestQueueMode.new }
94
+
95
+ before do
96
+ allow(KnapsackPro).to receive(:tracker).and_return(tracker)
97
+ end
98
+
99
+ describe '#before_setup' do
100
+ let(:file) { 'test/models/user_test.rb' }
101
+
102
+ before do
103
+ stub_const('ENV', {
104
+ 'KNAPSACK_PRO_BEFORE_QUEUE_HOOK_CALLED' => nil,
105
+ })
106
+ end
107
+
108
+ it do
109
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_before_queue).once
110
+
111
+ expect(described_class).to receive(:test_path).with(subject).twice.and_return(file)
112
+ expect(tracker).to receive(:current_test_path=).with(file).twice
113
+ expect(tracker).to receive(:start_timer).twice
114
+
115
+ subject.before_setup
116
+
117
+ # second call should not trigger KnapsackPro::Hooks::Queue.call_before_queue
118
+ subject.before_setup
119
+ end
120
+ end
121
+
122
+ describe '#after_teardown' do
123
+ it do
124
+ expect(tracker).to receive(:stop_timer)
125
+
126
+ subject.after_teardown
127
+ end
128
+ end
129
+ end
130
+
86
131
  describe 'bind methods' do
87
132
  describe '#bind_time_tracker' do
88
133
  let(:logger) { instance_double(Logger) }
@@ -110,6 +155,23 @@ describe KnapsackPro::Adapters::MinitestAdapter do
110
155
  subject.bind_save_report
111
156
  end
112
157
  end
158
+
159
+ describe '#bind_queue_mode' do
160
+ let(:logger) { instance_double(Logger) }
161
+ let(:global_time) { 'Global time: 01m 05s' }
162
+
163
+ it do
164
+ expect(::Minitest::Test).to receive(:send).with(:include, KnapsackPro::Adapters::MinitestAdapter::BindQueueModeMinitestPlugin)
165
+
166
+ expect(::Minitest).to receive(:after_run).and_yield
167
+
168
+ expect(KnapsackPro::Presenter).to receive(:global_time).and_return(global_time)
169
+ expect(KnapsackPro).to receive(:logger).and_return(logger)
170
+ expect(logger).to receive(:debug).with(global_time)
171
+
172
+ subject.bind_queue_mode
173
+ end
174
+ end
113
175
  end
114
176
 
115
177
  describe '#set_test_helper_path' do
@@ -627,10 +627,16 @@ describe KnapsackPro::Config::Env do
627
627
  allow(KnapsackPro::Config::CI::Buildkite).to receive_message_chain(:new, env_name).and_return(buildkite_env)
628
628
  end
629
629
 
630
- it { should eq circle_env }
630
+ context do
631
+ let(:buildkite_env) { nil }
632
+ let(:semaphore_env) { nil }
633
+
634
+ it { should eq circle_env }
635
+ end
631
636
 
632
637
  context do
633
638
  let(:circle_env) { nil }
639
+ let(:buildkite_env) { nil }
634
640
 
635
641
  it { should eq semaphore_env }
636
642
  end
@@ -0,0 +1,127 @@
1
+ describe KnapsackPro::Runners::Queue::MinitestRunner do
2
+ describe '.run' do
3
+ let(:test_suite_token_minitest) { 'fake-token' }
4
+ let(:queue_id) { 'fake-queue-id' }
5
+ let(:test_dir) { 'fake-test-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('minitest')
14
+
15
+ expect(KnapsackPro::Config::Env).to receive(:test_suite_token_minitest).and_return(test_suite_token_minitest)
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_minitest)
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::MinitestAdapter).and_return(runner)
23
+
24
+ expect($LOAD_PATH).to receive(:unshift).with(test_dir)
25
+ end
26
+
27
+ context 'when args provided' do
28
+ let(:args) { '--verbose --pride' }
29
+
30
+ it do
31
+ result = double
32
+ expect(described_class).to receive(:run_tests).with(runner, true, ['--verbose', '--pride'], 0, []).and_return(result)
33
+
34
+ expect(subject).to eq result
35
+ end
36
+ end
37
+
38
+ context 'when args not provided' do
39
+ let(:args) { nil }
40
+
41
+ it do
42
+ result = double
43
+ expect(described_class).to receive(:run_tests).with(runner, true, [], 0, []).and_return(result)
44
+
45
+ expect(subject).to eq result
46
+ end
47
+ end
48
+ end
49
+
50
+ describe '.run_tests' do
51
+ let(:runner) { instance_double(described_class) }
52
+ let(:can_initialize_queue) { double(:can_initialize_queue) }
53
+ let(:args) { ['--verbose', '--pride'] }
54
+ let(:exitstatus) { 0 }
55
+
56
+ subject { described_class.run_tests(runner, can_initialize_queue, args, exitstatus, []) }
57
+
58
+ before do
59
+ expect(runner).to receive(:test_file_paths).with(can_initialize_queue: can_initialize_queue, executed_test_files: []).and_return(test_file_paths)
60
+ end
61
+
62
+ context 'when test files exist' do
63
+ let(:test_file_paths) { ['a_test.rb', 'b_test.rb'] }
64
+
65
+ before do
66
+ subset_queue_id = 'fake-subset-queue-id'
67
+ expect(KnapsackPro::Config::EnvGenerator).to receive(:set_subset_queue_id).and_return(subset_queue_id)
68
+
69
+ expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_SUBSET_QUEUE_ID', subset_queue_id)
70
+
71
+ expect(KnapsackPro).to receive_message_chain(:tracker, :reset!)
72
+
73
+ # .minitest_run
74
+ expect(described_class).to receive(:require).with('./a_test.rb')
75
+ expect(described_class).to receive(:require).with('./b_test.rb')
76
+
77
+ expect(Minitest).to receive(:run).with(args).and_return(is_tests_green)
78
+
79
+ expect(Minitest::Runnable).to receive(:reset)
80
+
81
+
82
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_subset_queue)
83
+
84
+ expect(KnapsackPro::Report).to receive(:save_subset_queue_to_file)
85
+
86
+ # second call of run_tests because of recursion
87
+ expect(runner).to receive(:test_file_paths).with(can_initialize_queue: false, executed_test_files: ['a_test.rb', 'b_test.rb']).and_return([])
88
+ end
89
+
90
+ context 'when tests are passing' do
91
+ let(:is_tests_green) { true }
92
+
93
+ it 'returns exit code 0' do
94
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
95
+ expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
96
+ expect(described_class).to receive(:exit).with(0)
97
+
98
+ subject
99
+ end
100
+ end
101
+
102
+ context 'when tests are failing' do
103
+ let(:is_tests_green) { false }
104
+
105
+ it 'returns exit code 1' do
106
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
107
+ expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
108
+ expect(described_class).to receive(:exit).with(1)
109
+
110
+ subject
111
+ end
112
+ end
113
+ end
114
+
115
+ context "when test files don't exist" do
116
+ let(:test_file_paths) { [] }
117
+
118
+ it 'returns exit code 0' do
119
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
120
+ expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
121
+ expect(described_class).to receive(:exit).with(0)
122
+
123
+ subject
124
+ end
125
+ end
126
+ end
127
+ end
@@ -2,7 +2,7 @@ describe KnapsackPro do
2
2
  describe '.root' do
3
3
  subject { described_class.root }
4
4
 
5
- it { expect(subject).to match 'knapsack' }
5
+ it { expect(subject).to match 'knapsack_pro-ruby' }
6
6
  end
7
7
 
8
8
  describe '.logger' do
@@ -5,8 +5,14 @@ module Minitest
5
5
  def after_teardown; end
6
6
  end
7
7
 
8
+ class Runnable
9
+ def self.reset; end
10
+ end
11
+
8
12
  # https://github.com/seattlerb/minitest/blob/master/lib/minitest.rb
9
13
  def self.after_run(&block)
10
14
  block.call
11
15
  end
16
+
17
+ def self.run(args); end
12
18
  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: 0.53.0
4
+ version: 0.54.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-11 00:00:00.000000000 Z
11
+ date: 2018-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -207,6 +207,7 @@ executables:
207
207
  extensions: []
208
208
  extra_rdoc_files: []
209
209
  files:
210
+ - ".circleci/config.yml"
210
211
  - ".gitignore"
211
212
  - ".rspec"
212
213
  - CHANGELOG.md
@@ -215,7 +216,6 @@ files:
215
216
  - README.md
216
217
  - Rakefile
217
218
  - bin/knapsack_pro
218
- - circle.yml
219
219
  - knapsack_pro.gemspec
220
220
  - lib/knapsack_pro.rb
221
221
  - lib/knapsack_pro/adapters/base_adapter.rb
@@ -266,6 +266,7 @@ files:
266
266
  - lib/knapsack_pro/runners/cucumber_runner.rb
267
267
  - lib/knapsack_pro/runners/minitest_runner.rb
268
268
  - lib/knapsack_pro/runners/queue/base_runner.rb
269
+ - lib/knapsack_pro/runners/queue/minitest_runner.rb
269
270
  - lib/knapsack_pro/runners/queue/rspec_runner.rb
270
271
  - lib/knapsack_pro/runners/rspec_runner.rb
271
272
  - lib/knapsack_pro/runners/spinach_runner.rb
@@ -283,6 +284,7 @@ files:
283
284
  - lib/tasks/encrypted_branch_names.rake
284
285
  - lib/tasks/encrypted_test_file_names.rake
285
286
  - lib/tasks/minitest.rake
287
+ - lib/tasks/queue/minitest.rake
286
288
  - lib/tasks/queue/rspec.rake
287
289
  - lib/tasks/rspec.rake
288
290
  - lib/tasks/salt.rake
@@ -339,6 +341,7 @@ files:
339
341
  - spec/knapsack_pro/runners/cucumber_runner_spec.rb
340
342
  - spec/knapsack_pro/runners/minitest_runner_spec.rb
341
343
  - spec/knapsack_pro/runners/queue/base_runner_spec.rb
344
+ - spec/knapsack_pro/runners/queue/minitest_runner_spec.rb
342
345
  - spec/knapsack_pro/runners/queue/rspec_runner_spec.rb
343
346
  - spec/knapsack_pro/runners/rspec_runner_spec.rb
344
347
  - spec/knapsack_pro/runners/spinach_runner_spec.rb
@@ -383,7 +386,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
383
386
  version: '0'
384
387
  requirements: []
385
388
  rubyforge_project:
386
- rubygems_version: 2.6.13
389
+ rubygems_version: 2.7.6
387
390
  signing_key:
388
391
  specification_version: 4
389
392
  summary: Knapsack Pro splits tests across CI nodes and makes sure that tests will
@@ -440,6 +443,7 @@ test_files:
440
443
  - spec/knapsack_pro/runners/cucumber_runner_spec.rb
441
444
  - spec/knapsack_pro/runners/minitest_runner_spec.rb
442
445
  - spec/knapsack_pro/runners/queue/base_runner_spec.rb
446
+ - spec/knapsack_pro/runners/queue/minitest_runner_spec.rb
443
447
  - spec/knapsack_pro/runners/queue/rspec_runner_spec.rb
444
448
  - spec/knapsack_pro/runners/rspec_runner_spec.rb
445
449
  - spec/knapsack_pro/runners/spinach_runner_spec.rb
data/circle.yml DELETED
@@ -1,12 +0,0 @@
1
- machine:
2
- ruby:
3
- version: 2.4.0
4
- environment:
5
- CODECLIMATE_REPO_TOKEN: b6626e682a8e97e0c5978febc92c3526792a2d018b41b8e1b52689da37fb7d92
6
- test:
7
- override:
8
- # Specify command explicitly because CircleCI 1.0 adds arguments to RSpec
9
- # $ bundle exec rspec "--color --require spec_helper --format documentation" "" "spec"
10
- # and this cause error because in tests we load test-unit gem that tries to parse
11
- # the unknown arguments.
12
- - bundle exec rspec spec