knapsack_pro 0.27.0 → 0.28.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
  SHA1:
3
- metadata.gz: aeedb148388f2fda48884dbd34b294419fb55711
4
- data.tar.gz: 43a1a930c3e5a6703719d38a7dfff0ac3131fed8
3
+ metadata.gz: 558ebb63c8dd85721ac6b3b0fd3a4ec13a84727f
4
+ data.tar.gz: d28a11954c0412babd8f6de1f1d1c9171f371d6c
5
5
  SHA512:
6
- metadata.gz: cf278d4eecf850091463ad6ae7591e91c6993e7e82aa0a0d5b0f21beb6c0b25ef03ec742bb9e116b0b89861e52fa40be64aafd8d6e403459294ffae6cc7aec03
7
- data.tar.gz: 7cf8746554c01f34b7a6570f7d952574bcd819cae080244596d99d29df5133468874071310be3018b834a6d052a9683c48bea5d111cef162d682843b0fa2c41c
6
+ metadata.gz: e31031c889f546e3fa8d19c719cf6c3ddf9cf8e76c5728c915959e05e02e3762577a8aa06bb3d3434e9d308a0c4705b5d395f3eed6368d10fe6cfbc449cefc22
7
+ data.tar.gz: ce06127801cc30c4d53a53e3566dfebc262b3b7d8339a3ab330b21fae49e26e521b1528c1cc08affa6c295dd2167497f39ea1405e6c187898f9d96a9d3300c94
data/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  * TODO
4
4
 
5
+ ### 0.28.0
6
+
7
+ * Show at the end of `knapsack_pro:queue:rspec` command the example how to run all tests executed for the CI node in the development environment.
8
+ * Show for each intermediate request to Knapsack Pro API queue how to run a subset of tests fetched from API.
9
+
10
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v0.27.0...v0.28.0
11
+
5
12
  ### 0.27.0
6
13
 
7
14
  * Save build subset to API even when no test files were executed on CI node. Add warnings to notify why the test files were not executed on CI node in particular mode: regular or queue mode.
