Conversation
…object in Ruby 3 and can't be mocked https://www.mail-archive.com/puppet-bugs@googlegroups.com/msg206907.html
…command requires full path
…require test/unit
…unit while running tests so we can mock method test_unit_autorunner_run
…tcase' to not break RSpec
…s not longer supported Starting Mar 15, 2019: All projects will require a CircleCI 2.0 configuration. CircleCI 1.0 jobs will be viewable but will no longer run. https://circleci.com/sunset1-0/eol-policy/
| end | ||
|
|
||
| def project_dir | ||
| project_repo_name = ENV['CIRCLE_PROJECT_REPONAME'] |
There was a problem hiding this comment.
Determine project directory with CIRCLE_PROJECT_REPONAME was for CircleCI 1.0.
CircleCI 1.0 is deprecated since 2019 so this code is not needed.
| dir = KnapsackPro::Config::Env.project_dir | ||
|
|
||
| if dir.to_s.include?('~') | ||
| File.expand_path(dir) |
There was a problem hiding this comment.
If the path has ~ sign in ~/repo then it will be expanded to a full path: /home/user/repo.
Thanks to that other parts of the code can work properly, for instance determining git hash and branch name with command like git -C /home/user/repo rev-parse HEAD that is called in this class.
Unfortunately command like git -C ~/repo rev-parse HEAD crashes because it's not full path.
There was a problem hiding this comment.
What do you mean by "full path" in the last sentence - do you mean absolute path? Does the problem occur when there is the ~ character in the path specifically, all does it happen with all relative paths? Or maybe it's with all relative paths, but the only ones we encounter contain the tilde?
Basically the reason I'm asking is this: maybe we can always return the absolute path here this way:
def working_dir
dir = KnapsackPro::Config::Env.project_dir
File.expand_path(dir)
endThere was a problem hiding this comment.
By full path, I meant absolute path.
Yes, we can do File.expand_path(dir) always. I was worried it won't work when someone provides an invalid path (not existing path on the disk) but even then this method works fine so we could use it always.
|
|
||
| # https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/AutoRunner#run-class_method | ||
| def self.test_unit_autorunner_run(force_standalone, default_dir, argv) | ||
| require 'test/unit' |
There was a problem hiding this comment.
Method test_unit_autorunner_run has been extracted to not load require 'test/unit' because this breaks the test environment for RSpec and causes random errors.
There was a problem hiding this comment.
Not a fan of the require inside a method tbh. :/ Also a bit worried that the test environment dictates how we organize the code containing the actual business logic.
What types of random errors have you encountered? Any idea as to why it worked previously? Was there a reason for the require to previously lie inside of the if statement instead of at the top of the file (where you would typically expect it)? Was this done to avoid other errors maybe?
Have you considered any other solutions to solve the problems you encountered?
There was a problem hiding this comment.
knapsack_pro gem supports multiple test runners in a single gem. But we do not list them as dependencies in knapsack_pro.gemspec. They are listed there only as a dev dependency for a testing purpose of knapsack_pro gem.
For instance, if someone is using only RSpec in his project then when he installs knapsack_pro it would be pointless to download all test runners like cucumber, test-unit, etc.
That is why we only require a particular test runner during the runtime of the gem when a method like KnapsackPro::Runners::TestUnitRunner.run is called. Basically, when someone on purpose wants to run knapsack_pro for a given test runner like test-unit then we require require 'test/unit' and we assume the user already has test-unit gem installed in his Gemfile.
In the test environment for knapsack_pro gem we should not load multiple test runners at once because they impact each other. For instance require 'test/unit' breaks RSpec and a lot of weird errors were happening (state of tests was not clean up between test examples) https://app.circleci.com/pipelines/github/KnapsackPro/knapsack_pro-ruby/411/workflows/927f821d-df4f-4213-90d4-cc38c189cfa8/jobs/1398
That is why I extracted test_unit_autorunner_run method to hide require 'test/unit' and not call it in test runtime.
Why it was working previously? I guess I did not refresh my local copy of Gemfile.lock for a few years and when I updated it and new test-unit gem and new rspec gem versions were installed then problem was revealed.
There was a problem hiding this comment.
I see, thanks for the extended explanation!
| :allocator | ||
|
|
||
| def self.child_status | ||
| $? |
There was a problem hiding this comment.
$? has been extracted to a method child_status because it's not possible anymore to mock $? so let's hide it inside of a method that we can mock.
| dir = KnapsackPro::Config::Env.project_dir | ||
|
|
||
| if dir.to_s.include?('~') | ||
| File.expand_path(dir) |
There was a problem hiding this comment.
What do you mean by "full path" in the last sentence - do you mean absolute path? Does the problem occur when there is the ~ character in the path specifically, all does it happen with all relative paths? Or maybe it's with all relative paths, but the only ones we encounter contain the tilde?
Basically the reason I'm asking is this: maybe we can always return the absolute path here this way:
def working_dir
dir = KnapsackPro::Config::Env.project_dir
File.expand_path(dir)
end|
|
||
| # https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/AutoRunner#run-class_method | ||
| def self.test_unit_autorunner_run(force_standalone, default_dir, argv) | ||
| require 'test/unit' |
There was a problem hiding this comment.
Not a fan of the require inside a method tbh. :/ Also a bit worried that the test environment dictates how we organize the code containing the actual business logic.
What types of random errors have you encountered? Any idea as to why it worked previously? Was there a reason for the require to previously lie inside of the if statement instead of at the top of the file (where you would typically expect it)? Was this done to avoid other errors maybe?
Have you considered any other solutions to solve the problems you encountered?
| project_repo_name = ENV['CIRCLE_PROJECT_REPONAME'] | ||
| "/home/ubuntu/#{project_repo_name}" if project_repo_name | ||
| working_dir = ENV['CIRCLE_WORKING_DIRECTORY'] | ||
| return working_dir if working_dir |
There was a problem hiding this comment.
The return keyword is redundant here
| if runner.test_files_to_execute_exist? | ||
| adapter_class.verify_bind_method_called | ||
|
|
||
| require 'test/unit' |
There was a problem hiding this comment.
require was hide in the run method instead of being at the top of the file to not load test-unit gem during loading knapsack_pro gem.
If someone uses only RSpec then he wouldn't be able to load knapsack_pro gem without having test-unit in the Gemfile. We don't want to force users to install gems they don't use in their projects.
CIRCLE_WORKING_DIRECTORYenv var~in pathdevelopment tips
If you clone this project in development please remove your local copy of
Gemfile.lock(it is ignored in.gitignore) and then run:Gemfile.lockwith the latest gems as listed inknapsack_pro.gemspec