data/README.md CHANGED
@@ -109,6 +109,7 @@ The knapsack_pro has also [queue mode](#queue-mode) to get most optimal test sui
109
109
  - [How is that data secured?](#how-is-that-data-secured)
110
110
  - [Who has access to the data?](#who-has-access-to-the-data)
111
111
  - [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)
112
+ - [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)
112
113
  - [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)
113
114
  - [Gem tests](#gem-tests)
114
115
  - [Spec](#spec)
@@ -347,17 +348,25 @@ There might be some cached test suite splits for git commits you run in past for
347
348
 
348
349
  * If you are not using one of [supported CI providers](#supported-ci-providers) then please note that knapsack_pro gem doesn't know what is CI build ID in order to generated queue for particular CI build. This may result in two different CI builds taking tests from the same queue when CI builds are running at the same time against the same git commit.
349
350
 
350
- To avoid this you can specify unique `KNAPSACK_PRO_CI_NODE_BUILD_ID` environment variable for each CI build. This mean that each CI node that is part of particular CI build should have the same value for `KNAPSACK_PRO_CI_NODE_BUILD_ID`.
351
+ To avoid this you should specify unique `KNAPSACK_PRO_CI_NODE_BUILD_ID` environment variable for each CI build. This mean that each CI node that is part of particular CI build should have the same value for `KNAPSACK_PRO_CI_NODE_BUILD_ID`.
351
352
 
352
353
  * Note that in the Queue Mode by default you cannot retry the failed CI node with exactly the same subset of tests that were run on the CI node in the first place. It's possible in regular mode ([read more](#knapsack_pro_fixed_test_suite_splite-test-suite-split-based-on-seed)). If you want to have similar behavior in Queue Mode you need to explicitly [enable it](#knapsack_pro_fixed_queue_split-remember-queue-split-on-retry-ci-node).
353
354
 
354
355
  By default the Queue Mode works this way:
355
356
 
356
- * If you retry the failed build and your all CI nodes will start a new build then there will be a new dynamic test suite split across CI nodes.
357
+ * If you retry the failed build and your all CI nodes will start a new build then there will be a new dynamic test suite split across CI nodes. The reason is that the most of the CI providers schedule a new CI build with different ID when you retry CI build. They retry all CI nodes again. In that case you don't have to worry with below edge cases because the CI build ID will be different so a new queue will be initialized on Knapsack Pro API side and all retried CI node will connect to that queue.
357
358
 
358
- * Let's say one of the CI nodes failed and you retry just this single CI node while other CI nodes are still running. The retried CI node will be connected to the queue consumed by still running CI nodes.
359
+ Edge cases:
359
360
 
360
- * In the case when there are no running CI nodes then your retried CI node will initialize a new queue and it will run whole test suite from the queue because there will be no other CI nodes running connected to the queue. The order of tests on retried CI node will be different than on the first run.
361
+ * Let's say one of the CI nodes failed and you retry just this single CI node while other CI nodes are still running. Let's assume this retried CI node is part of the same CI build ID when you use supported CI provider or `KNAPSACK_PRO_CI_NODE_BUILD_ID` is defined and stays the same. The retried CI node will be connected to the queue consumed by still running CI nodes. You probably would expect the retried CI node to run the tests that were executed there on the first place. To achieve that you need to [enable it](#knapsack_pro_fixed_queue_split-remember-queue-split-on-retry-ci-node).
362
+
363
+ * Let's say one of the CI nodes failed and you retry just this single CI node while other CI nodes already finished work. Let's assume this retried CI node is part of the same CI build ID when you use supported CI provider or `KNAPSACK_PRO_CI_NODE_BUILD_ID` is defined and stays the same. The fact is all CI nodes finished work so the queue was consumed.
364
+ * If you retry CI node in first hour since the CI build started for the first time then the retried CI node won't execute tests because the queue was consumed. There is important reason why it works like that. For instance some CI providers like Buildkite allows to start CI node later than the others so sometimes the particular CI node may start work while all other CI nodes finished work. In that case we don't want to run tests on the CI node because queue was already consumed. We don't know whether the CI node is part of the build or it is retried CI node hence the 1 hour lock on initializing a new queue.
365
+ * If you retry CI node after 1 hour since the CI build started for the first time then the retried CI node will initialize a new queue and it will run whole test suite from the queue because there will be no other CI nodes running connected to the queue. The order of tests on retried CI node will be different than on the first run. You probably would expect the retried CI node to run the tests that were executed there on the first place. To achieve that you need to [enable it](#knapsack_pro_fixed_queue_split-remember-queue-split-on-retry-ci-node).
366
+
367
+ * When you use unsupported CI provider by knapack_pro gem or you forget to set unique `KNAPSACK_PRO_CI_NODE_BUILD_ID` per CI build then:
368
+ * when you retry single CI node then it will initialize a new queue and it will run whole test suite from the queue because there will be no other CI nodes running connected to the queue. The order of tests on retried CI node will be different than on the first run.
369
+ * when you retry all CI nodes then a new queue will be initialized and all CI nodes will connect to it.
361
370
 
362
371
  ### Extra configuration for Queue Mode
363
372
 
@@ -382,6 +391,8 @@ There might be some cached test suite splits for git commits you run in past for
382
391
 
383
392
  [knapsack_pro] {"queue_name"=>nil, "test_files"=>[{"path"=>"spec/foo_spec.rb", "time_execution"=>1.23}]}
384
393
 
394
+ To [reproduce tests executed on CI node](#for-knapsack_pro-queue-mode) in development environment please see FAQ.
395
+
385
396
  ### Supported test runners in queue mode
386
397
 
387
398
  At this moment the queue mode works for:
@@ -688,34 +699,42 @@ If you were running your tests with `--order random` on your CI then you can add
688
699
 
689
700
  #### for knapsack_pro queue mode
690
701
 
691
- To retry the particular CI node do this on your machine:
702
+ There are a few ways to reproduce tests executed on CI node in your development environment.
692
703
 
693
- KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=token \
694
- KNAPSACK_PRO_REPOSITORY_ADAPTER=git \
695
- KNAPSACK_PRO_PROJECT_DIR=~/projects/rails-app \
696
- KNAPSACK_PRO_CI_NODE_TOTAL=2 \
697
- KNAPSACK_PRO_CI_NODE_INDEX=0 \
698
- KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true \
699
- bundle exec rake "knapsack_pro:queue:rspec"
704
+ * At the end of `knapsack_pro:queue:rspec` results you will find example of command that you can copy and paste to your development machine. It will run all tests executed on the CI node in a single run.
700
705
 
701
- If you were running your tests with `--order random` on your CI like this:
706
+ * For each intermediate request to Knapsack Pro API queue you will also find example of command to run a subset of tests fetched from API. This might be helpful when you use `--order random` for rspec and you would like to reproduce the tests with the same seed.
702
707
 
703
- bundle exec rake "knapsack_pro:queue:rspec[--order random]"
708
+ * You can also retry tests and record the time execution data for them again for the particular CI node. Note you must be checkout on the same branch and git commit as your CI node was.
704
709
 
705
- Then you can find the seed number visible in rspec output:
710
+ To retry the particular CI node do this on your machine:
706
711
 
707
- (...)
708
- Randomized with seed 123
712
+ KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=token \
713
+ KNAPSACK_PRO_REPOSITORY_ADAPTER=git \
714
+ KNAPSACK_PRO_PROJECT_DIR=~/projects/rails-app \
715
+ KNAPSACK_PRO_CI_NODE_TOTAL=2 \
716
+ KNAPSACK_PRO_CI_NODE_INDEX=0 \
717
+ KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true \
718
+ bundle exec rake "knapsack_pro:queue:rspec"
709
719
 
710
- You can pass the seed in your local environment to reproduce the tests in the same order as they were executed on CI node:
720
+ If you were running your tests with `--order random` on your CI like this:
711
721
 
712
- KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=token \
713
- KNAPSACK_PRO_REPOSITORY_ADAPTER=git \
714
- KNAPSACK_PRO_PROJECT_DIR=~/projects/rails-app \
715
- KNAPSACK_PRO_CI_NODE_TOTAL=2 \
716
- KNAPSACK_PRO_CI_NODE_INDEX=0 \
717
- KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true \
718
- bundle exec rake "knapsack_pro:queue:rspec[--seed 123]"
722
+ bundle exec rake "knapsack_pro:queue:rspec[--order random]"
723
+
724
+ Then you can find the seed number visible in rspec output:
725
+
726
+ (...)
727
+ Randomized with seed 123
728
+
729
+ You can pass the seed in your local environment to reproduce the tests in the same order as they were executed on CI node:
730
+
731
+ KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=token \
732
+ KNAPSACK_PRO_REPOSITORY_ADAPTER=git \
733
+ KNAPSACK_PRO_PROJECT_DIR=~/projects/rails-app \
734
+ KNAPSACK_PRO_CI_NODE_TOTAL=2 \
735
+ KNAPSACK_PRO_CI_NODE_INDEX=0 \
736
+ KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true \
737
+ bundle exec rake "knapsack_pro:queue:rspec[--seed 123]"
719
738
 
720
739
  ### What happens when Knapsack Pro API is not available/not reachable temporarily?
721
740
 
@@ -834,6 +853,13 @@ When you use Queue Mode then knapack_pro does multiple requests to Knapsack Pro
834
853
  This means RSpec will remember failed tests so far and it will present them at the end of each executed test subset.
835
854
  You can see the list of all failed test files at the end of knapack_pro queue mode command.
836
855
 
856
+ ### Why when I use Queue Mode for RSpec then I see multiple times the same pending tests?
857
+
858
+ RSpec collects information about pending tests and presents it at the end of RSpec result.
859
+ When you use Queue Mode then knapack_pro does multiple requests to Knapsack Pro API and fetches a few test files to execute.
860
+ This means RSpec will remember pending tests so far and it will present them at the end of each executed test subset.
861
+ You can see the list of all pending test files at the end of knapack_pro queue mode command.
862
+
837
863
  ### Does in Queue Mode the RSpec is initialized many times that causes Rails load over and over again?
838
864
 
839
865
  No. In Queue Mode the RSpec configuration is updated every time when knapsack_pro gem gets a new set of test files from the Knapsack Pro API and it looks in knapsack_pro output like RSpec was loaded many times but in fact, it loads your project environment only once.
@@ -11,30 +11,52 @@ module KnapsackPro
11
11
 
12
12
  runner = new(KnapsackPro::Adapters::RSpecAdapter)
13
13
 
14
- cli_args = (args || '').split
15
- run_tests(runner, true, cli_args, 0)
14
+ cli_args = (args || '').split + [
15
+ '--default-path', runner.test_dir,
16
+ ]
17
+ run_tests(runner, true, cli_args, 0, [])
16
18
  end
17
19
 
18
- def self.run_tests(runner, can_initialize_queue, args, exitstatus)
20
+ def self.run_tests(runner, can_initialize_queue, args, exitstatus, all_test_file_paths)
19
21
  test_file_paths = runner.test_file_paths(can_initialize_queue: can_initialize_queue)
20
22
 
21
23
  if test_file_paths.empty?
24
+ unless all_test_file_paths.empty?
25
+ cli_args = args + all_test_file_paths
26
+
27
+ log_rspec_command(cli_args, :end_of_queue)
28
+ end
29
+
22
30
  KnapsackPro::Report.save_node_queue_to_api
23
31
  exit(exitstatus)
24
32
  else
25
33
  subset_queue_id = KnapsackPro::Config::EnvGenerator.set_subset_queue_id
26
34
  ENV['KNAPSACK_PRO_SUBSET_QUEUE_ID'] = subset_queue_id
27
35
 
28
- cli_args = args + [
29
- '--default-path', runner.test_dir,
30
- ] + test_file_paths
36
+ all_test_file_paths += test_file_paths
37
+ cli_args = args + test_file_paths
38
+
39
+ log_rspec_command(cli_args, :subset_queue)
40
+
31
41
  options = RSpec::Core::ConfigurationOptions.new(cli_args)
32
42
  exit_code = RSpec::Core::Runner.new(options).run($stderr, $stdout)
33
43
  exitstatus = exit_code if exit_code != 0
34
44
  RSpec.world.example_groups.clear
35
45
 
36
- run_tests(runner, false, args, exitstatus)
46
+ run_tests(runner, false, args, exitstatus, all_test_file_paths)
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def self.log_rspec_command(cli_args, type)
53
+ case type
54
+ when :subset_queue
55
+ KnapsackPro.logger.info("To retry in development the subset of tests fetched from API queue please run below command on your machine. If you use --order random then remember to add proper --seed 123 that you will find at the end of rspec command.")
56
+ when :end_of_queue
57
+ KnapsackPro.logger.info("To retry in development the tests for this CI node please run below command on your machine. It will run all tests in a single run. If you need to reproduce a particular subset of tests fetched from API queue then above after each request to Knapsack Pro API you will find example rspec command.")
37
58
  end
59
+ KnapsackPro.logger.info("bundle exec rspec " + cli_args.join(' '))
38
60
  end
39
61
  end
40
62
  end
@@ -1,3 +1,3 @@
1
1
  module KnapsackPro
2
- VERSION = '0.27.0'
2
+ VERSION = '0.28.0'
3
3
  end
@@ -2,7 +2,10 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
2
2
  describe '.run' do
3
3
  let(:test_suite_token_rspec) { 'fake-token' }
4
4
  let(:queue_id) { 'fake-queue-id' }
5
- let(:runner) { double }
5
+ let(:test_dir) { 'fake-test-dir' }
6
+ let(:runner) do
7
+ instance_double(described_class, test_dir: test_dir)
8
+ end
6
9
 
7
10
  subject { described_class.run(args) }
8
11
 
@@ -22,7 +25,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
22
25
 
23
26
  it do
24
27
  result = double
25
- expect(described_class).to receive(:run_tests).with(runner, true, ['--example-arg', 'example-value'], 0).and_return(result)
28
+ expect(described_class).to receive(:run_tests).with(runner, true, ['--example-arg', 'example-value', '--default-path', 'fake-test-dir'], 0, []).and_return(result)
26
29
 
27
30
  expect(subject).to eq result
28
31
  end
@@ -33,7 +36,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
33
36
 
34
37
  it do
35
38
  result = double
36
- expect(described_class).to receive(:run_tests).with(runner, true, [], 0).and_return(result)
39
+ expect(described_class).to receive(:run_tests).with(runner, true, ['--default-path', 'fake-test-dir'], 0, []).and_return(result)
37
40
 
38
41
  expect(subject).to eq result
39
42
  end
@@ -41,15 +44,12 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
41
44
  end
42
45
 
43
46
  describe '.run_tests' do
44
- let(:test_dir) { 'fake-test-dir' }
45
- let(:runner) do
46
- instance_double(described_class, test_dir: test_dir)
47
- end
47
+ let(:runner) { instance_double(described_class) }
48
48
  let(:can_initialize_queue) { double(:can_initialize_queue) }
49
- let(:args) { ['--example-arg', 'example-value'] }
49
+ let(:args) { ['--example-arg', 'example-value', '--default-path', 'fake-test-dir'] }
50
50
  let(:exitstatus) { double }
51
51
 
52
- subject { described_class.run_tests(runner, can_initialize_queue, args, exitstatus) }
52
+ subject { described_class.run_tests(runner, can_initialize_queue, args, exitstatus, []) }
53
53
 
54
54
  before do
55
55
  expect(runner).to receive(:test_file_paths).with(can_initialize_queue: can_initialize_queue).and_return(test_file_paths)
@@ -67,7 +67,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
67
67
  options = double
68
68
  expect(RSpec::Core::ConfigurationOptions).to receive(:new).with([
69
69
  '--example-arg', 'example-value',
70
- '--default-path', test_dir,
70
+ '--default-path', 'fake-test-dir',
71
71
  'a_spec.rb', 'b_spec.rb',
72
72
  ]).and_return(options)
73
73
 
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.27.0
4
+ version: 0.28.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-02-18 00:00:00.000000000 Z
11
+ date: 2017-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake