diff options
385 files changed, 4345 insertions, 3317 deletions
diff --git a/.travis.yml b/.travis.yml index b81c538737..afbc8a8a96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,17 +30,12 @@ env: matrix: include: - - rvm: 2.1 + - rvm: 2.2.5 sudo: true script: sudo -E $(which bundle) exec rake spec; # also remove integration / external tests bundler_args: --without changelog development docgen guard integration maintenance omnibus_package tools aix bsd mac_os_x solaris windows --frozen - - rvm: 2.2 - sudo: true - script: sudo -E $(which bundle) exec rake spec; - # also remove integration / external tests - bundler_args: --without changelog development docgen guard integration maintenance omnibus_package tools aix bsd mac_os_x solaris windows --frozen - - rvm: 2.3.0 + - rvm: 2.3.1 sudo: true script: sudo -E $(which bundle) exec rake spec; # also remove integration / external tests @@ -52,13 +47,13 @@ matrix: bundler_args: --without changelog development docgen guard integration maintenance omnibus_package tools aix bsd mac_os_x solaris windows --frozen - env: CHEFSTYLE: 1 - rvm: 2.1 + rvm: 2.3.1 script: bundle exec rake style # also remove integration / external tests bundler_args: --without changelog development docgen guard integration maintenance omnibus_package tools aix bsd mac_os_x solaris windows --frozen - env: AUDIT_CHECK: 1 - rvm: 2.1 + rvm: 2.3.1 script: bundle exec bundle-audit check --update # also remove integration / external tests bundler_args: --without changelog development docgen guard integration maintenance omnibus_package tools aix bsd mac_os_x solaris windows --frozen @@ -68,23 +63,23 @@ matrix: - env: TEST_GEM: chef-provisioning script: tasks/bin/run_external_test $TEST_GEM rake spec - rvm: 2.2 + rvm: 2.3.1 - env: TEST_GEM: chef-provisioning-aws script: tasks/bin/run_external_test $TEST_GEM rake spec - rvm: 2.2 + rvm: 2.3.1 - env: TEST_GEM: chef-sugar script: tasks/bin/run_external_test $TEST_GEM rake - rvm: 2.2 + rvm: 2.3.1 - env: - TEST_GEM: chef-zero script: tasks/bin/run_external_test $TEST_GEM rake spec cheffs - rvm: 2.2 + rvm: 2.3.1 - env: TEST_GEM: cheffish script: tasks/bin/run_external_test $TEST_GEM rake spec - rvm: 2.2 + rvm: 2.3.1 - env: TEST_GEM: chefspec # The chefspec tests + bundler cache + "gem update --system" interact badly :/ @@ -93,26 +88,26 @@ matrix: - gem install bundler -v $(grep bundler omnibus_overrides.rb | cut -d'"' -f2) - bundle config --local without server:docgen:maintenance:omnibus_package:development:ruby_prof:pry script: tasks/bin/run_external_test $TEST_GEM rake - rvm: 2.2.0 + rvm: 2.3.1 - env: TEST_GEM: foodcritic script: tasks/bin/run_external_test $TEST_GEM rake test - rvm: 2.2 + rvm: 2.3.1 - env: TEST_GEM: halite script: tasks/bin/run_external_test $TEST_GEM rake spec - rvm: 2.2 + rvm: 2.3.1 - env: TEST_GEM: knife-windows script: tasks/bin/run_external_test $TEST_GEM rake unit_spec - rvm: 2.2 + rvm: 2.3.1 - env: TEST_GEM: poise script: tasks/bin/run_external_test $TEST_GEM rake spec - rvm: 2.2 + rvm: 2.3.1 ### START TEST KITCHEN ONLY ### # - - rvm: 2.2 + - rvm: 2.3.1 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -129,7 +124,7 @@ matrix: env: - UBUNTU=12.04 - KITCHEN_YAML=.kitchen.travis.yml - - rvm: 2.2 + - rvm: 2.3.1 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -146,7 +141,7 @@ matrix: env: - UBUNTU=14.04 - KITCHEN_YAML=.kitchen.travis.yml - - rvm: 2.2 + - rvm: 2.3.1 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -163,7 +158,7 @@ matrix: env: - UBUNTU=16.04 - KITCHEN_YAML=.kitchen.travis.yml - - rvm: 2.2 + - rvm: 2.3.1 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -180,7 +175,7 @@ matrix: env: - DEBIAN=7 - KITCHEN_YAML=.kitchen.travis.yml - - rvm: 2.2 + - rvm: 2.3.1 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -197,7 +192,7 @@ matrix: env: - DEBIAN=8 - KITCHEN_YAML=.kitchen.travis.yml - - rvm: 2.2 + - rvm: 2.3.1 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -214,7 +209,7 @@ matrix: env: - CENTOS=6 - KITCHEN_YAML=.kitchen.travis.yml - - rvm: 2.2 + - rvm: 2.3.1 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -231,7 +226,7 @@ matrix: env: - CENTOS=7 - KITCHEN_YAML=.kitchen.travis.yml - - rvm: 2.2 + - rvm: 2.3.1 services: docker sudo: required gemfile: kitchen-tests/Gemfile @@ -249,7 +244,7 @@ matrix: - FEDORA=23 - KITCHEN_YAML=.kitchen.travis.yml ### END TEST KITCHEN ONLY ### - - rvm: 2.2 + - rvm: 2.3.1 sudo: required dist: trusty before_install: @@ -270,7 +265,6 @@ matrix: - sudo cat /var/log/squid3/access.log allow_failures: - - rvm: 2.3.0 - rvm: rbx notifications: diff --git a/CHANGELOG.md b/CHANGELOG.md index c9b30edba7..1dccc3860b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,48 @@ # Change Log +## [v12.13.37](https://github.com/chef/chef/tree/v12.13.37) (2016-08-12) +[Full Changelog](https://github.com/chef/chef/compare/v12.13.30...v12.13.37) + +**Enhancements:** + +- Bumping ohai and mixlib-log to fix regression [\#5197](https://github.com/chef/chef/pull/5197) ([mwrock](https://github.com/mwrock)) +- Remove requires in Chef::Recipe that are no longer necessary [\#5189](https://github.com/chef/chef/pull/5189) ([lamont-granquist](https://github.com/lamont-granquist)) + +## [v12.13.30](https://github.com/chef/chef/tree/v12.13.30) (2016-08-05) +[Full Changelog](https://github.com/chef/chef/compare/v12.12.15...v12.13.30) + +**Enhancements:** + +- noop apt_update similar to apt_repository [\#5173](https://github.com/chef/chef/pull/5173) ([lamont-granquist](https://github.com/lamont-granquist)) +- Bump dependencies to bring in Ohai 8.18 [\#5168](https://github.com/chef/chef/pull/5168) ([tas50](https://github.com/tas50)) +- Make Chef work with Ruby 2.3, update Ruby to 2.1.9 [\#5165](https://github.com/chef/chef/pull/5165) ([jkeiser](https://github.com/jkeiser)) +- Log cause chain for exceptions [\#3354](https://github.com/chef/chef/pull/3354) ([jaym](https://github.com/jaym)) +- First pass on --config-option handling. [\#5045](https://github.com/chef/chef/pull/5045) ([coderanger](https://github.com/coderanger)) +- Add bootstrap proxy authentication support. [\#4059](https://github.com/chef/chef/pull/4059) ([yossigo](https://github.com/yossigo)) +- Support setting an empty string for cron attrs [\#5127](https://github.com/chef/chef/pull/5127) ([thommay](https://github.com/thommay)) +- Also clear notifications when deleting a resource. [\#5146](https://github.com/chef/chef/pull/5146) ([coderanger](https://github.com/coderanger)) +- Clean up subscribes internals and notification storage. [\#5145](https://github.com/chef/chef/pull/5145) ([coderanger](https://github.com/coderanger)) +- Cache ChefFS children [\#5131](https://github.com/chef/chef/pull/5131) ([thommay](https://github.com/thommay)) +- Update to rspec 3.5 [\#5126](https://github.com/chef/chef/pull/5126) ([thommay](https://github.com/thommay)) +- Add `chef\_data\_bag\_item` to Cheffish DSL methods [\#5125](https://github.com/chef/chef/pull/5125) ([danielsdeleo](https://github.com/danielsdeleo)) +- replace glibc resolver with ruby resolver [\#5123](https://github.com/chef/chef/pull/5123) ([lamont-granquist](https://github.com/lamont-granquist)) +- The user must specify a category for a new cookbook [\#5091](https://github.com/chef/chef/pull/5091) ([thommay](https://github.com/thommay)) +- Warn if not installing an individual bff fileset [\#5093](https://github.com/chef/chef/pull/5093) ([mwrock](https://github.com/mwrock)) +- Use Mixlib::Archive to extract tarballs [\#5080](https://github.com/chef/chef/pull/5080) ([thommay](https://github.com/thommay)) +- Data Collector server URL validation, and disable on host down [\#5076](https://github.com/chef/chef/pull/5076) ([adamleff](https://github.com/adamleff)) + +**Fixed Bugs:** + +- Don't log error for reporting audit data in when in chef-zero [\#5016](https://github.com/chef/chef/pull/5016) ([erichelgeson](https://github.com/erichelgeson)) +- Invalidate the file system cache on deletion [\#5154](https://github.com/chef/chef/pull/5154) ([thommay](https://github.com/thommay)) +- Root ACLs are a top level json file not a sub-directory [\#5155](https://github.com/chef/chef/pull/5155) ([thommay](https://github.com/thommay)) +- Install nokogiri and pin mixlib-cli [\#5118](https://github.com/chef/chef/pull/5118) ([ksubrama](https://github.com/ksubrama)) +- Ensure that the valid option is given back to the option parser [\#5114](https://github.com/chef/chef/pull/5114) ([dldinternet](https://github.com/dldinternet)) +- Fixed regex for zypper version 1.13.\*. [\#5109](https://github.com/chef/chef/pull/5109) ([yeoldegrove](https://github.com/yeoldegrove)) +- add back method\_missing support to set\_unless [\#5103](https://github.com/chef/chef/pull/5103) ([lamont-granquist](https://github.com/lamont-granquist)) +- Fix \#5094 node.default\_unless issue in 12.12.13 [\#5097](https://github.com/chef/chef/pull/5097) ([lamont-granquist](https://github.com/lamont-granquist)) +- Fix \#5078 using cwd parameter instead of Dir.pwd [\#5079](https://github.com/chef/chef/pull/5079) ([Tensibai](https://github.com/Tensibai)) + ## [v12.12.15](https://github.com/chef/chef/tree/v12.12.15) (2016-07-08) [Full Changelog](https://github.com/chef/chef/compare/v12.12.13...v12.12.15) @@ -94,7 +137,7 @@ - Update rubygems provider to support local install of gems if so specified [\#4847](https://github.com/chef/chef/pull/4847) ([PrajaktaPurohit](https://github.com/PrajaktaPurohit)) - fix details in with\_run\_context [\#4839](https://github.com/chef/chef/pull/4839) ([lamont-granquist](https://github.com/lamont-granquist)) - Lock dependencies of chef through a `Gemfile.lock` [\#4820](https://github.com/chef/chef/pull/4820) ([jkeiser](https://github.com/jkeiser)) -- add better resource manipulation API [\#4834](https://github.com/chef/chef/pull/4834) ([lamont-granquist](https://github.com/lamont-granquist)) +- add better resource manipulation API [\#4834](https://github.com/chef/chef/pull/4834) ([lamont-granquist](https://github.com/lamont-granquist)) - add nillable apt\_repository and nillable properties [\#4832](https://github.com/chef/chef/pull/4832) ([lamont-granquist](https://github.com/lamont-granquist)) ## [v12.9](https://github.com/chef/chef/tree/v12.9.38) (2016-04-09) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 23dd85d7b7..4f9f527381 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,84 +15,54 @@ We have a 3 step process that utilizes **Github Issues**: 2. Create a Github Pull Request. 3. Do [Code Review](#cr) with the **Chef Engineering Team** or **Chef Core Committers** on the pull request. -### <a name="pulls"></a> Chef Pull Requests +### Chef Pull Requests -Chef is built to last. We strive to ensure high quality throughout the Chef experience. In order to ensure - this, we require a couple of things for all pull requests to Chef: +Chef is built to last. We strive to ensure high quality throughout the Chef experience. In order to ensure this, we require a couple of things for all pull requests to Chef: -1. **Tests:** To ensure high quality code and protect against future regressions, we require all the - code in Chef to have at least unit test coverage. See the [spec/unit](https://github.com/chef/chef/tree/master/spec/unit) - directory for the existing tests and use ```bundle exec rake spec``` to run them. -2. **Green Travis Run:** We use [Travis CI](https://travis-ci.org/) in order to run our tests - continuously on all the pull requests. We require the Travis runs to succeed on every pull - request before being merged. +1. **Tests:** To ensure high quality code and protect against future regressions, we require all the code in Chef to have at least unit test coverage. See the [spec/unit](https://github.com/chef/chef/tree/master/spec/unit) directory for the existing tests and use `bundle exec rake spec` to run them. +2. **Green Travis Run:** We use [Travis CI](https://travis-ci.org/) in order to run our tests continuously on all the pull requests. We require the Travis runs to succeed on every pull request before being merged. +### Chef Code Review Process -### <a name="cr"></a> Chef Code Review Process +The Chef Code Review process happens on Github pull requests. See [this article](https://help.github.com/articles/using-pull-requests) if you're not familiar with Github Pull Requests. -The Chef Code Review process happens on Github pull requests. See - [this article](https://help.github.com/articles/using-pull-requests) if you're not - familiar with Github Pull Requests. - -Once you a pull request, the **Chef Engineering Team** or **Chef Core Committers** will review your code - and respond to you with any feedback they might have. The process at this point is as follows: +Once you open a pull request, the **Chef Engineering Team** or **Chef Core Committers** will review your code and respond to you with any feedback they might have. The process at this point is as follows: 1. 2 thumbs-ups are required from the **Chef Engineering Team** or **Chef Core Committers** for all merges. 2. When ready, your pull request will be tagged with label `Ready For Merge`. -3. Your patch will be merged into `master` including necessary documentation updates - and you will be included in `CHANGELOG.md`. Our goal is to have patches merged in 2 weeks - after they are marked to be merged. - -If you would like to learn about when your code will be available in a release of Chef, read more about - [Chef Release Process](#release). +3. Your patch will be merged into `master` including necessary documentation updates and you will be included in `CHANGELOG.md`. Our goal is to have patches merged in 2 weeks after they are marked to be merged. +If you would like to learn about when your code will be available in a release of Chef, read more about [Chef Release Cycles](#chef-release-cycles). ### Contributor License Agreement (CLA) -Licensing is very important to open source projects. It helps ensure the - software continues to be available under the terms that the author desired. -Chef uses [the Apache 2.0 license](https://github.com/chef/chef/blob/master/LICENSE) - to strike a balance between open contribution and allowing you to use the - software however you would like to. +Licensing is very important to open source projects. It helps ensure the software continues to be available under the terms that the author desired. + +Chef uses [the Apache 2.0 license](https://github.com/chef/chef/blob/master/LICENSE) to strike a balance between open contribution and allowing you to use the software however you would like to. -The license tells you what rights you have that are provided by the copyright holder. - It is important that the contributor fully understands what rights they are - licensing and agrees to them. Sometimes the copyright holder isn't the contributor, - such as when the contributor is doing work for a company. +The license tells you what rights you have that are provided by the copyright holder. It is important that the contributor fully understands what rights they are licensing and agrees to them. Sometimes the copyright holder isn't the contributor, such as when the contributor is doing work for a company. -To make a good faith effort to ensure these criteria are met, Chef requires an Individual CLA - or a Corporate CLA for contributions. This agreement helps ensure you are aware of the - terms of the license you are contributing your copyrighted works under, which helps to - prevent the inclusion of works in the projects that the contributor does not hold the rights - to share. +To make a good faith effort to ensure these criteria are met, Chef requires an Individual CLA or a Corporate CLA for contributions. This agreement helps ensure you are aware of the terms of the license you are contributing your copyrighted works under, which helps to prevent the inclusion of works in the projects that the contributor does not hold the rights to share. It only takes a few minutes to complete a CLA, and you retain the copyright to your contribution. -You can complete our - [Individual CLA](https://supermarket.chef.io/icla-signatures/new) online. - If you're contributing on behalf of your employer and they retain the copyright for your works, - have your employer fill out our - [Corporate CLA](https://supermarket.chef.io/ccla-signatures/new) instead. +You can complete our [Individual CLA](https://supermarket.chef.io/icla-signatures/new) online. If you're contributing on behalf of your employer and they retain the copyright for your works, have your employer fill out our [Corporate CLA](https://supermarket.chef.io/ccla-signatures/new) instead. ### Chef Obvious Fix Policy -Small contributions such as fixing spelling errors, where the content is small enough - to not be considered intellectual property, can be submitted by a contributor as a patch, - without a CLA. +Small contributions such as fixing spelling errors, where the content is small enough to not be considered intellectual property, can be submitted by a contributor as a patch, without a CLA. -As a rule of thumb, changes are obvious fixes if they do not introduce any new functionality - or creative thinking. As long as the change does not affect functionality, some likely - examples include the following: +As a rule of thumb, changes are obvious fixes if they do not introduce any new functionality or creative thinking. As long as the change does not affect functionality, some likely examples include the following: -* Spelling / grammar fixes -* Typo correction, white space and formatting changes -* Comment clean up -* Bug fixes that change default return values or error codes stored in constants -* Adding logging messages or debugging output -* Changes to ‘metadata’ files like Gemfile, .gitignore, build scripts, etc. -* Moving source files from one directory or package to another +- Spelling / grammar fixes +- Typo correction, white space and formatting changes +- Comment clean up +- Bug fixes that change default return values or error codes stored in constants +- Adding logging messages or debugging output +- Changes to 'metadata' files like Gemfile, .gitignore, build scripts, etc. +- Moving source files from one directory or package to another -**Whenever you invoke the “obvious fix” rule, please say so in your commit message:** +**Whenever you invoke the "obvious fix" rule, please say so in your commit message:** ``` ------------------------------------------------------------------------ @@ -107,67 +77,50 @@ Date: Wed Sep 18 11:44:40 2013 -0700 ------------------------------------------------------------------------ ``` -## <a name="issues"></a> Chef Issue Tracking +## Chef Issue Tracking Chef Issue Tracking is handled using Github Issues. -If you are familiar with Chef and know the component that is causing you a problem or if you - have a feature request on a specific component you can file an issue in the corresponding - Github project. All of our Open Source Software can be found in our - [Github organization](https://github.com/chef/). +If you are familiar with Chef and know the component that is causing you a problem or if you have a feature request on a specific component you can file an issue in the corresponding Github project. All of our Open Source Software can be found in our [Github organization](https://github.com/chef/). -There is also a listing of the various Chef products and where to file issues that can be - found in the Chef docs in the [community contributions section](https://docs.chef.io/community_contributions.html#issues-and-bug-reports). - -Otherwise you can file your issue in the [Chef project](https://github.com/chef/chef/issues) - and we will make sure it gets filed against the appropriate project. +There is also a listing of the various Chef products and where to file issues that can be found in the Chef docs in the [community contributions section](https://docs.chef.io/community_contributions.html#issues-and-bug-reports). +Otherwise you can file your issue in the [Chef project](https://github.com/chef/chef/issues) and we will make sure it gets filed against the appropriate project. ### Useful Github Queries Contributions go through a review process to improve code quality and avoid regressions. Managing a large number of contributions requires a workflow to provide queues for work such as triage, code review, and merging. A semi-formal process has evolved over the life of the project. Chef maintains this process pending community development and acceptance of an [RFC](https://github.com/chef/chef-rfc). These queries will help track contributions through this process: -* [Issues that are not assigned to a team](https://github.com/chef/chef/issues?q=is%3Aopen+-label%3AAIX+-label%3ABSD+-label%3Awindows+-label%3A%22Chef+Core%22++-label%3A%22Dev+Tools%22+-label%3AUbuntu+-label%3A%22Enterprise+Linux%22+-label%3A%22Ready+For+Merge%22+-label%3AMac+-label%3ASolaris+) -* [Untriaged Issues](https://github.com/chef/chef/issues?q=is%3Aopen+is%3Aissue+-label%3ABug+-label%3AEnhancement+-label%3A%22Tech+Cleanup%22+-label%3A%22Ready+For+Merge%22) -* [PRs to be Reviewed](https://github.com/chef/chef/labels/Pending%20Maintainer%20Review) -* [Suitable for First Contribution](https://github.com/chef/chef/labels/Easy) - -## <a name="release"></a> Chef Release Cycles +- [Issues that are not assigned to a team](https://github.com/chef/chef/issues?q=is%3Aopen+-label%3AAIX+-label%3ABSD+-label%3Awindows+-label%3A%22Chef+Core%22++-label%3A%22Dev+Tools%22+-label%3AUbuntu+-label%3A%22Enterprise+Linux%22+-label%3A%22Ready+For+Merge%22+-label%3AMac+-label%3ASolaris+) +- [Untriaged Issues](https://github.com/chef/chef/issues?q=is%3Aopen+is%3Aissue+-label%3ABug+-label%3AEnhancement+-label%3A%22Tech+Cleanup%22+-label%3A%22Ready+For+Merge%22) +- [PRs to be Reviewed](https://github.com/chef/chef/labels/Pending%20Maintainer%20Review) +- [Suitable for First Contribution](https://github.com/chef/chef/labels/Easy) -Our primary shipping vehicle is operating system specific packages that includes - all the requirements of Chef. We call these [Omnibus packages](https://github.com/chef/omnibus) +## Chef Release Cycles -We also release our software as gems to [Rubygems](https://rubygems.org/) but we strongly - recommend using Chef packages since they are the only combination of native libraries & - gems required by Chef that we test throughly. +Our primary shipping vehicle is operating system specific packages that includes all the requirements of Chef. We call these [Omnibus packages](https://github.com/chef/omnibus) -Our version numbering closely follows [Semantic Versioning](http://semver.org/) standard. Our - standard version numbers look like X.Y.Z which mean: +We also release our software as gems to [Rubygems](https://rubygems.org/) but we strongly recommend using Chef packages since they are the only combination of native libraries & gems required by Chef that we test throughly. -* X is a major release, which may not be fully compatible with prior major releases -* Y is a minor release, which adds both new features and bug fixes -* Z is a patch release, which adds just bug fixes +Our version numbering roughly follows [Semantic Versioning](http://semver.org/) standard. Our standard version numbers look like X.Y.Z which mean: -We frequently make `alpha` and `beta` releases with version numbers that look like - `X.Y.Z.alpha.0` or `X.Y.Z.beta.1`. These releases are still well tested but not as - throughly as **Minor** or **Patch** releases. +- X is a major release, which may not be fully compatible with prior major releases +- Y is a minor release, which adds both new features and bug fixes +- Z is a patch release, which adds just bug fixes -We do a `Minor` release approximately every 3 months and `Patch` releases on a when-needed - basis for regressions, significant bugs, and security issues. +After shipping a release of Chef we bump the `Minor` version by one to start development of the next minor releaae. All merges to master trigger an increment of the `Patch` version, and a build through our internal testing pipeline. We do a `Minor` release approximately every month, which consist of shipping one of the already auto-incremented and tested `Patch` versions. For example after shiping 12.10.24, we incremented Chef to 12.11.0\. From there 18 commits where merged bringing the version to 12.11.18, which we shipped as an omnibus package. -Announcements of releases are available on [Chef Blog](https://www.chef.io/blog/) when they are - available. +Announcements of releases are made to the [chef mailing list](https://discourse.chef.io/c/chef-release) when they are available. ## Chef Community -Chef is made possible by a strong community of developers and system administrators. If you have - any questions or if you would like to get involved in the Chef community you can check out: +Chef is made possible by a strong community of developers and system administrators. If you have any questions or if you would like to get involved in the Chef community you can check out: -* [chef](https://discourse.chef.io/) mailing list -* [\#chef](https://botbot.me/freenode/chef/) and [\#chef-hacking](https://botbot.me/freenode/chef-hacking/) IRC channels on irc.freenode.net +- [Chef Mailing List](https://discourse.chef.io/) +- [Chef Community Slack](https://community-slack.chef.io/) Also here are some additional pointers to some awesome Chef content: -* [Chef Docs](https://docs.chef.io/) -* [Learn Chef](https://learn.chef.io/) -* [Chef Inc](https://www.chef.io/) +- [Chef Docs](https://docs.chef.io/) +- [Learn Chef](https://learn.chef.io/) +- [Chef Inc.](https://www.chef.io/) diff --git a/DOC_CHANGES.md b/DOC_CHANGES.md index 069cdc62b4..fadd382cbb 100644 --- a/DOC_CHANGES.md +++ b/DOC_CHANGES.md @@ -6,15 +6,4 @@ Example Doc Change: Description of the required change. --> -## Doc changes for Chef 12.11 - -### RFC 062 Exit Status Support - -Starting with Chef Client 12.11, there is support for the consistent, standard exit codes as defined in [Chef RFC 062](https://github.com/chef/chef-rfc/blob/master/rfc062-exit-status.md). - -With no additional configuration when Chef Client exits with a non-standard exit code a deprecation warning will be issued advising users of the upcoming change in behavior. - -To enable the standardized exit code behavior, there is a new setting in client.rb. The `exit_status` setting, when set to `:enabled` will enforce standarized exit codes. In a future release, this will become the default behavior. - -If you need to maintain the previous exit code behavior to support your current workflow, you can disable this (and the deprecation warnings) by setting `exit_status` to `:disabled`. - +## Doc changes for Chef 12.13 @@ -20,6 +20,7 @@ gem "cheffish" group(:omnibus_package) do gem "appbundler" gem "rb-readline" + gem "nokogiri" end group(:omnibus_package, :pry) do @@ -34,7 +35,7 @@ group(:integration) do gem "chef-provisioning-aws" gem "chef-rewind" gem "chef-sugar" - gem "chefspec" + gem "chefspec", git: "https://github.com/sethvargo/chefspec", branch: "master" gem "halite" gem "poise" gem "knife-windows" @@ -65,7 +66,6 @@ end group(:development, :test) do gem "simplecov" - gem "rack", "< 2.0" # 2.0 requires Ruby 2.2+ # for testing new chefstyle rules # gem 'chefstyle', github: 'chef/chefstyle' @@ -79,6 +79,7 @@ end group(:travis) do # See `bundler-audit` in .travis.yml gem "bundler-audit", git: "https://github.com/rubysec/bundler-audit.git" + gem "travis" end instance_eval(ENV["GEMFILE_MOD"]) if ENV["GEMFILE_MOD"] diff --git a/Gemfile.lock b/Gemfile.lock index 4988559d09..daace58001 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,26 +1,37 @@ GIT remote: https://github.com/chef/chefstyle.git - revision: 52a0d55a9e8fb30d067c0a66371db4ae781a0269 + revision: c36dcbd6c2c21d2e19db77d9fbdf2402d0bacccf branch: master specs: - chefstyle (0.3.1) - rubocop (= 0.39.0) + chefstyle (0.4.0) + rubocop (= 0.42.0) GIT remote: https://github.com/rubysec/bundler-audit.git - revision: b16b26e0a4eed474f5f1ee38c22030a2f617ffc8 + revision: b7123d7b294f244165d9469f22b37a559e235fc2 specs: bundler-audit (0.5.0) bundler (~> 1.2) thor (~> 0.18) +GIT + remote: https://github.com/sethvargo/chefspec + revision: b8754bdbdffc26e2744dcb5d18fd5ee5e82a703a + branch: master + specs: + chefspec (4.7.0) + chef (>= 12.0) + fauxhai (~> 3.6) + rspec (~> 3.0) + PATH remote: . specs: - chef (12.12.24) + chef (12.14.24) + addressable bundler (>= 1.10) - chef-config (= 12.12.24) - chef-zero (~> 4.5) + chef-config (= 12.14.24) + chef-zero (~> 4.8) diff-lcs (~> 1.2, >= 1.2.4) erubis (~> 2.7) ffi-yajl (~> 2.2) @@ -28,7 +39,7 @@ PATH iniparse (~> 1.4) mixlib-archive (>= 0.2.0) mixlib-authentication (~> 1.4) - mixlib-cli (~> 1.4) + mixlib-cli (~> 1.7) mixlib-log (~> 1.3) mixlib-shellout (~> 2.0) net-sftp (~> 2.1, >= 2.1.2) @@ -37,18 +48,19 @@ PATH ohai (>= 8.6.0.alpha.1, < 9) plist (~> 3.2) proxifier (~> 1.0) - rspec-core (~> 3.4.0) - rspec-expectations (~> 3.4.0) - rspec-mocks (~> 3.4.0) + rspec-core (~> 3.5) + rspec-expectations (~> 3.5) + rspec-mocks (~> 3.5) rspec_junit_formatter (~> 0.2.0) serverspec (~> 2.7) specinfra (~> 2.10) syslog-logger (~> 1.6) uuidtools (~> 2.1.5) - chef (12.12.24-universal-mingw32) + chef (12.14.24-universal-mingw32) + addressable bundler (>= 1.10) - chef-config (= 12.12.24) - chef-zero (~> 4.5) + chef-config (= 12.14.24) + chef-zero (~> 4.8) diff-lcs (~> 1.2, >= 1.2.4) erubis (~> 2.7) ffi (~> 1.9) @@ -57,7 +69,7 @@ PATH iniparse (~> 1.4) mixlib-archive (>= 0.2.0) mixlib-authentication (~> 1.4) - mixlib-cli (~> 1.4) + mixlib-cli (~> 1.7) mixlib-log (~> 1.3) mixlib-shellout (~> 2.0) net-sftp (~> 2.1, >= 2.1.2) @@ -66,9 +78,9 @@ PATH ohai (>= 8.6.0.alpha.1, < 9) plist (~> 3.2) proxifier (~> 1.0) - rspec-core (~> 3.4.0) - rspec-expectations (~> 3.4.0) - rspec-mocks (~> 3.4.0) + rspec-core (~> 3.5) + rspec-expectations (~> 3.5) + rspec-mocks (~> 3.5) rspec_junit_formatter (~> 0.2.0) serverspec (~> 2.7) specinfra (~> 2.10) @@ -88,8 +100,9 @@ PATH PATH remote: chef-config specs: - chef-config (12.12.24) - fuzzyurl (~> 0.8.0) + chef-config (12.14.24) + addressable + fuzzyurl mixlib-config (~> 2.0) mixlib-shellout (~> 2.0) @@ -101,54 +114,50 @@ GEM mixlib-cli (~> 1.4) artifactory (2.3.3) ast (2.3.0) - aws-sdk (2.3.19) - aws-sdk-resources (= 2.3.19) - aws-sdk-core (2.3.19) + aws-sdk (2.5.5) + aws-sdk-resources (= 2.5.5) + aws-sdk-core (2.5.5) jmespath (~> 1.0) - aws-sdk-resources (2.3.19) - aws-sdk-core (= 2.3.19) + aws-sdk-resources (2.5.5) + aws-sdk-core (= 2.5.5) aws-sdk-v1 (1.66.0) json (~> 1.4) nokogiri (>= 1.4.4) + backports (3.6.8) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) builder (3.2.2) byebug (9.0.5) - chef-api (0.6.0) + chef-api (0.7.0) logify (~> 0.1) mime-types - chef-provisioning (1.8.0) - cheffish (>= 1.3.1, < 3.0) + chef-provisioning (1.9.1) + cheffish (>= 1.3.1, < 4.0) inifile (>= 2.0.2) mixlib-install (~> 1.0) net-scp (~> 1.0) net-ssh (>= 2.9, < 4.0) net-ssh-gateway (~> 1.2.0) winrm (~> 1.3) - chef-provisioning-aws (1.10.0) + chef-provisioning-aws (1.11.0) aws-sdk (>= 2.1.26, < 3.0) aws-sdk-v1 (>= 1.59.0) chef-provisioning (~> 1.4) retryable (~> 2.0, >= 2.0.1) ubuntu_ami (~> 0.4, >= 0.4.1) chef-rewind (0.0.9) - chef-sugar (3.3.0) - chef-zero (4.7.0) + chef-sugar (3.4.0) + chef-zero (4.9.0) ffi-yajl (~> 2.2) hashie (>= 2.0, < 4.0) mixlib-log (~> 1.3) rack (< 2) uuidtools (~> 2.1) - cheffish (2.0.4) + cheffish (3.0.0) chef-zero (~> 4.3) - compat_resource - chefspec (4.7.0) - chef (>= 11.14) - fauxhai (~> 3.2) - rspec (~> 3.0) + net-ssh coderay (1.1.1) colorize (0.8.1) - compat_resource (12.10.6) cucumber-core (1.5.0) gherkin (~> 4.0) debug_inspector (0.0.2) @@ -157,17 +166,21 @@ GEM diff-lcs (1.2.5) docile (1.1.5) erubis (2.7.0) + ethon (0.9.0) + ffi (>= 1.3.0) faraday (0.9.2) multipart-post (>= 1.2, < 3) - fauxhai (3.6.0) + faraday_middleware (0.10.0) + faraday (>= 0.7.4, < 0.10) + fauxhai (3.8.0) net-ssh - ffi (1.9.10) - ffi (1.9.10-x86-mingw32) - ffi-win32-extensions (1.0.2) + ffi (1.9.14) + ffi (1.9.14-x86-mingw32) + ffi-win32-extensions (1.0.3) ffi - ffi-yajl (2.2.3) + ffi-yajl (2.3.0) libyajl2 (~> 1.2) - foodcritic (6.3.0) + foodcritic (7.1.0) cucumber-core (>= 1.3) erubis nokogiri (>= 1.5, < 2.0) @@ -175,15 +188,22 @@ GEM rufus-lru (~> 1.0) treetop (~> 1.4) yajl-ruby (~> 1.1) - fuzzyurl (0.8.0) + fuzzyurl (0.9.0) + gh (0.14.0) + addressable + backports + faraday (~> 0.8) + multi_json (~> 1.0) + net-http-persistent (>= 2.7) + net-http-pipeline gherkin (4.0.0) - github_api (0.14.2) + github_api (0.14.5) addressable (~> 2.4.0) descendants_tracker (~> 0.0.4) faraday (~> 0.8, < 0.10) hashie (>= 3.4) - oauth2 - github_changelog_generator (1.12.1) + oauth2 (~> 1.0) + github_changelog_generator (1.13.1) colorize (~> 0.7) github_api (~> 0.12) rake (>= 10.0) @@ -198,17 +218,17 @@ GEM thor hashie (3.4.4) highline (1.7.8) - httpclient (2.8.0) + httpclient (2.8.2.2) inifile (3.0.0) iniparse (1.4.2) ipaddress (0.8.3) - jmespath (1.2.4) - json_pure (>= 1.8.1) + jmespath (1.3.1) json (1.8.3) - json_pure (1.8.3) - jwt (1.5.1) - knife-windows (1.4.1) + jwt (1.5.4) + knife-windows (1.5.0) winrm (~> 1.7) + launchy (2.4.3) + addressable (~> 2.3) libyajl2 (1.2.0) little-plugger (1.1.4) logging (2.1.0) @@ -224,13 +244,13 @@ GEM mixlib-log mixlib-authentication (1.4.1) mixlib-log - mixlib-cli (1.6.0) - mixlib-config (2.2.1) + mixlib-cli (1.7.0) + mixlib-config (2.2.2) mixlib-install (1.1.0) artifactory mixlib-shellout mixlib-versioning - mixlib-log (1.6.0) + mixlib-log (1.7.1) mixlib-shellout (2.2.6) mixlib-shellout (2.2.6-universal-mingw32) win32-process (~> 0.8.2) @@ -239,6 +259,8 @@ GEM multi_json (1.12.1) multi_xml (0.5.5) multipart-post (2.0.0) + net-http-persistent (2.9.4) + net-http-pipeline (1.0.1) net-scp (1.2.1) net-ssh (>= 2.6.5) net-sftp (2.1.2) @@ -258,22 +280,22 @@ GEM mini_portile2 (~> 2.1.0) pkg-config (~> 1.1.7) nori (2.6.0) - oauth2 (1.1.0) + oauth2 (1.2.0) faraday (>= 0.8, < 0.10) - jwt (~> 1.0, < 1.5.2) + jwt (~> 1.0) multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) octokit (4.3.0) sawyer (~> 0.7.0, >= 0.5.3) - ohai (8.17.1) + ohai (8.19.2) chef-config (>= 12.5.0.alpha.1, < 13) ffi (~> 1.9) ffi-yajl (~> 2.2) ipaddress mixlib-cli mixlib-config (~> 2.0) - mixlib-log + mixlib-log (>= 1.7.1, < 2.0) mixlib-shellout (~> 2.0) plist (~> 3.1) systemu (~> 2.6.4) @@ -287,7 +309,7 @@ GEM polyglot (0.3.5) powerpack (0.1.1) proxifier (1.0.3) - pry (0.10.3) + pry (0.10.4) coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) @@ -300,32 +322,35 @@ GEM pry-stack_explorer (0.4.9.2) binding_of_caller (>= 0.7) pry (>= 0.9.11) + pusher-client (0.6.2) + json + websocket (~> 1.0) rack (1.6.4) rainbow (2.1.0) rake (11.2.2) rb-readline (0.5.3) - retryable (2.0.3) - rspec (3.4.0) - rspec-core (~> 3.4.0) - rspec-expectations (~> 3.4.0) - rspec-mocks (~> 3.4.0) - rspec-core (3.4.4) - rspec-support (~> 3.4.0) - rspec-expectations (3.4.0) + retryable (2.0.4) + rspec (3.5.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-core (3.5.2) + rspec-support (~> 3.5.0) + rspec-expectations (3.5.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.4.0) + rspec-support (~> 3.5.0) rspec-its (1.2.0) rspec-core (>= 3.0.0) rspec-expectations (>= 3.0.0) - rspec-mocks (3.4.1) + rspec-mocks (3.5.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.4.0) - rspec-support (3.4.1) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) rspec_junit_formatter (0.2.3) builder (< 4) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (0.39.0) - parser (>= 2.3.0.7, < 3.0) + rubocop (0.42.0) + parser (>= 2.3.1.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) @@ -344,13 +369,13 @@ GEM rspec-its specinfra (~> 2.53) sfl (2.2) - simplecov (0.11.2) + simplecov (0.12.0) docile (~> 1.1.0) - json (~> 1.8) + json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.0) slop (3.6.0) - specinfra (2.59.4) + specinfra (2.61.1) net-scp net-ssh (>= 2.7, < 4.0) net-telnet @@ -362,12 +387,24 @@ GEM systemu (2.6.5) thor (0.19.1) thread_safe (0.3.5) - tomlrb (1.2.2) - treetop (1.6.5) + tomlrb (1.2.3) + travis (1.8.2) + backports + faraday (~> 0.9) + faraday_middleware (~> 0.9, >= 0.9.1) + gh (~> 0.13) + highline (~> 1.6) + launchy (~> 2.1) + pusher-client (~> 0.4) + typhoeus (~> 0.6, >= 0.6.8) + treetop (1.6.8) polyglot (~> 0.3) + typhoeus (0.8.0) + ethon (>= 0.8.0) ubuntu_ami (0.4.1) unicode-display_width (1.1.0) uuidtools (2.1.5) + websocket (1.2.3) win32-api (1.5.3-universal-mingw32) win32-dir (0.5.1) ffi (>= 1.0.0) @@ -398,7 +435,7 @@ GEM rubyntlm (~> 0.6.0) wmi-lite (1.0.0) yajl-ruby (1.2.1) - yard (0.8.7.6) + yard (0.9.5) PLATFORMS ruby @@ -415,26 +452,27 @@ DEPENDENCIES chef-rewind chef-sugar cheffish - chefspec + chefspec! chefstyle! foodcritic github_changelog_generator halite knife-windows netrc + nokogiri octokit poise pry pry-byebug pry-remote pry-stack_explorer - rack (< 2.0) rake rb-readline ruby-prof ruby-shadow simplecov tomlrb + travis yard BUNDLED WITH diff --git a/MAINTAINERS.md b/MAINTAINERS.md index fb82fbf44a..d8fc022bb8 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -7,7 +7,7 @@ file tells you who needs to review your patch - you need a simple majority of ma for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. -Check out [How Chef is Maintained](https://github.com/opscode/chef-rfc/blob/master/rfc030-maintenance-policy.md#how-the-project-is-maintained) for details on the process, how to become +Check out [How Chef is Maintained](https://github.com/chef/chef-rfc/blob/master/rfc030-maintenance-policy.md#how-the-project-is-maintained) for details on the process, how to become a maintainer, lieutenant, or the project lead. # Project Lead diff --git a/MAINTAINERS.toml b/MAINTAINERS.toml index dd05255b03..ca90a72119 100644 --- a/MAINTAINERS.toml +++ b/MAINTAINERS.toml @@ -12,7 +12,7 @@ file tells you who needs to review your patch - you need a simple majority of ma for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. -Check out [How Chef is Maintained](https://github.com/opscode/chef-rfc/blob/master/rfc030-maintenance-policy.md#how-the-project-is-maintained) for details on the process, how to become +Check out [How Chef is Maintained](https://github.com/chef/chef-rfc/blob/master/rfc030-maintenance-policy.md#how-the-project-is-maintained) for details on the process, how to become a maintainer, lieutenant, or the project lead. """ @@ -8,9 +8,7 @@ Want to try Chef? Get started with [learnchef](https://learn.chef.io) * Documentation: [http://docs.chef.io](http://docs.chef.io) * Source: [http://github.com/chef/chef/tree/master](http://github.com/chef/chef/tree/master) * Tickets/Issues: [https://github.com/chef/chef/issues](https://github.com/chef/chef/issues) -* IRC: `#chef` and `#chef-hacking` on Freenode - - Join via browser: [#chef](https://webchat.freenode.net/?channels=chef), [#chef-hacking](https://webchat.freenode.net/?channels=chef-hacking) - - View logs: [#chef](https://botbot.me/freenode/chef/), [#chef-hacking](https://botbot.me/freenode/chef-hacking/) +* Slack: [Chef Community Slack](https://community-slack.chef.io/) * Mailing list: [https://discourse.chef.io](https://discourse.chef.io) Chef is a configuration management tool designed to bring automation to your @@ -38,9 +36,9 @@ Install these via your platform's preferred method (`apt`, `yum`, `ports`, * git * C compiler, header files, etc. On Ubuntu/Debian, use the `build-essential` package. -* ruby 2.0.0 or later +* ruby 2.1.0 or later * rubygems -* bundler +* bundler gem ### Chef Installation @@ -77,10 +75,10 @@ The general development process is: 4. Push your feature branch to github and open a pull request against master. -Once your repository is set up, you can start working on the code. We do use -TDD with RSpec, so you'll need to get a development environment running. -Follow the above procedure ("Installing from Git") to get your local -copy of the source running. +Once your repository is set up, you can start working on the code. We do utilize +RSpec for test driven development, so you'll need to get a development +environment running. Follow the above procedure ("Installing from Git") to get +your local copy of the source running. ## Reporting Issues @@ -142,12 +140,12 @@ Chef is an amalgam of many components. These components update all the time, nec ## Chef Packages -Chef is distributed as packages for debian, rhel, ubuntu, windows and os/x. It includes a large number of components from various sources, and these are versioned and maintained separately from chef project, which bundles them all together conveniently for the user. +Chef is distributed as packages for debian, rhel, ubuntu, windows, solaris, aix, and os x. It includes a large number of components from various sources, and these are versioned and maintained separately from chef project, which bundles them all together conveniently for the user. These packages go through several milestones: - `master`: When code is checked in to master, the patch version of chef is bumped (e.g. 0.9.10 -> 0.9.11) and a build is kicked off automatically to create and test the packages in Chef's Jenkins cluster. - `unstable`: When a package is built, it enters the unstable channel. When all packages for all OS's have successfully built, the test phase is kicked off in Jenkins across all supported OS's. These builds are password-protected and generally only available to the test systems. -- `current`: If the packages pass all the tests on all supported OS's, it is promoted as a unit to `current`, and is available via Chef's artifactory by running `curl https://omnitruck.chef.io/install.sh | sudo bash -s -- -c current -P chef` +- `current`: If the packages pass all the tests on all supported OS's, it is promoted as a unit to `current`, and is available via Chef's artifactory by running `curl https://www.chef.io/chef/install.sh | sudo bash -s -- -c current -P chef` - `stable`: Periodically, Chef will pick a release to "bless" for folks who would like a slower update schedule than "every time a build passes the tests." When this happens, it is manually promoted to stable and an announcement is sent to the list. It can be reached at https://downloads.chef.io or installed using the `curl` command without specifying `-c current`. Packages in `stable` are no longer available in `current`. Additionally, periodically Chef will update the desired versions of chef components and check that in to `master`, triggering a new build with the updated components in it. diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index b3bba87dc0..14e30f1f77 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,35 +1,33 @@ *This file holds "in progress" release notes for the current release under development and is intended for consumption by the Chef Documentation team. Please see `https://docs.chef.io/release/<major>-<minor>/release_notes.html` for the official Chef release notes.* -# Chef Client Release Notes 12.12: - -## Attribute read/write/unlink/exist? APIs - -On the node object: - -- `node.read("foo", "bar", "baz")` equals `node["foo"]["bar"]["baz"] `but with safety (nil instead of exception) -- `node.read!("foo", "bar", "baz")` equals `node["foo"]["bar"]["baz"]` and does raises NoMethodError - -- `node.write(:default, "foo", "bar", "baz")` equals `node.default["foo"]["bar"] = "baz"` and autovivifies and replaces intermediate non-hash objects (very safe) -- `node.write!(:default, "foo", "bar", "baz")` equals `node.default["foo"]["bar"] = "baz"` and while it autovivifies it can raise if you hit a non-hash on an intermediate key (NoMethodError) -- there is still no non-autovivifying writer, and i don't think anyone really wants one. -- `node.exist?("foo", "bar")` can be used to see if `node["foo"]["bar"]` exists - -On node levels: - -- `node.default.read/read!("foo")` operates similarly to `node.read("foo")` but only on default level -- `node.default.write/write!("foo", "bar")` is `node.write/write!(:default, "foo", "bar")` -- `node.default.unlink/unlink!("foo")` is `node.unlink/unlink!(:default, "foo")` -- `node.default.exist?("foo", "bar")` can be used to see if `node.default["foo"]["bar"]` exists - -Deprecations: - -- node.set is deprecated -- node.set_unless is deprecated - -## `data_collector` enhancements - -- Adds `node` to the `data_collector` message -- `data_collector` reports on all resources and not just those that have been processed - -## `knife cookbook create` is deprecated. Use the chef-dk's `chef generate cookbook` instead.
\ No newline at end of file +# Chef Client Release Notes 12.13: + +Highlights for this release: + +- Ohai 8.18 includes a new plugin for gathering available user shells. Additionally for OS X users there is a new hardware plugin that gathers system information, and we’ve added detection of VMware and VirtualBox installations. + +## Updated Dependencies + +- ruby - 2.1.9 (was 2.1.8) + +### Updated Gems + +- chef-zero - 4.8.0 (was 4.7.0) +- cheffish - 2.0.5 (was 2.0.4) +- compat_resource - 12.10.7 (was 12.10.6) +- ffi - 1.9.14 (was 1.9.10) +- ffi-yajl - 2.3.0 (was 2.2.3) +- fuzzyurl - 0.9.0 (was 0.8.0) +- mixlib-cli - 1.7.0 (was 1.6.0) +- mixlib-log - 1.7.0 (was 1.6.0) +- ohai - 8.18.0 (was 8.17.1) +- pry - 0.10.4 (was 0.10.3) +- rspec - 3.5.0 (was 3.4.0) +- rspec-core - 3.5.2 (was 3.4.4) +- rspec-expectations - 3.5.0 (was 3.4.0) +- rspec-mocks - 3.5.0 (was 3.4.1) +- rspec-support - 3.5.0 (was 3.4.1) +- simplecov - 0.12.0 (was 0.11.2) +- specinfra - 2.60.3 (was 2.59.4) +- mixlib-archive - 0.2.0 (added to package) @@ -1 +1 @@ -12.12.24
\ No newline at end of file +12.14.24
\ No newline at end of file diff --git a/acceptance/.gitignore b/acceptance/.gitignore index c2ab70737d..4b0b151d75 100644 --- a/acceptance/.gitignore +++ b/acceptance/.gitignore @@ -1 +1,3 @@ .acceptance_logs +.acceptance_data +data-collector/Berksfile.lock diff --git a/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml b/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml index 40228829bb..dfe3d888a0 100644 --- a/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml +++ b/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml @@ -213,18 +213,7 @@ platforms: image-type: machine user_data: | <powershell> - $logfile="C:\\Program Files\\Amazon\\Ec2ConfigService\\Logs\\kitchen-ec2.log" - #PS Remoting and & winrm.cmd basic config - Enable-PSRemoting -Force -SkipNetworkProfileCheck - & winrm.cmd set winrm/config '@{MaxTimeoutms="1800000"}' >> $logfile - & winrm.cmd set winrm/config/winrs '@{MaxMemoryPerShellMB="1024"}' >> $logfile - & winrm.cmd set winrm/config/winrs '@{MaxShellsPerUser="50"}' >> $logfile - #Server settings - support username/password login - & winrm.cmd set winrm/config/service/auth '@{Basic="true"}' >> $logfile - & winrm.cmd set winrm/config/service '@{AllowUnencrypted="true"}' >> $logfile - & winrm.cmd set winrm/config/winrs '@{MaxMemoryPerShellMB="1024"}' >> $logfile - #Firewall Config - & netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" profile=public protocol=tcp localport=5985 remoteip=localsubnet new remoteip=any >> $logfile + & netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" profile=public protocol=tcp localport=5985 remoteip=localsubnet new remoteip=any #Set script execution to unrestricted & Set-ExecutionPolicy Unrestricted -Force </powershell> diff --git a/acceptance/.shared/kitchen_acceptance/libraries/kitchen.rb b/acceptance/.shared/kitchen_acceptance/libraries/kitchen.rb index c8bcd4ab77..d5d2e1380b 100644 --- a/acceptance/.shared/kitchen_acceptance/libraries/kitchen.rb +++ b/acceptance/.shared/kitchen_acceptance/libraries/kitchen.rb @@ -1,3 +1,5 @@ +require 'chef/mixin/shell_out' + module KitchenAcceptance class Kitchen < Chef::Resource resource_name :kitchen @@ -33,25 +35,32 @@ module KitchenAcceptance property :kitchen_options, String, default: lazy { ENV["PROJECT_NAME"] ? "-c -l debug" : "-c" } action :run do - execute "bundle exec kitchen #{command}#{instances ? " #{instances}" : ""}#{kitchen_options ? " #{kitchen_options}" : ""}" do - cwd kitchen_dir - env({ - "KITCHEN_DRIVER" => driver, - "KITCHEN_INSTANCES" => instances, - "KITCHEN_LOCAL_YAML" => ::File.expand_path("../../.kitchen.#{driver}.yml", __FILE__), - "KITCHEN_CHEF_PRODUCT" => chef_product, - "KITCHEN_CHEF_CHANNEL" => chef_channel, - "KITCHEN_CHEF_VERSION" => chef_version, - "ARTIFACTORY_USERNAME" => artifactory_username, - "ARTIFACTORY_PASSWORD" => artifactory_password - }.merge(new_resource.env)) - end + ruby_block "copy_kitchen_logs_to_data_path" do block do + cmd_env = { + "KITCHEN_DRIVER" => driver, + "KITCHEN_INSTANCES" => instances, + "KITCHEN_LOCAL_YAML" => ::File.expand_path("../../.kitchen.#{driver}.yml", __FILE__), + "KITCHEN_CHEF_PRODUCT" => chef_product, + "KITCHEN_CHEF_CHANNEL" => chef_channel, + "KITCHEN_CHEF_VERSION" => chef_version, + "ARTIFACTORY_USERNAME" => artifactory_username, + "ARTIFACTORY_PASSWORD" => artifactory_password + }.merge(new_resource.env) suite = kitchen_dir.split("/").last - kitchen_log_path = ENV["WORKSPACE"] ? "#{ENV["WORKSPACE"]}/chef-acceptance-data/logs" : "#{kitchen_dir}/../.acceptance_data/logs/kitchen" - FileUtils.mkdir_p("#{kitchen_log_path}/#{suite}") - FileUtils.cp_r("#{kitchen_dir}/.kitchen/logs/", "#{kitchen_log_path}/#{suite}") + kitchen_log_path = ENV["WORKSPACE"] ? "#{ENV["WORKSPACE"]}/chef-acceptance-data/logs" : "#{kitchen_dir}/../.acceptance_data/logs/" + + begin + shell_out!("bundle exec kitchen #{command}#{instances ? " #{instances}" : ""}#{kitchen_options ? " #{kitchen_options}" : ""}", + env: cmd_env, + timeout: 60 * 30, + live_stream: STDOUT, + cwd: kitchen_dir) + ensure + FileUtils.mkdir_p("#{kitchen_log_path}/#{suite}/#{command}") + FileUtils.cp_r("#{kitchen_dir}/.kitchen/logs/.", "#{kitchen_log_path}/#{suite}/#{command}") + end end end end diff --git a/acceptance/Gemfile b/acceptance/Gemfile index 185437ed71..b521df8607 100644 --- a/acceptance/Gemfile +++ b/acceptance/Gemfile @@ -1,13 +1,16 @@ source "https://rubygems.org" gem "chef-acceptance", github: "chef/chef-acceptance" -gem "test-kitchen" gem "kitchen-ec2" -gem "kitchen-inspec" gem "inspec" # Pinning to github for kitchen-vagrant because 0.19.0 incorrectly # puts in a box_url for bento when a vagrant box in atlas is specified gem "kitchen-vagrant" gem "windows_chef_zero" -gem "winrm-fs" +gem "kitchen-inspec", :github => "mwrock/kitchen-inspec", :branch => "winrm-v2" +gem "test-kitchen", :github => "test-kitchen", :branch => "winrm-v2" +gem "train", :github => "chef/train", :branch => "winrm-v2" +gem "winrm", :github => "winrb/winrm", :branch => "winrm-v2" +gem "winrm-fs", :github => "winrb/winrm-fs", :branch => "winrm-v2" +gem "winrm-elevated", :github => "winrb/winrm-elevated", :branch => "winrm-v2" gem "berkshelf" diff --git a/acceptance/Gemfile.lock b/acceptance/Gemfile.lock index 6598e20c17..f4ee7d055a 100644 --- a/acceptance/Gemfile.lock +++ b/acceptance/Gemfile.lock @@ -6,17 +6,88 @@ GIT mixlib-shellout (~> 2.0) thor (~> 0.19) +GIT + remote: git://github.com/chef/train.git + revision: 11ec2db8a2c06757335660a2704ca140b24b7ec3 + branch: winrm-v2 + specs: + train (0.15.1) + docker-api (~> 1.26) + json (~> 1.8) + mixlib-shellout (~> 2.0) + net-scp (~> 1.2) + net-ssh (>= 2.9, < 4.0) + winrm (~> 2.0) + winrm-fs (~> 1.0) + +GIT + remote: git://github.com/mwrock/kitchen-inspec.git + revision: 5c00e1d66fa3b459e0a504ed08d0550c31f35b06 + branch: winrm-v2 + specs: + kitchen-inspec (0.14.0) + inspec (>= 0.22.0, < 1.0.0) + test-kitchen (~> 1.6) + +GIT + remote: git://github.com/test-kitchen/test-kitchen.git + revision: c4b42161729572b95a93468fb8d653d15935bc74 + branch: winrm-v2 + specs: + test-kitchen (1.10.2) + mixlib-install (~> 1.0, >= 1.0.4) + mixlib-shellout (>= 1.2, < 3.0) + net-scp (~> 1.1) + net-ssh (>= 2.9, < 4.0) + safe_yaml (~> 1.0) + thor (~> 0.18) + +GIT + remote: git://github.com/winrb/winrm-elevated.git + revision: fcf1d3490412d780d17ac4db09a9101b9794f6f4 + branch: winrm-v2 + specs: + winrm-elevated (1.0.0) + winrm (~> 2.0) + winrm-fs (~> 1.0) + +GIT + remote: git://github.com/winrb/winrm-fs.git + revision: d8fa7d648d797c434b20d8f45aa91ddb8f2d2c82 + branch: winrm-v2 + specs: + winrm-fs (1.0.0) + erubis (~> 2.7) + logging (>= 1.6.1, < 3.0) + rubyzip (~> 1.1) + winrm + +GIT + remote: git://github.com/winrb/winrm.git + revision: d6ae35d857234676916054344070d601519ec102 + branch: winrm-v2 + specs: + winrm (2.0.0) + builder (>= 2.1.2) + erubis (~> 2.7) + gssapi (~> 1.2) + gyoku (~> 1.0) + httpclient (~> 2.2, >= 2.2.0.2) + logging (>= 1.6.1, < 3.0) + nori (~> 2.0) + rubyntlm (~> 0.6.0) + GEM remote: https://rubygems.org/ specs: addressable (2.4.0) artifactory (2.3.3) - aws-sdk (2.3.18) - aws-sdk-resources (= 2.3.18) - aws-sdk-core (2.3.18) + aws-sdk (2.5.3) + aws-sdk-resources (= 2.5.3) + aws-sdk-core (2.5.3) jmespath (~> 1.0) - aws-sdk-resources (2.3.18) - aws-sdk-core (= 2.3.18) + aws-sdk-resources (2.5.3) + aws-sdk-core (= 2.5.3) berkshelf (4.3.5) addressable (~> 2.3, >= 2.3.4) berkshelf-api-client (~> 2.0, >= 2.0.2) @@ -53,22 +124,22 @@ GEM celluloid-io (0.16.2) celluloid (>= 0.16.0) nio4r (>= 1.1.0) - chef-config (12.11.18) - fuzzyurl (~> 0.8.0) + chef-config (12.13.30) + fuzzyurl mixlib-config (~> 2.0) mixlib-shellout (~> 2.0) cleanroom (1.0.0) coderay (1.1.1) diff-lcs (1.2.5) - docker-api (1.29.0) + docker-api (1.31.0) excon (>= 0.38.0) json erubis (2.7.0) - excon (0.50.1) + excon (0.51.0) faraday (0.9.2) multipart-post (>= 1.2, < 3) - ffi (1.9.10) - fuzzyurl (0.8.0) + ffi (1.9.14) + fuzzyurl (0.9.0) gssapi (1.2.0) ffi (>= 1.0.1) gyoku (1.3.1) @@ -76,7 +147,7 @@ GEM hashie (3.4.4) hitimes (1.2.4) httpclient (2.7.2) - inspec (0.26.0) + inspec (0.28.1) hashie (~> 3.4) json (~> 1.8) method_source (~> 0.8) @@ -86,20 +157,15 @@ GEM rspec-its (~> 1.2) rubyzip (~> 1.1) thor (~> 0.19) - train (~> 0.13) - jmespath (1.2.4) - json_pure (>= 1.8.1) + train (>= 0.15.1, < 1.0) + jmespath (1.3.1) json (1.8.3) - json_pure (1.8.3) - kitchen-ec2 (1.0.0) + kitchen-ec2 (1.1.0) aws-sdk (~> 2) excon multi_json retryable (~> 2.0) test-kitchen (~> 1.4, >= 1.4.1) - kitchen-inspec (0.14.0) - inspec (>= 0.22.0, < 1.0.0) - test-kitchen (~> 1.6) kitchen-vagrant (0.20.0) test-kitchen (~> 1.4) little-plugger (1.1.4) @@ -108,7 +174,8 @@ GEM multi_json (~> 1.10) method_source (0.8.2) minitar (0.5.4) - mixlib-archive (0.1.0) + mixlib-archive (0.2.0) + mixlib-log mixlib-authentication (1.4.1) mixlib-log mixlib-config (2.2.1) @@ -116,7 +183,7 @@ GEM artifactory mixlib-shellout mixlib-versioning - mixlib-log (1.6.0) + mixlib-log (1.7.1) mixlib-shellout (2.2.6) mixlib-versioning (1.1.0) molinillo (0.4.5) @@ -129,17 +196,17 @@ GEM nori (2.6.0) octokit (4.3.0) sawyer (~> 0.7.0, >= 0.5.3) - pry (0.10.3) + pry (0.10.4) coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) rainbow (2.1.0) - retryable (2.0.3) - ridley (4.5.1) + retryable (2.0.4) + ridley (4.6.1) addressable buff-config (~> 1.0) buff-extensions (~> 1.0) - buff-ignore (~> 1.1) + buff-ignore (~> 1.1.1) buff-shell_out (~> 0.1) celluloid (~> 0.16.0) celluloid-io (~> 0.16.1) @@ -153,22 +220,22 @@ GEM retryable (~> 2.0) semverse (~> 1.1) varia_model (~> 0.4.0) - rspec (3.4.0) - rspec-core (~> 3.4.0) - rspec-expectations (~> 3.4.0) - rspec-mocks (~> 3.4.0) - rspec-core (3.4.4) - rspec-support (~> 3.4.0) - rspec-expectations (3.4.0) + rspec (3.5.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-core (3.5.2) + rspec-support (~> 3.5.0) + rspec-expectations (3.5.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.4.0) + rspec-support (~> 3.5.0) rspec-its (1.2.0) rspec-core (>= 3.0.0) rspec-expectations (>= 3.0.0) - rspec-mocks (3.4.1) + rspec-mocks (3.5.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.4.0) - rspec-support (3.4.1) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) rubyntlm (0.6.0) rubyzip (1.2.0) safe_yaml (1.0.4) @@ -180,42 +247,14 @@ GEM solve (2.0.3) molinillo (~> 0.4.2) semverse (~> 1.1) - test-kitchen (1.10.2) - mixlib-install (~> 1.0, >= 1.0.4) - mixlib-shellout (>= 1.2, < 3.0) - net-scp (~> 1.1) - net-ssh (>= 2.9, < 4.0) - safe_yaml (~> 1.0) - thor (~> 0.18) thor (0.19.1) timers (4.0.4) hitimes - train (0.14.2) - docker-api (~> 1.26) - json (~> 1.8) - mixlib-shellout (~> 2.0) - net-scp (~> 1.2) - net-ssh (>= 2.9, < 4.0) - winrm (~> 1.6) - winrm-fs (~> 0.3) varia_model (0.4.1) buff-extensions (~> 1.0) hashie (>= 2.0.2, < 4.0.0) windows_chef_zero (2.0.0) test-kitchen (>= 1.2.1) - winrm (1.8.1) - builder (>= 2.1.2) - gssapi (~> 1.2) - gyoku (~> 1.0) - httpclient (~> 2.2, >= 2.2.0.2) - logging (>= 1.6.1, < 3.0) - nori (~> 2.0) - rubyntlm (~> 0.6.0) - winrm-fs (0.4.3) - erubis (~> 2.7) - logging (>= 1.6.1, < 3.0) - rubyzip (~> 1.1) - winrm (~> 1.5) PLATFORMS ruby @@ -225,11 +264,14 @@ DEPENDENCIES chef-acceptance! inspec kitchen-ec2 - kitchen-inspec + kitchen-inspec! kitchen-vagrant - test-kitchen + test-kitchen! + train! windows_chef_zero - winrm-fs + winrm! + winrm-elevated! + winrm-fs! BUNDLED WITH 1.12.5 diff --git a/acceptance/basics/test/integration/helpers/serverspec/Gemfile b/acceptance/basics/test/integration/helpers/serverspec/Gemfile new file mode 100644 index 0000000000..b56d1e1298 --- /dev/null +++ b/acceptance/basics/test/integration/helpers/serverspec/Gemfile @@ -0,0 +1,8 @@ +source "https://rubygems.org" + +# Until https://github.com/test-kitchen/busser-serverspec/pull/42 is merged and +# released, we need to include rake and rspec-core in the Gemfile +gem "rake" +gem "rspec-core" +gem "busser-serverspec" +gem "serverspec" diff --git a/acceptance/data-collector/Berksfile.lock b/acceptance/data-collector/Berksfile.lock deleted file mode 100644 index 39f4ce30dc..0000000000 --- a/acceptance/data-collector/Berksfile.lock +++ /dev/null @@ -1,6 +0,0 @@ -DEPENDENCIES - data-collector-test - path: .acceptance/data-collector-test - -GRAPH - data-collector-test (0.1.0) diff --git a/acceptance/data-collector/test/integration/helpers/serverspec/Gemfile b/acceptance/data-collector/test/integration/helpers/serverspec/Gemfile new file mode 100644 index 0000000000..b56d1e1298 --- /dev/null +++ b/acceptance/data-collector/test/integration/helpers/serverspec/Gemfile @@ -0,0 +1,8 @@ +source "https://rubygems.org" + +# Until https://github.com/test-kitchen/busser-serverspec/pull/42 is merged and +# released, we need to include rake and rspec-core in the Gemfile +gem "rake" +gem "rspec-core" +gem "busser-serverspec" +gem "serverspec" diff --git a/acceptance/fips/test/integration/fips-integration/serverspec/Gemfile b/acceptance/fips/test/integration/fips-integration/serverspec/Gemfile index 3921e6a92a..d297c4314d 100644 --- a/acceptance/fips/test/integration/fips-integration/serverspec/Gemfile +++ b/acceptance/fips/test/integration/fips-integration/serverspec/Gemfile @@ -1,3 +1,9 @@ source "https://rubygems.org" +# Until https://github.com/test-kitchen/busser-serverspec/pull/42 is merged and +# released, we need to include rake and rspec-core in the Gemfile +gem "rake" +gem "rspec-core" +gem "busser-serverspec" +gem "serverspec" gem "mixlib-shellout" diff --git a/acceptance/fips/test/integration/fips-unit-functional/serverspec/Gemfile b/acceptance/fips/test/integration/fips-unit-functional/serverspec/Gemfile index 3921e6a92a..03c7a9e657 100644 --- a/acceptance/fips/test/integration/fips-unit-functional/serverspec/Gemfile +++ b/acceptance/fips/test/integration/fips-unit-functional/serverspec/Gemfile @@ -1,3 +1,7 @@ source "https://rubygems.org" +# Until https://github.com/test-kitchen/busser-serverspec/pull/42 is merged and +# released, we need to include rake and rspec-core in the Gemfile +gem "rake" +gem "rspec-core" gem "mixlib-shellout" diff --git a/acceptance/top-cookbooks/.acceptance/acceptance-cookbook/libraries/top_cookbooks.rb b/acceptance/top-cookbooks/.acceptance/acceptance-cookbook/libraries/top_cookbooks.rb index 203ea9809a..73f5151bca 100644 --- a/acceptance/top-cookbooks/.acceptance/acceptance-cookbook/libraries/top_cookbooks.rb +++ b/acceptance/top-cookbooks/.acceptance/acceptance-cookbook/libraries/top_cookbooks.rb @@ -3,6 +3,8 @@ class TopCookbooks < Chef::Resource property :command, String, name_property: true + # Disabling all windows tests until winrm issue is properly settled. + # action :run do cookbook_kitchen "#{command} docker" do end @@ -33,8 +35,6 @@ class TopCookbooks < Chef::Resource repository "adamedx/winbox" end - # Temporarily disabling windows and chocolatey to eliminate - # transient errors on the builders # cookbook_kitchen "#{command} windows" do # end diff --git a/acceptance/trivial/.kitchen.yml b/acceptance/trivial/.kitchen.yml index 1e0af03503..0db67c468f 100644 --- a/acceptance/trivial/.kitchen.yml +++ b/acceptance/trivial/.kitchen.yml @@ -3,5 +3,5 @@ verifier: suites: - name: chef-current-install - includes: [windows-2012r2] + includes: [ubuntu-14.04, windows-server-2012r2] run_list: diff --git a/acceptance/windows-service/.acceptance/acceptance-cookbook/recipes/destroy.rb b/acceptance/windows-service/.acceptance/acceptance-cookbook/recipes/destroy.rb index e2d663ac2f..e12f938cf3 100644 --- a/acceptance/windows-service/.acceptance/acceptance-cookbook/recipes/destroy.rb +++ b/acceptance/windows-service/.acceptance/acceptance-cookbook/recipes/destroy.rb @@ -1 +1 @@ -kitchen "destroy" +#kitchen "destroy" diff --git a/acceptance/windows-service/.acceptance/acceptance-cookbook/recipes/provision.rb b/acceptance/windows-service/.acceptance/acceptance-cookbook/recipes/provision.rb index 5726c0e7b5..cec9de4e5d 100644 --- a/acceptance/windows-service/.acceptance/acceptance-cookbook/recipes/provision.rb +++ b/acceptance/windows-service/.acceptance/acceptance-cookbook/recipes/provision.rb @@ -1 +1 @@ -kitchen "converge" +#kitchen "converge" diff --git a/acceptance/windows-service/.acceptance/acceptance-cookbook/recipes/verify.rb b/acceptance/windows-service/.acceptance/acceptance-cookbook/recipes/verify.rb index 05ac94ce66..52e3560cf6 100644 --- a/acceptance/windows-service/.acceptance/acceptance-cookbook/recipes/verify.rb +++ b/acceptance/windows-service/.acceptance/acceptance-cookbook/recipes/verify.rb @@ -1 +1 @@ -kitchen "verify" +#kitchen "verify" diff --git a/acceptance/windows-service/test/integration/chef-windows-service/inspec/chef_windows_service_spec.rb b/acceptance/windows-service/test/integration/chef-windows-service/inspec/chef_windows_service_spec.rb index a791177362..75383b69bf 100644 --- a/acceptance/windows-service/test/integration/chef-windows-service/inspec/chef_windows_service_spec.rb +++ b/acceptance/windows-service/test/integration/chef-windows-service/inspec/chef_windows_service_spec.rb @@ -13,7 +13,7 @@ describe service("chef-client") do it { should_not be_running } end -describe command("chef-service-manager -a install") do +describe command("/opscode/chef/bin/chef-service-manager.bat -a install") do its("exit_status") { should eq 0 } its(:stdout) { should match /Service 'chef-client' has successfully been installed./ } end @@ -24,7 +24,7 @@ describe service("chef-client") do it { should_not be_running } end -describe command("chef-service-manager -a start") do +describe command("/opscode/chef/bin/chef-service-manager.bat -a start") do its("exit_status") { should eq 0 } its(:stdout) { should match /Service 'chef-client' is now 'running'/ } end @@ -35,7 +35,7 @@ describe service("chef-client") do it { should be_running } end -describe command("chef-service-manager -a stop") do +describe command("/opscode/chef/bin/chef-service-manager.bat -a stop") do its("exit_status") { should eq 0 } its(:stdout) { should match /Service 'chef-client' is now 'stopped'/ } end @@ -46,7 +46,7 @@ describe service("chef-client") do it { should_not be_running } end -describe command("chef-service-manager -a uninstall") do +describe command("/opscode/chef/bin/chef-service-manager.bat -a uninstall") do its("exit_status") { should eq 0 } its(:stdout) { should match /Service chef-client deleted/ } end diff --git a/appveyor.yml b/appveyor.yml index 7d89df1eb3..831ecf67e5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,9 +6,8 @@ platform: environment: matrix: - # 21-x64 is failing right now - #- ruby_version: "21-x64" - - ruby_version: "21" + - ruby_version: "23-x64" + - ruby_version: "23" clone_folder: c:\projects\chef clone_depth: 1 diff --git a/chef-config/chef-config.gemspec b/chef-config/chef-config.gemspec index 307112126e..9e40528fba 100644 --- a/chef-config/chef-config.gemspec +++ b/chef-config/chef-config.gemspec @@ -17,7 +17,8 @@ Gem::Specification.new do |spec| spec.add_dependency "mixlib-shellout", "~> 2.0" spec.add_dependency "mixlib-config", "~> 2.0" - spec.add_dependency "fuzzyurl", "~> 0.8.0" + spec.add_dependency "fuzzyurl" + spec.add_dependency "addressable" spec.add_development_dependency "rake", "~> 10.0" diff --git a/chef-config/lib/chef-config/config.rb b/chef-config/lib/chef-config/config.rb index a194edc80e..f46419937a 100644 --- a/chef-config/lib/chef-config/config.rb +++ b/chef-config/lib/chef-config/config.rb @@ -30,6 +30,7 @@ require "chef-config/mixin/fuzzy_hostname_matcher" require "mixlib/shellout" require "uri" +require "addressable/uri" require "openssl" module ChefConfig @@ -791,6 +792,11 @@ module ChefConfig default :normal_attribute_whitelist, nil default :override_attribute_whitelist, nil + # Pull down all the rubygems versions from rubygems and cache them the first time we do a gem_package or + # chef_gem install. This is memory-expensive and will grow without bounds, but will reduce network + # round trips. + default :rubygems_cache_enabled, false + config_context :windows_service do # Set `watchdog_timeout` to the number of seconds to wait for a chef-client run # to finish @@ -865,6 +871,13 @@ module ChefConfig export_no_proxy(no_proxy) if no_proxy end + # Character classes for Addressable + # See https://www.ietf.org/rfc/rfc3986.txt 3.2.1 + # The user part may not have a : in it + USER = Addressable::URI::CharacterClasses::UNRESERVED + Addressable::URI::CharacterClasses::SUB_DELIMS + # The password part may have any valid USERINFO characters + PASSWORD = USER + "\\:" + # Builds a proxy uri and exports it to the appropriate environment variables. Examples: # http://username:password@hostname:port # https://username@hostname:port @@ -879,19 +892,17 @@ module ChefConfig path = "#{scheme}://#{path}" unless path.include?("://") # URI.split returns the following parts: # [scheme, userinfo, host, port, registry, path, opaque, query, fragment] - parts = URI.split(URI.encode(path)) - # URI::Generic.build requires an integer for the port, but URI::split gives - # returns a string for the port. - parts[3] = parts[3].to_i if parts[3] + uri = Addressable::URI.encode(path, Addressable::URI) + if user && !user.empty? - userinfo = URI.encode(URI.encode(user), "@:") + userinfo = Addressable::URI.encode_component(user, USER) if pass - userinfo << ":#{URI.encode(URI.encode(pass), '@:')}" + userinfo << ":#{Addressable::URI.encode_component(pass, PASSWORD)}" end - parts[1] = userinfo + uri.userinfo = userinfo end - path = URI::Generic.build(parts).to_s + path = uri.to_s ENV["#{scheme}_proxy".downcase] = path unless ENV["#{scheme}_proxy".downcase] ENV["#{scheme}_proxy".upcase] = path unless ENV["#{scheme}_proxy".upcase] end diff --git a/chef-config/lib/chef-config/mixin/fuzzy_hostname_matcher.rb b/chef-config/lib/chef-config/mixin/fuzzy_hostname_matcher.rb index c4d9185d81..6dd678840a 100644 --- a/chef-config/lib/chef-config/mixin/fuzzy_hostname_matcher.rb +++ b/chef-config/lib/chef-config/mixin/fuzzy_hostname_matcher.rb @@ -21,9 +21,9 @@ module ChefConfig module FuzzyHostnameMatcher def fuzzy_hostname_match_any?(hostname, matches) - return matches.to_s.split(/\s*,\s*/).compact.any? { - |m| fuzzy_hostname_match?(hostname, m) - } if (hostname != nil) && (matches != nil) + return matches.to_s.split(/\s*,\s*/).compact.any? do |m| + fuzzy_hostname_match?(hostname, m) + end if (hostname != nil) && (matches != nil) false end diff --git a/chef-config/lib/chef-config/package_task.rb b/chef-config/lib/chef-config/package_task.rb index eb257ff4b5..de830c09d3 100644 --- a/chef-config/lib/chef-config/package_task.rb +++ b/chef-config/lib/chef-config/package_task.rb @@ -182,7 +182,7 @@ module ChefConfig IO.write(version_file_path, new_version) end - def update_version_rb + def update_version_rb # rubocop:disable Lint/NestedMethodDefinition puts "Updating #{version_rb_path} to include version #{version} ..." contents = <<-VERSION_RB # Copyright:: Copyright 2010-2016, Chef Software, Inc. @@ -223,7 +223,7 @@ end IO.write(version_rb_path, contents) end - def update_gemfile_lock + def update_gemfile_lock # rubocop:disable Lint/NestedMethodDefinition if File.exist?(gemfile_lock_path) puts "Updating #{gemfile_lock_path} to include version #{version} ..." contents = IO.read(gemfile_lock_path) diff --git a/chef-config/lib/chef-config/version.rb b/chef-config/lib/chef-config/version.rb index c082a79274..b845636d21 100644 --- a/chef-config/lib/chef-config/version.rb +++ b/chef-config/lib/chef-config/version.rb @@ -21,7 +21,7 @@ module ChefConfig CHEFCONFIG_ROOT = File.expand_path("../..", __FILE__) - VERSION = "12.12.24" + VERSION = "12.14.24" end # diff --git a/chef.gemspec b/chef.gemspec index b65332bb91..ff30872b9d 100644 --- a/chef.gemspec +++ b/chef.gemspec @@ -13,11 +13,11 @@ Gem::Specification.new do |s| s.email = "adam@chef.io" s.homepage = "http://www.chef.io" - s.required_ruby_version = ">= 2.1.0" + s.required_ruby_version = ">= 2.2.0" s.add_dependency "chef-config", "= #{Chef::VERSION}" - s.add_dependency "mixlib-cli", "~> 1.4" + s.add_dependency "mixlib-cli", "~> 1.7" s.add_dependency "mixlib-log", "~> 1.3" s.add_dependency "mixlib-authentication", "~> 1.4" s.add_dependency "mixlib-shellout", "~> 2.0" @@ -32,13 +32,14 @@ Gem::Specification.new do |s| s.add_dependency "erubis", "~> 2.7" s.add_dependency "diff-lcs", "~> 1.2", ">= 1.2.4" - s.add_dependency "chef-zero", "~> 4.5" + s.add_dependency "chef-zero", "~> 4.8" s.add_dependency "plist", "~> 3.2" s.add_dependency "iniparse", "~> 1.4" + s.add_dependency "addressable" # Audit mode requires these, so they are non-developmental dependencies now - %w{rspec-core rspec-expectations rspec-mocks}.each { |gem| s.add_dependency gem, "~> 3.4.0" } + %w{rspec-core rspec-expectations rspec-mocks}.each { |gem| s.add_dependency gem, "~> 3.5" } s.add_dependency "rspec_junit_formatter", "~> 0.2.0" s.add_dependency "serverspec", "~> 2.7" s.add_dependency "specinfra", "~> 2.10" diff --git a/kitchen-tests/.kitchen.travis.yml b/kitchen-tests/.kitchen.travis.yml index 99486928de..9c5854d923 100644 --- a/kitchen-tests/.kitchen.travis.yml +++ b/kitchen-tests/.kitchen.travis.yml @@ -10,7 +10,7 @@ transport: provisioner: name: chef_github root_path: /opt/kitchen - chef_version: latest + require_chef_omnibus: latest chef_omnibus_url: "https://omnitruck.chef.io/install.sh" chef_omnibus_install_options: "-c current" github_owner: "chef" @@ -24,6 +24,7 @@ provisioner: verifier: name: inspec + format: progress platforms: - name: debian-7 @@ -32,7 +33,7 @@ platforms: pid_one_command: /sbin/init intermediate_instructions: - RUN /usr/bin/apt-get update - - RUN /usr/bin/apt-get -y install zlib1g-dev sudo net-tools + - RUN /usr/bin/apt-get -y install zlib1g-dev sudo net-tools wget ca-certificates - RUN /bin/mkdir /var/run/sshd - name: debian-8 @@ -41,7 +42,7 @@ platforms: pid_one_command: /bin/systemd intermediate_instructions: - RUN /usr/bin/apt-get update - - RUN /usr/bin/apt-get -y install zlib1g-dev sudo net-tools + - RUN /usr/bin/apt-get -y install zlib1g-dev sudo net-tools wget ca-certificates - name: centos-5 driver: @@ -50,7 +51,7 @@ platforms: run_command: /sbin/init intermediate_instructions: - RUN yum clean all - - RUN yum install -y which initscripts net-tools sudo + - RUN yum install -y which initscripts net-tools sudo wget - RUN sed -i -e "s/Defaults.*requiretty.*/Defaults !requiretty/g" /etc/sudoers - name: centos-6 @@ -59,7 +60,7 @@ platforms: run_command: /sbin/init intermediate_instructions: - RUN yum clean all - - RUN yum -y install which initscripts net-tools sudo + - RUN yum -y install which initscripts net-tools sudo wget - RUN sed -i -e "s/Defaults.*requiretty.*/Defaults !requiretty/g" /etc/sudoers - name: centos-7 @@ -68,7 +69,7 @@ platforms: pid_one_command: /usr/lib/systemd/systemd intermediate_instructions: - RUN yum clean all - - RUN yum -y install which initscripts net-tools sudo + - RUN yum -y install which initscripts net-tools sudo wget - RUN sed -i -e "s/Defaults.*requiretty.*/Defaults !requiretty/g" /etc/sudoers - name: fedora-23 @@ -76,7 +77,7 @@ platforms: image: fedora:23 pid_one_command: /usr/lib/systemd/systemd intermediate_instructions: - - RUN dnf -y install yum which initscripts rpm-build zlib-devel net-tools sudo + - RUN dnf -y install yum which initscripts rpm-build zlib-devel net-tools sudo wget - RUN sed -i -e "s/Defaults.*requiretty.*/Defaults !requiretty/g" /etc/sudoers - name: ubuntu-12.04 @@ -85,7 +86,7 @@ platforms: pid_one_command: /sbin/init intermediate_instructions: - RUN /usr/bin/apt-get update - - RUN /usr/bin/apt-get -y install zlib1g-dev sudo net-tools + - RUN /usr/bin/apt-get -y install zlib1g-dev sudo net-tools wget ca-certificates - name: ubuntu-14.04 driver: @@ -93,7 +94,7 @@ platforms: pid_one_command: /sbin/init intermediate_instructions: - RUN /usr/bin/apt-get update - - RUN /usr/bin/apt-get -y install zlib1g-dev sudo net-tools + - RUN /usr/bin/apt-get -y install zlib1g-dev sudo net-tools wget ca-certificates - name: ubuntu-16.04 driver: @@ -101,7 +102,7 @@ platforms: pid_one_command: /bin/systemd intermediate_instructions: - RUN /usr/bin/apt-get update - - RUN /usr/bin/apt-get -y install zlib1g-dev sudo net-tools + - RUN /usr/bin/apt-get -y install zlib1g-dev sudo net-tools wget ca-certificates - name: opensuse-13.2 driver: diff --git a/kitchen-tests/.kitchen.yml b/kitchen-tests/.kitchen.yml index c02ea55a02..314857663e 100644 --- a/kitchen-tests/.kitchen.yml +++ b/kitchen-tests/.kitchen.yml @@ -7,6 +7,7 @@ driver: verifier: name: inspec + format: progress provisioner: name: chef_github diff --git a/kitchen-tests/Berksfile.lock b/kitchen-tests/Berksfile.lock index 79bb375d05..ba701180a8 100644 --- a/kitchen-tests/Berksfile.lock +++ b/kitchen-tests/Berksfile.lock @@ -12,7 +12,7 @@ GRAPH apache2 (3.2.2) apt (4.0.1) compat_resource (>= 12.10) - aws (3.3.3) + aws (3.4.1) ohai (>= 2.1.0) base (0.1.0) apt (>= 0.0.0) @@ -30,19 +30,19 @@ GRAPH ubuntu (>= 0.0.0) users (>= 0.0.0) yum-epel (>= 0.0.0) - build-essential (6.0.0) + build-essential (6.0.3) compat_resource (>= 12.10) mingw (>= 1.1) seven_zip (>= 0.0.0) - chef-client (4.6.0) + chef-client (5.0.0) cron (>= 1.7.0) logrotate (>= 1.9.0) windows (>= 1.42.0) - chef-sugar (3.3.0) + chef-sugar (3.4.0) chef_handler (1.4.0) chef_hostname (0.4.1) compat_resource (>= 0.0.0) - compat_resource (12.10.6) + compat_resource (12.10.7) cron (1.7.6) database (2.3.1) aws (>= 0.0.0) @@ -50,11 +50,12 @@ GRAPH mysql-chef_gem (~> 0.0) postgresql (>= 1.0.0) xfs (>= 0.0.0) - iis (4.1.8) + iis (4.2.0) windows (>= 1.34.6) iptables (2.2.0) - logrotate (1.9.2) - mingw (1.2.2) + logrotate (2.1.0) + compat_resource (>= 0.0.0) + mingw (1.2.4) compat_resource (>= 0.0.0) seven_zip (>= 0.0.0) multipackage (3.0.28) @@ -68,7 +69,7 @@ GRAPH compat_resource (>= 0.0.0) ntp (2.0.0) windows (>= 1.38.0) - ohai (4.1.1) + ohai (4.2.0) compat_resource (>= 12.10) openssh (2.0.0) iptables (>= 1.0) @@ -89,16 +90,16 @@ GRAPH selinux (0.9.0) seven_zip (2.0.1) windows (>= 1.2.2) - sudo (2.9.0) + sudo (2.11.0) ubuntu (1.2.0) apt (>= 0.0.0) - users (2.0.3) + users (3.0.0) webapp (0.1.0) apache2 (~> 3.2.2) database (~> 2.3.1) mysql (~> 5.6.3) php (~> 1.5.0) - windows (1.44.0) + windows (1.44.1) chef_handler (>= 0.0.0) xfs (2.0.1) xml (2.0.0) @@ -107,5 +108,5 @@ GRAPH yum (3.11.0) yum-epel (0.7.0) yum (>= 3.6.3) - yum-mysql-community (0.2.0) + yum-mysql-community (0.3.0) yum (>= 3.2) diff --git a/kitchen-tests/Gemfile.lock b/kitchen-tests/Gemfile.lock index 8ab7fbe707..ae06da2504 100644 --- a/kitchen-tests/Gemfile.lock +++ b/kitchen-tests/Gemfile.lock @@ -2,14 +2,14 @@ GEM remote: https://rubygems.org/ specs: addressable (2.4.0) - artifactory (2.3.2) - aws-sdk (2.3.9) - aws-sdk-resources (= 2.3.9) - aws-sdk-core (2.3.9) + artifactory (2.3.3) + aws-sdk (2.5.3) + aws-sdk-resources (= 2.5.3) + aws-sdk-core (2.5.3) jmespath (~> 1.0) - aws-sdk-resources (2.3.9) - aws-sdk-core (= 2.3.9) - berkshelf (4.3.3) + aws-sdk-resources (2.5.3) + aws-sdk-core (= 2.5.3) + berkshelf (4.3.5) addressable (~> 2.3, >= 2.3.4) berkshelf-api-client (~> 2.0, >= 2.0.2) buff-config (~> 1.0) @@ -21,6 +21,7 @@ GEM faraday (~> 0.9) httpclient (~> 2.7) minitar (~> 0.5, >= 0.5.4) + mixlib-archive (~> 0.1) octokit (~> 4.0) retryable (~> 2.0) ridley (~> 4.5) @@ -44,22 +45,23 @@ GEM celluloid-io (0.16.2) celluloid (>= 0.16.0) nio4r (>= 1.1.0) - chef-config (12.10.24) - fuzzyurl (~> 0.8.0) + chef-config (12.13.30) + fuzzyurl mixlib-config (~> 2.0) mixlib-shellout (~> 2.0) cleanroom (1.0.0) coderay (1.1.1) diff-lcs (1.2.5) - docker-api (1.26.2) + docker-api (1.31.0) excon (>= 0.38.0) json erubis (2.7.0) - excon (0.49.0) + excon (0.51.0) faraday (0.9.2) multipart-post (>= 1.2, < 3) - ffi (1.9.10) - fuzzyurl (0.8.0) + ffi (1.9.14) + ffi (1.9.14-x86-mingw32) + fuzzyurl (0.9.0) gssapi (1.2.0) ffi (>= 1.0.1) gyoku (1.3.1) @@ -68,32 +70,30 @@ GEM hitimes (1.2.4) hitimes (1.2.4-x86-mingw32) httpclient (2.7.2) - inspec (0.22.1) + inspec (0.29.0) hashie (~> 3.4) json (~> 1.8) method_source (~> 0.8) pry (~> 0) - r-train (~> 0.12) rainbow (~> 2) rspec (~> 3) rspec-its (~> 1.2) rubyzip (~> 1.1) thor (~> 0.19) - jmespath (1.2.4) - json_pure (>= 1.8.1) + train (>= 0.16.0, < 1.0) + jmespath (1.3.1) json (1.8.3) - json_pure (1.8.3) kitchen-appbundle-updater (0.1.2) - kitchen-dokken (0.0.29) - docker-api (~> 1.26.2) + kitchen-dokken (0.0.32) + docker-api (~> 1.29) test-kitchen (~> 1.5) - kitchen-ec2 (1.0.0) + kitchen-ec2 (1.1.0) aws-sdk (~> 2) excon multi_json retryable (~> 2.0) test-kitchen (~> 1.4, >= 1.4.1) - kitchen-inspec (0.14.0) + kitchen-inspec (0.15.0) inspec (>= 0.22.0, < 1.0.0) test-kitchen (~> 1.6) kitchen-vagrant (0.20.0) @@ -104,17 +104,16 @@ GEM multi_json (~> 1.10) method_source (0.8.2) minitar (0.5.4) - mixlib-authentication (1.4.0) + mixlib-archive (0.2.0) + mixlib-log + mixlib-authentication (1.4.1) mixlib-log - rspec-core (~> 3.2) - rspec-expectations (~> 3.2) - rspec-mocks (~> 3.2) mixlib-config (2.2.1) - mixlib-install (1.0.12) + mixlib-install (1.1.0) artifactory mixlib-shellout mixlib-versioning - mixlib-log (1.6.0) + mixlib-log (1.7.1) mixlib-shellout (2.2.6) mixlib-shellout (2.2.6-universal-mingw32) win32-process (~> 0.8.2) @@ -125,30 +124,22 @@ GEM multipart-post (2.0.0) net-scp (1.2.1) net-ssh (>= 2.6.5) - net-ssh (3.1.1) + net-ssh (3.2.0) nio4r (1.2.1) nori (2.6.0) octokit (4.3.0) sawyer (~> 0.7.0, >= 0.5.3) - pry (0.10.3) + pry (0.10.4) coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) - r-train (0.12.1) - docker-api (~> 1.26) - json (~> 1.8) - mixlib-shellout (~> 2.0) - net-scp (~> 1.2) - net-ssh (>= 2.9, < 4.0) - winrm (~> 1.6) - winrm-fs (~> 0.3) rainbow (2.1.0) - retryable (2.0.3) - ridley (4.5.1) + retryable (2.0.4) + ridley (4.6.1) addressable buff-config (~> 1.0) buff-extensions (~> 1.0) - buff-ignore (~> 1.1) + buff-ignore (~> 1.1.1) buff-shell_out (~> 0.1) celluloid (~> 0.16.0) celluloid-io (~> 0.16.1) @@ -162,22 +153,22 @@ GEM retryable (~> 2.0) semverse (~> 1.1) varia_model (~> 0.4.0) - rspec (3.4.0) - rspec-core (~> 3.4.0) - rspec-expectations (~> 3.4.0) - rspec-mocks (~> 3.4.0) - rspec-core (3.4.4) - rspec-support (~> 3.4.0) - rspec-expectations (3.4.0) + rspec (3.5.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) + rspec-core (3.5.2) + rspec-support (~> 3.5.0) + rspec-expectations (3.5.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.4.0) + rspec-support (~> 3.5.0) rspec-its (1.2.0) rspec-core (>= 3.0.0) rspec-expectations (>= 3.0.0) - rspec-mocks (3.4.1) + rspec-mocks (3.5.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.4.0) - rspec-support (3.4.1) + rspec-support (~> 3.5.0) + rspec-support (3.5.0) rubyntlm (0.6.0) rubyzip (1.2.0) safe_yaml (1.0.4) @@ -189,7 +180,7 @@ GEM solve (2.0.3) molinillo (~> 0.4.2) semverse (~> 1.1) - test-kitchen (1.9.0) + test-kitchen (1.10.2) mixlib-install (~> 1.0, >= 1.0.4) mixlib-shellout (>= 1.2, < 3.0) net-scp (~> 1.1) @@ -199,6 +190,14 @@ GEM thor (0.19.1) timers (4.0.4) hitimes + train (0.16.0) + docker-api (~> 1.26) + json (~> 1.8) + mixlib-shellout (~> 2.0) + net-scp (~> 1.2) + net-ssh (>= 2.9, < 4.0) + winrm (~> 1.6) + winrm-fs (~> 0.3) vagrant-wrapper (2.0.3) varia_model (0.4.1) buff-extensions (~> 1.0) @@ -213,7 +212,7 @@ GEM logging (>= 1.6.1, < 3.0) nori (~> 2.0) rubyntlm (~> 0.6.0) - winrm-fs (0.4.2) + winrm-fs (0.4.3) erubis (~> 2.7) logging (>= 1.6.1, < 3.0) rubyzip (~> 1.1) diff --git a/lib/chef/application.rb b/lib/chef/application.rb index f8df71f723..f9735a3769 100644 --- a/lib/chef/application.rb +++ b/lib/chef/application.rb @@ -28,6 +28,7 @@ require "mixlib/cli" require "tmpdir" require "rbconfig" require "chef/application/exit_code" +require "yaml" class Chef class Application @@ -108,7 +109,22 @@ class Chef config_content = config_fetcher.read_config apply_config(config_content, config[:config_file]) end + extra_config_options = config.delete(:config_option) Chef::Config.merge!(config) + if extra_config_options + extra_parsed_options = extra_config_options.inject({}) do |memo, option| + # Sanity check value. + Chef::Application.fatal!("Unparsable config option #{option.inspect}") if option.empty? || !option.include?("=") + # Split including whitespace if someone does truly odd like + # --config-option "foo = bar" + key, value = option.split(/\s*=\s*/, 2) + # Call to_sym because Chef::Config expects only symbol keys. Also + # runs a simple parse on the string for some common types. + memo[key.to_sym] = YAML.safe_load(value) + memo + end + Chef::Config.merge!(extra_parsed_options) + end end def set_specific_recipes @@ -332,6 +348,13 @@ class Chef class << self def debug_stacktrace(e) message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}" + + cause = e.cause if e.respond_to?(:cause) + while cause != nil + message << "\n\n>>>> Caused by #{cause.class}: #{cause}\n#{cause.backtrace.join("\n")}" + cause = cause.respond_to?(:cause) ? cause.cause : nil + end + chef_stacktrace_out = "Generated at #{Time.now}\n" chef_stacktrace_out += message diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb index 2a2f70c3a1..cbaa494b71 100644 --- a/lib/chef/application/client.rb +++ b/lib/chef/application/client.rb @@ -41,6 +41,14 @@ class Chef::Application::Client < Chef::Application :long => "--config CONFIG", :description => "The configuration file to use" + option :config_option, + :long => "--config-option OPTION=VALUE", + :description => "Override a single configuration option", + :proc => lambda { |option, existing| + (existing ||= []) << option + existing + } + option :formatter, :short => "-F FORMATTER", :long => "--format FORMATTER", @@ -196,9 +204,9 @@ class Chef::Application::Client < Chef::Application :description => "Replace current run list with specified items for a single run", :proc => lambda {|items| items = items.split(",") - items.compact.map {|item| + items.compact.map do |item| Chef::RunList::RunListItem.new(item) - } + end } option :runlist, @@ -207,9 +215,9 @@ class Chef::Application::Client < Chef::Application :description => "Permanently replace current run list with specified items", :proc => lambda {|items| items = items.split(",") - items.compact.map {|item| + items.compact.map do |item| Chef::RunList::RunListItem.new(item) - } + end } option :why_run, :short => "-W", diff --git a/lib/chef/application/knife.rb b/lib/chef/application/knife.rb index 34598574dd..c80d0245f1 100644 --- a/lib/chef/application/knife.rb +++ b/lib/chef/application/knife.rb @@ -33,6 +33,14 @@ class Chef::Application::Knife < Chef::Application :description => "The configuration file to use", :proc => lambda { |path| File.expand_path(path, Dir.pwd) } + option :config_option, + :long => "--config-option OPTION=VALUE", + :description => "Override a single configuration option", + :proc => lambda { |option, existing| + (existing ||= []) << option + existing + } + verbosity_level = 0 option :verbosity, :short => "-V", diff --git a/lib/chef/application/solo.rb b/lib/chef/application/solo.rb index a7c4038f4c..446a0f007d 100644 --- a/lib/chef/application/solo.rb +++ b/lib/chef/application/solo.rb @@ -41,6 +41,14 @@ class Chef::Application::Solo < Chef::Application :default => Chef::Config.platform_specific_path("/etc/chef/solo.rb"), :description => "The configuration file to use" + option :config_option, + :long => "--config-option OPTION=VALUE", + :description => "Override a single configuration option", + :proc => lambda { |option, existing| + (existing ||= []) << option + existing + } + option :formatter, :short => "-F FORMATTER", :long => "--format FORMATTER", @@ -160,9 +168,9 @@ class Chef::Application::Solo < Chef::Application :description => "Replace current run list with specified items", :proc => lambda {|items| items = items.split(",") - items.compact.map {|item| + items.compact.map do |item| Chef::RunList::RunListItem.new(item) - } + end } option :client_fork, diff --git a/lib/chef/audit/audit_reporter.rb b/lib/chef/audit/audit_reporter.rb index a40cae93dd..8546a21bb4 100644 --- a/lib/chef/audit/audit_reporter.rb +++ b/lib/chef/audit/audit_reporter.rb @@ -140,7 +140,11 @@ class Chef # Save the audit report to local disk error_file = "failed-audit-data.json" Chef::FileCache.store(error_file, Chef::JSONCompat.to_json_pretty(run_data), 0640) - Chef::Log.error("Failed to post audit report to server. Saving report to #{Chef::FileCache.load(error_file, false)}") + if Chef::Config.chef_zero.enabled + Chef::Log.debug("Saving audit report to #{Chef::FileCache.load(error_file, false)}") + else + Chef::Log.error("Failed to post audit report to server. Saving report to #{Chef::FileCache.load(error_file, false)}") + end end else Chef::Log.error("Failed to post audit report to server (#{e})") diff --git a/lib/chef/audit/runner.rb b/lib/chef/audit/runner.rb index 100a72d2e1..837346381c 100644 --- a/lib/chef/audit/runner.rb +++ b/lib/chef/audit/runner.rb @@ -165,7 +165,7 @@ class Chef add_example_group_methods run_context.audits.each do |name, group| ctl_grp = RSpec::Core::ExampleGroup.__control_group__(*group.args, &group.block) - RSpec.world.register(ctl_grp) + RSpec.world.record(ctl_grp) end end diff --git a/lib/chef/chef_fs/chef_fs_data_store.rb b/lib/chef/chef_fs/chef_fs_data_store.rb index aa5a6d5a69..6b3e830f8d 100644 --- a/lib/chef/chef_fs/chef_fs_data_store.rb +++ b/lib/chef/chef_fs/chef_fs_data_store.rb @@ -458,6 +458,7 @@ class Chef # We want to delete just the ones that == POLICY next unless policy.name.rpartition("-")[0] == path[1] policy.delete(false) + FileSystemCache.instance.delete!(policy.file_path) found_policy = true end raise ChefZero::DataStore::DataNotFoundError.new(path) if !found_policy diff --git a/lib/chef/chef_fs/command_line.rb b/lib/chef/chef_fs/command_line.rb index c824bc90df..2d887f4780 100644 --- a/lib/chef/chef_fs/command_line.rb +++ b/lib/chef/chef_fs/command_line.rb @@ -242,48 +242,50 @@ class Chef return [ [ :error, old_entry, new_entry, nil, nil, e ] ] end - private + class << self + private - def self.sort_keys(json_object) - if json_object.is_a?(Array) - json_object.map { |o| sort_keys(o) } - elsif json_object.is_a?(Hash) - new_hash = {} - json_object.keys.sort.each { |key| new_hash[key] = sort_keys(json_object[key]) } - new_hash - else - json_object + def sort_keys(json_object) + if json_object.is_a?(Array) + json_object.map { |o| sort_keys(o) } + elsif json_object.is_a?(Hash) + new_hash = {} + json_object.keys.sort.each { |key| new_hash[key] = sort_keys(json_object[key]) } + new_hash + else + json_object + end end - end - def self.canonicalize_json(json_text) - parsed_json = Chef::JSONCompat.parse(json_text) - sorted_json = sort_keys(parsed_json) - Chef::JSONCompat.to_json_pretty(sorted_json) - end - - def self.diff_text(old_path, new_path, old_value, new_value) - # Copy to tempfiles before diffing - # TODO don't copy things that are already in files! Or find an in-memory diff algorithm - begin - new_tempfile = Tempfile.new("new") - new_tempfile.write(new_value) - new_tempfile.close + def canonicalize_json(json_text) + parsed_json = Chef::JSONCompat.parse(json_text) + sorted_json = sort_keys(parsed_json) + Chef::JSONCompat.to_json_pretty(sorted_json) + end + def diff_text(old_path, new_path, old_value, new_value) + # Copy to tempfiles before diffing + # TODO don't copy things that are already in files! Or find an in-memory diff algorithm begin - old_tempfile = Tempfile.new("old") - old_tempfile.write(old_value) - old_tempfile.close + new_tempfile = Tempfile.new("new") + new_tempfile.write(new_value) + new_tempfile.close - result = Chef::Util::Diff.new.udiff(old_tempfile.path, new_tempfile.path) - result = result.gsub(/^--- #{old_tempfile.path}/, "--- #{old_path}") - result = result.gsub(/^\+\+\+ #{new_tempfile.path}/, "+++ #{new_path}") - result + begin + old_tempfile = Tempfile.new("old") + old_tempfile.write(old_value) + old_tempfile.close + + result = Chef::Util::Diff.new.udiff(old_tempfile.path, new_tempfile.path) + result = result.gsub(/^--- #{old_tempfile.path}/, "--- #{old_path}") + result = result.gsub(/^\+\+\+ #{new_tempfile.path}/, "+++ #{new_path}") + result + ensure + old_tempfile.close! + end ensure - old_tempfile.close! + new_tempfile.close! end - ensure - new_tempfile.close! end end end diff --git a/lib/chef/chef_fs/data_handler/data_handler_base.rb b/lib/chef/chef_fs/data_handler/data_handler_base.rb index b34aff4b98..3668f77dd5 100644 --- a/lib/chef/chef_fs/data_handler/data_handler_base.rb +++ b/lib/chef/chef_fs/data_handler/data_handler_base.rb @@ -93,7 +93,7 @@ class Chef # name to recipe[name]. Then calls uniq on the result. # def normalize_run_list(run_list) - run_list.map {|item| + run_list.map do |item| case item.to_s when /^recipe\[.*\]$/ item # explicit recipe @@ -102,7 +102,7 @@ class Chef else "recipe[#{item}]" end - }.uniq + end.uniq end # diff --git a/lib/chef/chef_fs/file_pattern.rb b/lib/chef/chef_fs/file_pattern.rb index a308a0fe2c..9c12bd4b96 100644 --- a/lib/chef/chef_fs/file_pattern.rb +++ b/lib/chef/chef_fs/file_pattern.rb @@ -160,7 +160,7 @@ class Chef pattern end - private + private def regexp calculate diff --git a/lib/chef/chef_fs/file_system.rb b/lib/chef/chef_fs/file_system.rb index 69dce54f00..1a8da2fd6b 100644 --- a/lib/chef/chef_fs/file_system.rb +++ b/lib/chef/chef_fs/file_system.rb @@ -68,7 +68,7 @@ class Chef list_from(exact_child, &block) end - # Otherwise, go through all children and find any matches + # Otherwise, go through all children and find any matches elsif entry.dir? results = Parallelizer.parallelize(entry.children) { |child| Chef::ChefFS::FileSystem.list(child, pattern) } results.flatten(1).each(&block) @@ -257,172 +257,174 @@ class Chef [ are_same, a_value, b_value ] end - private - - # Copy two entries (could be files or dirs) - def self.copy_entries(src_entry, dest_entry, new_dest_parent, recurse_depth, options, ui, format_path) - # A NOTE about this algorithm: - # There are cases where this algorithm does too many network requests. - # knife upload with a specific filename will first check if the file - # exists (a "dir" in the parent) before deciding whether to POST or - # PUT it. If we just tried PUT (or POST) and then tried the other if - # the conflict failed, we wouldn't need to check existence. - # On the other hand, we may already have DONE the request, in which - # case we shouldn't waste time trying PUT if we know the file doesn't - # exist. - # Will need to decide how that works with checksums, though. - error = false - begin - dest_path = format_path.call(dest_entry) if ui - src_path = format_path.call(src_entry) if ui - if !src_entry.exists? - if options[:purge] - # If we would not have uploaded it, we will not purge it. - if src_entry.parent.can_have_child?(dest_entry.name, dest_entry.dir?) - if options[:dry_run] - ui.output "Would delete #{dest_path}" if ui - else - begin - dest_entry.delete(true) - ui.output "Deleted extra entry #{dest_path} (purge is on)" if ui - rescue Chef::ChefFS::FileSystem::NotFoundError - ui.output "Entry #{dest_path} does not exist. Nothing to do. (purge is on)" if ui + class << self + private + + # Copy two entries (could be files or dirs) + def copy_entries(src_entry, dest_entry, new_dest_parent, recurse_depth, options, ui, format_path) + # A NOTE about this algorithm: + # There are cases where this algorithm does too many network requests. + # knife upload with a specific filename will first check if the file + # exists (a "dir" in the parent) before deciding whether to POST or + # PUT it. If we just tried PUT (or POST) and then tried the other if + # the conflict failed, we wouldn't need to check existence. + # On the other hand, we may already have DONE the request, in which + # case we shouldn't waste time trying PUT if we know the file doesn't + # exist. + # Will need to decide how that works with checksums, though. + error = false + begin + dest_path = format_path.call(dest_entry) if ui + src_path = format_path.call(src_entry) if ui + if !src_entry.exists? + if options[:purge] + # If we would not have uploaded it, we will not purge it. + if src_entry.parent.can_have_child?(dest_entry.name, dest_entry.dir?) + if options[:dry_run] + ui.output "Would delete #{dest_path}" if ui + else + begin + dest_entry.delete(true) + ui.output "Deleted extra entry #{dest_path} (purge is on)" if ui + rescue Chef::ChefFS::FileSystem::NotFoundError + ui.output "Entry #{dest_path} does not exist. Nothing to do. (purge is on)" if ui + end end - end - else - ui.output ("Not deleting extra entry #{dest_path} (purge is off)") if ui - end - end - - elsif !dest_entry.exists? - if new_dest_parent.can_have_child?(src_entry.name, src_entry.dir?) - # If the entry can do a copy directly from filesystem, do that. - if new_dest_parent.respond_to?(:create_child_from) - if options[:dry_run] - ui.output "Would create #{dest_path}" if ui else - new_dest_parent.create_child_from(src_entry) - ui.output "Created #{dest_path}" if ui + ui.output ("Not deleting extra entry #{dest_path} (purge is off)") if ui end - return end - if src_entry.dir? - if options[:dry_run] - ui.output "Would create #{dest_path}" if ui - new_dest_dir = new_dest_parent.child(src_entry.name) - else - new_dest_dir = new_dest_parent.create_child(src_entry.name, nil) - ui.output "Created #{dest_path}" if ui - end - # Directory creation is recursive. - if recurse_depth != 0 - parallel_do(src_entry.children) do |src_child| - new_dest_child = new_dest_dir.child(src_child.name) - child_error = copy_entries(src_child, new_dest_child, new_dest_dir, recurse_depth ? recurse_depth - 1 : recurse_depth, options, ui, format_path) - error ||= child_error + elsif !dest_entry.exists? + if new_dest_parent.can_have_child?(src_entry.name, src_entry.dir?) + # If the entry can do a copy directly from filesystem, do that. + if new_dest_parent.respond_to?(:create_child_from) + if options[:dry_run] + ui.output "Would create #{dest_path}" if ui + else + new_dest_parent.create_child_from(src_entry) + ui.output "Created #{dest_path}" if ui end + return end - else - if options[:dry_run] - ui.output "Would create #{dest_path}" if ui - else - child = new_dest_parent.create_child(src_entry.name, src_entry.read) - ui.output "Created #{format_path.call(child)}" if ui - end - end - end - - else - # Both exist. - # If the entry can do a copy directly, do that. - if dest_entry.respond_to?(:copy_from) - if options[:force] || compare(src_entry, dest_entry)[0] == false - if options[:dry_run] - ui.output "Would update #{dest_path}" if ui + if src_entry.dir? + if options[:dry_run] + ui.output "Would create #{dest_path}" if ui + new_dest_dir = new_dest_parent.child(src_entry.name) + else + new_dest_dir = new_dest_parent.create_child(src_entry.name, nil) + ui.output "Created #{dest_path}" if ui + end + # Directory creation is recursive. + if recurse_depth != 0 + parallel_do(src_entry.children) do |src_child| + new_dest_child = new_dest_dir.child(src_child.name) + child_error = copy_entries(src_child, new_dest_child, new_dest_dir, recurse_depth ? recurse_depth - 1 : recurse_depth, options, ui, format_path) + error ||= child_error + end + end else - dest_entry.copy_from(src_entry, options) - ui.output "Updated #{dest_path}" if ui + if options[:dry_run] + ui.output "Would create #{dest_path}" if ui + else + child = new_dest_parent.create_child(src_entry.name, src_entry.read) + ui.output "Created #{format_path.call(child)}" if ui + end end end - return - end - # If they are different types, log an error. - if src_entry.dir? - if dest_entry.dir? - # If both are directories, recurse into their children - if recurse_depth != 0 - parallel_do(child_pairs(src_entry, dest_entry)) do |src_child, dest_child| - child_error = copy_entries(src_child, dest_child, dest_entry, recurse_depth ? recurse_depth - 1 : recurse_depth, options, ui, format_path) - error ||= child_error + else + # Both exist. + + # If the entry can do a copy directly, do that. + if dest_entry.respond_to?(:copy_from) + if options[:force] || compare(src_entry, dest_entry)[0] == false + if options[:dry_run] + ui.output "Would update #{dest_path}" if ui + else + dest_entry.copy_from(src_entry, options) + ui.output "Updated #{dest_path}" if ui end end - else - # If they are different types. - ui.error("File #{src_path} is a directory while file #{dest_path} is a regular file\n") if ui return end - else - if dest_entry.dir? - ui.error("File #{src_path} is a regular file while file #{dest_path} is a directory\n") if ui - return - else - # Both are files! Copy them unless we're sure they are the same.' - if options[:diff] == false - should_copy = false - elsif options[:force] - should_copy = true - src_value = nil + # If they are different types, log an error. + if src_entry.dir? + if dest_entry.dir? + # If both are directories, recurse into their children + if recurse_depth != 0 + parallel_do(child_pairs(src_entry, dest_entry)) do |src_child, dest_child| + child_error = copy_entries(src_child, dest_child, dest_entry, recurse_depth ? recurse_depth - 1 : recurse_depth, options, ui, format_path) + error ||= child_error + end + end else - are_same, src_value, _dest_value = compare(src_entry, dest_entry) - should_copy = !are_same + # If they are different types. + ui.error("File #{src_path} is a directory while file #{dest_path} is a regular file\n") if ui + return end - if should_copy - if options[:dry_run] - ui.output "Would update #{dest_path}" if ui + else + if dest_entry.dir? + ui.error("File #{src_path} is a regular file while file #{dest_path} is a directory\n") if ui + return + else + + # Both are files! Copy them unless we're sure they are the same.' + if options[:diff] == false + should_copy = false + elsif options[:force] + should_copy = true + src_value = nil else - src_value = src_entry.read if src_value.nil? - dest_entry.write(src_value) - ui.output "Updated #{dest_path}" if ui + are_same, src_value, _dest_value = compare(src_entry, dest_entry) + should_copy = !are_same + end + if should_copy + if options[:dry_run] + ui.output "Would update #{dest_path}" if ui + else + src_value = src_entry.read if src_value.nil? + dest_entry.write(src_value) + ui.output "Updated #{dest_path}" if ui + end end end end end + rescue RubyFileError => e + ui.warn "#{format_path.call(e.entry)} #{e.reason}." if ui + rescue DefaultEnvironmentCannotBeModifiedError => e + ui.warn "#{format_path.call(e.entry)} #{e.reason}." if ui + rescue OperationFailedError => e + ui.error "#{format_path.call(e.entry)} failed to #{e.operation}: #{e.message}" if ui + error = true + rescue OperationNotAllowedError => e + ui.error "#{format_path.call(e.entry)} #{e.reason}." if ui + error = true end - rescue RubyFileError => e - ui.warn "#{format_path.call(e.entry)} #{e.reason}." if ui - rescue DefaultEnvironmentCannotBeModifiedError => e - ui.warn "#{format_path.call(e.entry)} #{e.reason}." if ui - rescue OperationFailedError => e - ui.error "#{format_path.call(e.entry)} failed to #{e.operation}: #{e.message}" if ui - error = true - rescue OperationNotAllowedError => e - ui.error "#{format_path.call(e.entry)} #{e.reason}." if ui - error = true + error end - error - end - def self.get_or_create_parent(entry, options, ui, format_path) - parent = entry.parent - if parent && !parent.exists? - parent_path = format_path.call(parent) if ui - parent_parent = get_or_create_parent(parent, options, ui, format_path) - if options[:dry_run] - ui.output "Would create #{parent_path}" if ui - else - parent = parent_parent.create_child(parent.name, nil) - ui.output "Created #{parent_path}" if ui + def get_or_create_parent(entry, options, ui, format_path) + parent = entry.parent + if parent && !parent.exists? + parent_path = format_path.call(parent) if ui + parent_parent = get_or_create_parent(parent, options, ui, format_path) + if options[:dry_run] + ui.output "Would create #{parent_path}" if ui + else + parent = parent_parent.create_child(parent.name, nil) + ui.output "Created #{parent_path}" if ui + end end + return parent end - return parent - end - def self.parallel_do(enum, options = {}, &block) - Chef::ChefFS::Parallelizer.parallel_do(enum, options, &block) + def parallel_do(enum, options = {}, &block) + Chef::ChefFS::Parallelizer.parallel_do(enum, options, &block) + end end end end diff --git a/lib/chef/chef_fs/file_system/repository/acls_dir.rb b/lib/chef/chef_fs/file_system/repository/acls_dir.rb index 619031aa70..110befdf22 100644 --- a/lib/chef/chef_fs/file_system/repository/acls_dir.rb +++ b/lib/chef/chef_fs/file_system/repository/acls_dir.rb @@ -28,14 +28,16 @@ class Chef module Repository class AclsDir < Repository::Directory + BARE_FILES = %w{ organization.json root } + def can_have_child?(name, is_dir) - is_dir ? Chef::ChefFS::FileSystem::ChefServer::AclsDir::ENTITY_TYPES.include?(name) : name == "organization.json" + is_dir ? Chef::ChefFS::FileSystem::ChefServer::AclsDir::ENTITY_TYPES.include?(name) : BARE_FILES.include?(name) end protected def make_child_entry(child_name) - if child_name == "organization.json" + if BARE_FILES.include? child_name Acl.new(child_name, self) else AclsSubDir.new(child_name, self) diff --git a/lib/chef/chef_fs/file_system/repository/base_file.rb b/lib/chef/chef_fs/file_system/repository/base_file.rb index a768bcf971..3e1edc8d62 100644 --- a/lib/chef/chef_fs/file_system/repository/base_file.rb +++ b/lib/chef/chef_fs/file_system/repository/base_file.rb @@ -16,6 +16,8 @@ # limitations under the License. # +require "chef/chef_fs/file_system_cache" + class Chef module ChefFS module FileSystem @@ -99,6 +101,7 @@ class Chef end def delete(_) + FileSystemCache.instance.delete!(file_path) File.delete(file_path) rescue Errno::ENOENT raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!) diff --git a/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_entry.rb b/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_entry.rb index 9d1538e46e..4019c6985b 100644 --- a/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_entry.rb +++ b/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_entry.rb @@ -120,6 +120,7 @@ class Chef end def delete(recurse) + FileSystemCache.instance.delete!(file_path) begin if dir? if !recurse diff --git a/lib/chef/chef_fs/file_system/repository/directory.rb b/lib/chef/chef_fs/file_system/repository/directory.rb index dae467993a..328cf92b03 100644 --- a/lib/chef/chef_fs/file_system/repository/directory.rb +++ b/lib/chef/chef_fs/file_system/repository/directory.rb @@ -16,6 +16,8 @@ # limitations under the License. # +require "chef/chef_fs/file_system_cache" + class Chef module ChefFS module FileSystem @@ -68,9 +70,11 @@ class Chef end def children - dir_ls.sort. + return FileSystemCache.instance.children(file_path) if FileSystemCache.instance.exist?(file_path) + children = dir_ls.sort. map { |child_name| make_child_entry(child_name) }. select { |new_child| new_child.fs_entry_valid? && can_have_child?(new_child.name, new_child.dir?) } + FileSystemCache.instance.set_children(file_path, children) rescue Errno::ENOENT => e raise Chef::ChefFS::FileSystem::NotFoundError.new(self, e) end @@ -80,6 +84,7 @@ class Chef if child.exists? raise Chef::ChefFS::FileSystem::AlreadyExistsError.new(:create_child, child) end + FileSystemCache.instance.delete!(child.file_path) if file_contents child.write(file_contents) else @@ -118,6 +123,7 @@ class Chef raise Chef::ChefFS::FileSystem::AlreadyExistsError.new(:create_child, self) end begin + FileSystemCache.instance.delete!(file_path) Dir.mkdir(file_path) rescue Errno::EEXIST raise Chef::ChefFS::FileSystem::AlreadyExistsError.new(:create_child, self) @@ -134,6 +140,7 @@ class Chef raise MustDeleteRecursivelyError.new(self, $!) end FileUtils.rm_r(file_path) + FileSystemCache.instance.delete!(file_path) else raise Chef::ChefFS::FileSystem::NotFoundError.new(self, $!) end @@ -145,6 +152,10 @@ class Chef protected + def write(data) + raise FileSystemError.new(self, nil, "attempted to write to a directory entry") + end + def make_child_entry(child_name) raise "Not Implemented" end diff --git a/lib/chef/chef_fs/file_system_cache.rb b/lib/chef/chef_fs/file_system_cache.rb new file mode 100644 index 0000000000..a9d8d8bfe4 --- /dev/null +++ b/lib/chef/chef_fs/file_system_cache.rb @@ -0,0 +1,80 @@ +# +# Copyright:: Copyright 2016, Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "singleton" +require "chef/client" + +class Chef + module ChefFS + class FileSystemCache + include Singleton + + def initialize + @cache = {} + + Chef::Client.when_run_starts do + FileSystemCache.instance.reset! + end + end + + def reset! + @cache = {} + end + + def exist?(path) + @cache.key?(path) + end + + def children(path) + @cache[path]["children"] + end + + def set_children(path, val) + @cache[path] ||= { "children" => [] } + @cache[path]["children"] = val + val + end + + def delete!(path) + parent = _get_parent(path) + Chef::Log.debug("Deleting parent #{parent} and #{path} from FileSystemCache") + if @cache.key?(path) + @cache.delete(path) + end + if !parent.nil? && @cache.key?(parent) + @cache.delete(parent) + end + end + + def fetch(path) + if @cache.key?(path) + @cache[path] + else + false + end + end + + private + + def _get_parent(path) + parts = ChefFS::PathUtils.split(path) + return nil if parts.nil? || parts.length < 2 + ChefFS::PathUtils.join(*parts[0..-2]) + end + end + end +end diff --git a/lib/chef/chef_fs/parallelizer/parallel_enumerable.rb b/lib/chef/chef_fs/parallelizer/parallel_enumerable.rb index 9d02bbab78..ab578bdb7f 100644 --- a/lib/chef/chef_fs/parallelizer/parallel_enumerable.rb +++ b/lib/chef/chef_fs/parallelizer/parallel_enumerable.rb @@ -184,9 +184,7 @@ class Chef sleep(0.01) end - until @unconsumed_output.empty? - yield @unconsumed_output.pop - end + yield @unconsumed_output.pop until @unconsumed_output.empty? # If no one is working on our tasks and we're allowed to # work on them in the main thread, process an input to @@ -227,9 +225,7 @@ class Chef def stop @unconsumed_input.clear - while @in_process.size > 0 - sleep(0.05) - end + sleep(0.05) while @in_process.size > 0 @unconsumed_output.clear end diff --git a/lib/chef/cookbook/cookbook_version_loader.rb b/lib/chef/cookbook/cookbook_version_loader.rb index d9b027f322..af8b2e043e 100644 --- a/lib/chef/cookbook/cookbook_version_loader.rb +++ b/lib/chef/cookbook/cookbook_version_loader.rb @@ -3,6 +3,7 @@ require "chef/cookbook_version" require "chef/cookbook/chefignore" require "chef/cookbook/metadata" require "chef/util/path_helper" +require "find" class Chef class Cookbook @@ -168,7 +169,7 @@ class Chef when /\.json$/ apply_json_metadata(metadata_file) else - raise RuntimeError, "Invalid metadata file: #{metadata_file} for cookbook: #{cookbook_version}" + raise "Invalid metadata file: #{metadata_file} for cookbook: #{cookbook_version}" end end @@ -223,27 +224,31 @@ class Chef # however if the file is named ".uploaded-cookbook-version.json" it is # assumed to be managed by chef-zero and not part of the cookbook. def load_all_files - Dir.glob(File.join(Chef::Util::PathHelper.escape_glob_dir(cookbook_path), "*"), File::FNM_DOTMATCH).each do |fs_entry| - if File.directory?(fs_entry) - dir_relpath = Chef::Util::PathHelper.relative_path_from(@cookbook_path, fs_entry) - - next if dir_relpath.to_s.start_with?(".") - - Dir.glob(File.join(fs_entry, "**/*"), File::FNM_DOTMATCH).each do |file| - next if File.directory?(file) - file = Pathname.new(file).cleanpath.to_s - name = Chef::Util::PathHelper.relative_path_from(@cookbook_path, file) - cookbook_settings[:all_files][name] = file - end - elsif File.file?(fs_entry) - file = Pathname.new(fs_entry).cleanpath.to_s - - next if File.basename(file) == UPLOADED_COOKBOOK_VERSION_FILE - - name = Chef::Util::PathHelper.relative_path_from(@cookbook_path, file) - cookbook_settings[:all_files][name] = file - else # pipes, devices, other weirdness - next + return unless File.exist?(cookbook_path) + + # If cookbook_path is a symlink, Find on Windows Ruby 2.3 will not traverse it. + # Dir.entries will do so on all platforms, so we iterate the top level using + # Dir.entries. Since we have different behavior at the top anyway (hidden + # directories at the top level are not included for backcompat), this + # actually keeps things a bit cleaner. + Dir.entries(cookbook_path).each do |top_filename| + # Skip top-level directories starting with "." + top_path = File.join(cookbook_path, top_filename) + next if File.directory?(top_path) && top_filename.start_with?(".") + + # Use Find.find because it: + # (a) returns any children, recursively + # (b) includes top_path as well + # (c) skips symlinks, which is backcompat (no judgement on whether it was *right*) + Find.find(top_path) do |path| + # Only add files, not directories + next unless File.file?(path) + # Don't add .uploaded-cookbook-version.json + next if File.basename(path) == UPLOADED_COOKBOOK_VERSION_FILE + + relative_path = Chef::Util::PathHelper.relative_path_from(cookbook_path, path) + path = Pathname.new(path).cleanpath.to_s + cookbook_settings[:all_files][relative_path] = path end end end diff --git a/lib/chef/cookbook/metadata.rb b/lib/chef/cookbook/metadata.rb index 603f80748c..ab83da9e55 100644 --- a/lib/chef/cookbook/metadata.rb +++ b/lib/chef/cookbook/metadata.rb @@ -722,7 +722,7 @@ class Chef end end - private + private # Helper to match a gem style version (ohai_version/chef_version) against a set of # Gem::Dependency version constraints. If none are present, it always matches. if diff --git a/lib/chef/cookbook/synchronizer.rb b/lib/chef/cookbook/synchronizer.rb index 1ee30bacc7..bb44bc3d5c 100644 --- a/lib/chef/cookbook/synchronizer.rb +++ b/lib/chef/cookbook/synchronizer.rb @@ -152,11 +152,11 @@ class Chef queue << lambda do |lock| full_file_path = sync_file(file) - lock.synchronize { + lock.synchronize do # Save the full_path of the downloaded file to be restored in the manifest later save_full_file_path(file, full_file_path) mark_file_synced(file) - } + end end end @@ -291,7 +291,7 @@ class Chef end def server_api - Chef::ServerAPI.new(Chef::Config[:chef_server_url]) + Thread.current[:server_api] ||= Chef::ServerAPI.new(Chef::Config[:chef_server_url], keepalives: true) end end diff --git a/lib/chef/cookbook_site_streaming_uploader.rb b/lib/chef/cookbook_site_streaming_uploader.rb index 9fb8d0d4bc..c0e85ff984 100644 --- a/lib/chef/cookbook_site_streaming_uploader.rb +++ b/lib/chef/cookbook_site_streaming_uploader.rb @@ -31,7 +31,7 @@ class Chef # inspired by http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html class CookbookSiteStreamingUploader - DefaultHeaders = { "accept" => "application/json", "x-chef-version" => ::Chef::VERSION } + DefaultHeaders = { "accept" => "application/json", "x-chef-version" => ::Chef::VERSION } # rubocop:disable Style/ConstantName class << self @@ -149,11 +149,11 @@ class Chef alias :to_s :body # BUGBUG this makes the response compatible with what respsonse_steps expects to test headers (response.headers[] -> response[]) - def headers + def headers # rubocop:disable Lint/NestedMethodDefinition self end - def status + def status # rubocop:disable Lint/NestedMethodDefinition code.to_i end end diff --git a/lib/chef/cookbook_uploader.rb b/lib/chef/cookbook_uploader.rb index 95c27799ec..bb75234563 100644 --- a/lib/chef/cookbook_uploader.rb +++ b/lib/chef/cookbook_uploader.rb @@ -55,7 +55,7 @@ class Chef checksum_files.merge!(cb.checksums) end - checksums = checksum_files.inject({}) { |memo, elt| memo[elt.first] = nil ; memo } + checksums = checksum_files.inject({}) { |memo, elt| memo[elt.first] = nil; memo } new_sandbox = rest.post("sandboxes", { :checksums => checksums }) Chef::Log.info("Uploading files") diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb index 1e903608b5..8de9cb26dd 100644 --- a/lib/chef/cookbook_version.rb +++ b/lib/chef/cookbook_version.rb @@ -316,13 +316,13 @@ class Chef error_message << error_locations.join("\n") existing_files = segment_filenames(segment) # Strip the root_dir prefix off all files for readability - pretty_existing_files = existing_files.map { |path| + pretty_existing_files = existing_files.map do |path| if root_dir path[root_dir.length + 1..-1] else path end - } + end # Show the files that the cookbook does have. If the user made a typo, # hopefully they'll see it here. unless pretty_existing_files.empty? @@ -599,12 +599,12 @@ class Chef end end - def <=>(o) - raise Chef::Exceptions::CookbookVersionNameMismatch if self.name != o.name + def <=>(other) + raise Chef::Exceptions::CookbookVersionNameMismatch if self.name != other.name # FIXME: can we change the interface to the Metadata class such # that metadata.version returns a Chef::Version instance instead # of a string? - Chef::Version.new(self.version) <=> Chef::Version.new(o.version) + Chef::Version.new(self.version) <=> Chef::Version.new(other.version) end private @@ -623,7 +623,7 @@ class Chef # For each filename, produce a mapping of base filename (i.e. recipe name # or attribute file) to on disk location def filenames_by_name(filenames) - filenames.select { |filename| filename =~ /\.rb$/ }.inject({}) { |memo, filename| memo[File.basename(filename, ".rb")] = filename ; memo } + filenames.select { |filename| filename =~ /\.rb$/ }.inject({}) { |memo, filename| memo[File.basename(filename, ".rb")] = filename; memo } end def file_vendor diff --git a/lib/chef/dsl/cheffish.rb b/lib/chef/dsl/cheffish.rb index de052bbe5c..03290b3674 100644 --- a/lib/chef/dsl/cheffish.rb +++ b/lib/chef/dsl/cheffish.rb @@ -27,6 +27,7 @@ class Chef chef_acl chef_client chef_container + chef_data_bag_item chef_data_bag chef_environment chef_group diff --git a/lib/chef/dsl/declare_resource.rb b/lib/chef/dsl/declare_resource.rb index 8d76ddfb31..86227a0f9d 100644 --- a/lib/chef/dsl/declare_resource.rb +++ b/lib/chef/dsl/declare_resource.rb @@ -71,7 +71,15 @@ class Chef # delete_resource!(:template, '/x/y.txy') # def delete_resource!(type, name, run_context: self.run_context) - run_context.resource_collection.delete("#{type}[#{name}]") + run_context.resource_collection.delete("#{type}[#{name}]").tap do |resource| + # Purge any pending notifications too. This will not raise an exception + # if there are no notifications. + if resource + run_context.before_notification_collection.delete(resource.declared_key) + run_context.immediate_notification_collection.delete(resource.declared_key) + run_context.delayed_notification_collection.delete(resource.declared_key) + end + end end # Lookup a resource in the resource collection by name and delete it. Returns diff --git a/lib/chef/dsl/powershell.rb b/lib/chef/dsl/powershell.rb index 1a900af6f6..7dc7a9a0f6 100644 --- a/lib/chef/dsl/powershell.rb +++ b/lib/chef/dsl/powershell.rb @@ -21,7 +21,7 @@ require "chef/util/powershell/ps_credential" class Chef module DSL module Powershell - def ps_credential(username = "placeholder", password) + def ps_credential(username = "placeholder", password) # rubocop:disable Style/OptionalArguments Chef::Util::Powershell::PSCredential.new(username, password) end end diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb index 43759568a7..a4d5ff60e2 100644 --- a/lib/chef/exceptions.rb +++ b/lib/chef/exceptions.rb @@ -184,7 +184,7 @@ class Chef # A different version of a cookbook was added to a # VersionedRecipeList than the one already there. - class CookbookVersionConflict < ArgumentError ; end + class CookbookVersionConflict < ArgumentError; end # does not follow X.Y.Z format. ArgumentError? class InvalidPlatformVersion < ArgumentError; end diff --git a/lib/chef/file_access_control/windows.rb b/lib/chef/file_access_control/windows.rb index 6b7184bbd3..6f1ac5f581 100644 --- a/lib/chef/file_access_control/windows.rb +++ b/lib/chef/file_access_control/windows.rb @@ -128,7 +128,7 @@ class Chef end def should_update_dacl? - return true unless ::File.exists?(file) + return true unless ::File.exists?(file) || ::File.symlink?(file) dacl = target_dacl existing_dacl = existing_descriptor.dacl inherits = target_inherits @@ -161,7 +161,7 @@ class Chef end def should_update_group? - return true unless ::File.exists?(file) + return true unless ::File.exists?(file) || ::File.symlink?(file) (group = target_group) && (group != existing_descriptor.group) end @@ -180,7 +180,7 @@ class Chef end def should_update_owner? - return true unless ::File.exists?(file) + return true unless ::File.exists?(file) || ::File.symlink?(file) (owner = target_owner) && (owner != existing_descriptor.owner) end diff --git a/lib/chef/file_cache.rb b/lib/chef/file_cache.rb index cefc9da1eb..8e9bb1e3e4 100644 --- a/lib/chef/file_cache.rb +++ b/lib/chef/file_cache.rb @@ -85,7 +85,7 @@ class Chef File.join(create_cache_path(File.join(file_path_array), true), file_name) ) else - raise RuntimeError, "Cannot move #{file} to #{path}!" + raise "Cannot move #{file} to #{path}!" end end diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb index d43f1993b2..7dbbf1d948 100644 --- a/lib/chef/formatters/doc.rb +++ b/lib/chef/formatters/doc.rb @@ -32,9 +32,9 @@ class Chef def pretty_elapsed_time time = elapsed_time - if time < 60 then + if time < 60 message = Time.at(time).utc.strftime("%S seconds") - elsif time < 3600 then + elsif time < 3600 message = Time.at(time).utc.strftime("%M minutes %S seconds") else message = Time.at(time).utc.strftime("%H hours %M minutes %S seconds") diff --git a/lib/chef/http.rb b/lib/chef/http.rb index 3e69f58383..924081bc6b 100644 --- a/lib/chef/http.rb +++ b/lib/chef/http.rb @@ -77,6 +77,9 @@ class Chef attr_reader :middlewares + # [Boolean] if we're doing keepalives or not + attr_reader :keepalives + # Create a HTTP client object. The supplied +url+ is used as the base for # all subsequent requests. For example, when initialized with a base url # http://localhost:4000, a call to +get+ with 'nodes' will make an @@ -87,6 +90,7 @@ class Chef @sign_on_redirect = true @redirects_followed = 0 @redirect_limit = 10 + @keepalives = options[:keepalives] || false @options = options @middlewares = [] @@ -228,6 +232,33 @@ class Chef def http_client(base_url = nil) base_url ||= url + if keepalives && !base_url.nil? + # only reuse the http_client if we want keepalives and have a base_url + @http_client ||= {} + # the per-host per-port cache here gets peristent connections correct when + # redirecting to different servers + if base_url.is_a?(String) # sigh, this kind of abuse can't happen with strongly typed languages + @http_client[base_url] ||= build_http_client(base_url) + else + @http_client[base_url.host] ||= {} + @http_client[base_url.host][base_url.port] ||= build_http_client(base_url) + end + else + build_http_client(base_url) + end + end + + # DEPRECATED: This is only kept around to provide access to cache control data in + # lib/chef/provider/remote_file/http.rb + # FIXME: Find a better API. + def last_response + @last_response + end + + private + + # @api private + def build_http_client(base_url) if chef_zero_uri?(base_url) # PERFORMANCE CRITICAL: *MUST* lazy require here otherwise we load up webrick # via chef-zero and that hits DNS (at *require* time) which may timeout, @@ -239,12 +270,11 @@ class Chef SocketlessChefZeroClient.new(base_url) else - BasicClient.new(base_url, :ssl_policy => Chef::HTTP::APISSLPolicy) + BasicClient.new(base_url, ssl_policy: Chef::HTTP::APISSLPolicy, keepalives: keepalives) end end - protected - + # @api private def create_url(path) return path if path.is_a?(URI) if path =~ /^(http|https|chefzero):\/\//i @@ -259,6 +289,7 @@ class Chef end end + # @api private def apply_request_middleware(method, url, headers, data) middlewares.inject([method, url, headers, data]) do |req_data, middleware| Chef::Log.debug("Chef::HTTP calling #{middleware.class}#handle_request") @@ -266,6 +297,7 @@ class Chef end end + # @api private def apply_response_middleware(response, rest_request, return_value) middlewares.reverse.inject([response, rest_request, return_value]) do |res_data, middleware| Chef::Log.debug("Chef::HTTP calling #{middleware.class}#handle_response") @@ -273,6 +305,7 @@ class Chef end end + # @api private def apply_stream_complete_middleware(response, rest_request, return_value) middlewares.reverse.inject([response, rest_request, return_value]) do |res_data, middleware| Chef::Log.debug("Chef::HTTP calling #{middleware.class}#handle_stream_complete") @@ -280,6 +313,7 @@ class Chef end end + # @api private def log_failed_request(response, return_value) return_value ||= {} error_message = "HTTP Request Returned #{response.code} #{response.message}: " @@ -287,12 +321,14 @@ class Chef Chef::Log.info(error_message) end + # @api private def success_response?(response) response.kind_of?(Net::HTTPSuccess) || response.kind_of?(Net::HTTPRedirection) end # Runs a synchronous HTTP request, with no middleware applied (use #request # to have the middleware applied). The entire response will be loaded into memory. + # @api private def send_http_request(method, url, headers, body, &response_handler) headers = build_headers(method, url, headers, body) @@ -328,6 +364,7 @@ class Chef # Wraps an HTTP request with retry logic. # === Arguments # url:: URL of the request, used for error messages + # @api private def retrying_http_errors(url) http_attempts = 0 begin @@ -377,18 +414,22 @@ class Chef end end + # @api private def http_retry_delay config[:http_retry_delay] end + # @api private def http_retry_count config[:http_retry_count] end + # @api private def config Chef::Config end + # @api private def follow_redirect raise Chef::Exceptions::RedirectLimitExceeded if @redirects_followed >= redirect_limit @redirects_followed += 1 @@ -399,13 +440,13 @@ class Chef @redirects_followed = 0 end - private - + # @api private def chef_zero_uri?(uri) uri = URI.parse(uri) unless uri.respond_to?(:scheme) uri.scheme == "chefzero" end + # @api private def redirected_to(response) return nil unless response.kind_of?(Net::HTTPRedirection) # Net::HTTPNotModified is undesired subclass of Net::HTTPRedirection so test for this @@ -413,6 +454,7 @@ class Chef response["location"] end + # @api private def build_headers(method, url, headers = {}, json_body = false) headers = @default_headers.merge(headers) headers["Content-Length"] = json_body.bytesize.to_s if json_body @@ -420,6 +462,7 @@ class Chef headers end + # @api private def stream_to_tempfile(url, response, &progress_block) content_length = response["Content-Length"] tf = Tempfile.open("chef-rest") @@ -443,18 +486,5 @@ class Chef raise end - public - - ############################################################################ - # DEPRECATED - ############################################################################ - - # This is only kept around to provide access to cache control data in - # lib/chef/provider/remote_file/http.rb - # Find a better API. - def last_response - @last_response - end - end end diff --git a/lib/chef/http/auth_credentials.rb b/lib/chef/http/auth_credentials.rb index d5dbff3758..053b2c938e 100644 --- a/lib/chef/http/auth_credentials.rb +++ b/lib/chef/http/auth_credentials.rb @@ -49,7 +49,7 @@ class Chef sign_obj = Mixlib::Authentication::SignedHeaderAuth.signing_object(request_params) signed = sign_obj.sign(key).merge({ :host => host }) - signed.inject({}) { |memo, kv| memo["#{kv[0].to_s.upcase}"] = kv[1];memo } + signed.inject({}) { |memo, kv| memo["#{kv[0].to_s.upcase}"] = kv[1]; memo } end end diff --git a/lib/chef/http/basic_client.rb b/lib/chef/http/basic_client.rb index 3a87fe85e4..460744ea2a 100644 --- a/lib/chef/http/basic_client.rb +++ b/lib/chef/http/basic_client.rb @@ -34,6 +34,7 @@ class Chef attr_reader :url attr_reader :http_client attr_reader :ssl_policy + attr_reader :keepalives # Instantiate a BasicClient. # === Arguments: @@ -43,7 +44,11 @@ class Chef def initialize(url, opts = {}) @url = url @ssl_policy = opts[:ssl_policy] || DefaultSSLPolicy - @http_client = build_http_client + @keepalives = opts[:keepalives] || false + end + + def http_client + @http_client ||= build_http_client end def host @@ -114,7 +119,11 @@ class Chef http_client.read_timeout = config[:rest_timeout] http_client.open_timeout = config[:rest_timeout] - http_client + if keepalives + http_client.start + else + http_client + end end def config diff --git a/lib/chef/http/socketless_chef_zero_client.rb b/lib/chef/http/socketless_chef_zero_client.rb index 1acac5e758..d2f1f45b1d 100644 --- a/lib/chef/http/socketless_chef_zero_client.rb +++ b/lib/chef/http/socketless_chef_zero_client.rb @@ -197,9 +197,9 @@ class Chef private def headers_extracted_from_options - options.reject { |name, _| KNOWN_OPTIONS.include?(name) }.map { |name, value| + options.reject { |name, _| KNOWN_OPTIONS.include?(name) }.map do |name, value| [name.to_s.split("_").map { |segment| segment.capitalize }.join("-"), value] - } + end end end diff --git a/lib/chef/key.rb b/lib/chef/key.rb index 1c25c5daad..38822e8b26 100644 --- a/lib/chef/key.rb +++ b/lib/chef/key.rb @@ -201,72 +201,71 @@ class Chef chef_rest.delete("#{api_base}/#{@actor}/keys/#{@name}") end - # Class methods - def self.from_hash(key_hash) - if key_hash.has_key?("user") - key = Chef::Key.new(key_hash["user"], "user") - elsif key_hash.has_key?("client") - key = Chef::Key.new(key_hash["client"], "client") - else - raise Chef::Exceptions::MissingKeyAttribute, "The hash passed to from_hash does not contain the key 'user' or 'client'. Please pass a hash that defines one of those keys." + class << self + def from_hash(key_hash) + if key_hash.has_key?("user") + key = Chef::Key.new(key_hash["user"], "user") + elsif key_hash.has_key?("client") + key = Chef::Key.new(key_hash["client"], "client") + else + raise Chef::Exceptions::MissingKeyAttribute, "The hash passed to from_hash does not contain the key 'user' or 'client'. Please pass a hash that defines one of those keys." + end + key.name key_hash["name"] if key_hash.key?("name") + key.public_key key_hash["public_key"] if key_hash.key?("public_key") + key.private_key key_hash["private_key"] if key_hash.key?("private_key") + key.create_key key_hash["create_key"] if key_hash.key?("create_key") + key.expiration_date key_hash["expiration_date"] if key_hash.key?("expiration_date") + key end - key.name key_hash["name"] if key_hash.key?("name") - key.public_key key_hash["public_key"] if key_hash.key?("public_key") - key.private_key key_hash["private_key"] if key_hash.key?("private_key") - key.create_key key_hash["create_key"] if key_hash.key?("create_key") - key.expiration_date key_hash["expiration_date"] if key_hash.key?("expiration_date") - key - end - - def self.from_json(json) - Chef::Key.from_hash(Chef::JSONCompat.from_json(json)) - end - def self.json_create(json) - Chef.log_deprecation("Auto inflation of JSON data is deprecated. Please use Chef::Key#from_json or one of the load_by methods.") - Chef::Key.from_json(json) - end + def from_json(json) + Chef::Key.from_hash(Chef::JSONCompat.from_json(json)) + end - def self.list_by_user(actor, inflate = false) - keys = Chef::ServerAPI.new(Chef::Config[:chef_server_root]).get("users/#{actor}/keys") - self.list(keys, actor, :load_by_user, inflate) - end + def json_create(json) + Chef.log_deprecation("Auto inflation of JSON data is deprecated. Please use Chef::Key#from_json or one of the load_by methods.") + Chef::Key.from_json(json) + end - def self.list_by_client(actor, inflate = false) - keys = Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("clients/#{actor}/keys") - self.list(keys, actor, :load_by_client, inflate) - end + def list_by_user(actor, inflate = false) + keys = Chef::ServerAPI.new(Chef::Config[:chef_server_root]).get("users/#{actor}/keys") + self.list(keys, actor, :load_by_user, inflate) + end - def self.load_by_user(actor, key_name) - response = Chef::ServerAPI.new(Chef::Config[:chef_server_root]).get("users/#{actor}/keys/#{key_name}") - Chef::Key.from_hash(response.merge({ "user" => actor })) - end + def list_by_client(actor, inflate = false) + keys = Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("clients/#{actor}/keys") + self.list(keys, actor, :load_by_client, inflate) + end - def self.load_by_client(actor, key_name) - response = Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("clients/#{actor}/keys/#{key_name}") - Chef::Key.from_hash(response.merge({ "client" => actor })) - end + def load_by_user(actor, key_name) + response = Chef::ServerAPI.new(Chef::Config[:chef_server_root]).get("users/#{actor}/keys/#{key_name}") + Chef::Key.from_hash(response.merge({ "user" => actor })) + end - def self.generate_fingerprint(public_key) - openssl_key_object = OpenSSL::PKey::RSA.new(public_key) - data_string = OpenSSL::ASN1::Sequence([ - OpenSSL::ASN1::Integer.new(openssl_key_object.public_key.n), - OpenSSL::ASN1::Integer.new(openssl_key_object.public_key.e), - ]) - OpenSSL::Digest::SHA1.hexdigest(data_string.to_der).scan(/../).join(":") - end + def load_by_client(actor, key_name) + response = Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("clients/#{actor}/keys/#{key_name}") + Chef::Key.from_hash(response.merge({ "client" => actor })) + end - private + def generate_fingerprint(public_key) + openssl_key_object = OpenSSL::PKey::RSA.new(public_key) + data_string = OpenSSL::ASN1::Sequence([ + OpenSSL::ASN1::Integer.new(openssl_key_object.public_key.n), + OpenSSL::ASN1::Integer.new(openssl_key_object.public_key.e), + ]) + OpenSSL::Digest::SHA1.hexdigest(data_string.to_der).scan(/../).join(":") + end - def self.list(keys, actor, load_method_symbol, inflate) - if inflate - keys.inject({}) do |key_map, result| - name = result["name"] - key_map[name] = Chef::Key.send(load_method_symbol, actor, name) - key_map + def list(keys, actor, load_method_symbol, inflate) + if inflate + keys.inject({}) do |key_map, result| + name = result["name"] + key_map[name] = Chef::Key.send(load_method_symbol, actor, name) + key_map + end + else + keys end - else - keys end end end diff --git a/lib/chef/knife.rb b/lib/chef/knife.rb index 356bf47fd4..c8b344b5f1 100644 --- a/lib/chef/knife.rb +++ b/lib/chef/knife.rb @@ -233,61 +233,66 @@ class Chef end end - private - OFFICIAL_PLUGINS = %w{ec2 rackspace windows openstack terremark bluebox} - def self.path_from_caller(caller_line) - caller_line.split(/:\d+/).first - end - - # :nodoc: - # Error out and print usage. probably because the arguments given by the - # user could not be resolved to a subcommand. - def self.subcommand_not_found!(args) - ui.fatal("Cannot find subcommand for: '#{args.join(' ')}'") + class << self + private - # Mention rehash when the subcommands cache(plugin_manifest.json) is used - if subcommand_loader.is_a?(Chef::Knife::SubcommandLoader::HashedCommandLoader) || - subcommand_loader.is_a?(Chef::Knife::SubcommandLoader::CustomManifestLoader) - ui.info("If this is a recently installed plugin, please run 'knife rehash' to update the subcommands cache.") + # @api private + def path_from_caller(caller_line) + caller_line.split(/:\d+/).first end - if category_commands = guess_category(args) - list_commands(category_commands) - elsif missing_plugin = ( OFFICIAL_PLUGINS.find { |plugin| plugin == args[0] } ) - ui.info("The #{missing_plugin} commands were moved to plugins in Chef 0.10") - ui.info("You can install the plugin with `(sudo) gem install knife-#{missing_plugin}`") - ui.info("Use `chef gem install knife-#{missing_plugin}` instead if using ChefDK") - else - list_commands - end + # :nodoc: + # Error out and print usage. probably because the arguments given by the + # user could not be resolved to a subcommand. + # @api private + def subcommand_not_found!(args) + ui.fatal("Cannot find subcommand for: '#{args.join(' ')}'") + + # Mention rehash when the subcommands cache(plugin_manifest.json) is used + if subcommand_loader.is_a?(Chef::Knife::SubcommandLoader::HashedCommandLoader) || + subcommand_loader.is_a?(Chef::Knife::SubcommandLoader::CustomManifestLoader) + ui.info("If this is a recently installed plugin, please run 'knife rehash' to update the subcommands cache.") + end - exit 10 - end + if category_commands = guess_category(args) + list_commands(category_commands) + elsif missing_plugin = ( OFFICIAL_PLUGINS.find { |plugin| plugin == args[0] } ) + ui.info("The #{missing_plugin} commands were moved to plugins in Chef 0.10") + ui.info("You can install the plugin with `(sudo) gem install knife-#{missing_plugin}`") + ui.info("Use `chef gem install knife-#{missing_plugin}` instead if using ChefDK") + else + list_commands + end - def self.list_commands(preferred_category = nil) - category_desc = preferred_category ? preferred_category + " " : "" - msg "Available #{category_desc}subcommands: (for details, knife SUB-COMMAND --help)\n\n" - subcommand_loader.list_commands(preferred_category).sort.each do |category, commands| - next if category =~ /deprecated/i - msg "** #{category.upcase} COMMANDS **" - commands.sort.each do |command| - subcommand_loader.load_command(command) - msg subcommands[command].banner if subcommands[command] + exit 10 + end + + # @api private + def list_commands(preferred_category = nil) + category_desc = preferred_category ? preferred_category + " " : "" + msg "Available #{category_desc}subcommands: (for details, knife SUB-COMMAND --help)\n\n" + subcommand_loader.list_commands(preferred_category).sort.each do |category, commands| + next if category =~ /deprecated/i + msg "** #{category.upcase} COMMANDS **" + commands.sort.each do |command| + subcommand_loader.load_command(command) + msg subcommands[command].banner if subcommands[command] + end + msg end - msg end - end - def self.reset_config_path! - @@chef_config_dir = nil + # @api private + def reset_config_path! + @@chef_config_dir = nil + end + end reset_config_path! - public - # Create a new instance of the current class configured for the given # arguments and options def initialize(argv = []) diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb index f5dc29371f..ee4d9ce7af 100644 --- a/lib/chef/knife/bootstrap.rb +++ b/lib/chef/knife/bootstrap.rb @@ -101,6 +101,14 @@ class Chef :description => "The proxy server for the node being bootstrapped", :proc => Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p } + option :bootstrap_proxy_user, + :long => "--bootstrap-proxy-user PROXY_USER", + :description => "The proxy authentication username for the node being bootstrapped" + + option :bootstrap_proxy_pass, + :long => "--bootstrap-proxy-pass PROXY_PASS", + :description => "The proxy authentication password for the node being bootstrapped" + option :bootstrap_no_proxy, :long => "--bootstrap-no-proxy [NO_PROXY_URL|NO_PROXY_IP]", :description => "Do not proxy locations for the node being bootstrapped; this option is used internally by Opscode", @@ -224,6 +232,7 @@ class Chef unless valid_values.include?(v) raise "Invalid value '#{v}' for --node-ssl-verify-mode. Valid values are: #{valid_values.join(", ")}" end + v } option :node_verify_api_cert, diff --git a/lib/chef/knife/client_delete.rb b/lib/chef/knife/client_delete.rb index e1b2365361..08cdf6c7dd 100644 --- a/lib/chef/knife/client_delete.rb +++ b/lib/chef/knife/client_delete.rb @@ -43,7 +43,7 @@ class Chef exit 1 end - delete_object(Chef::ApiClientV1, @client_name, "client") { + delete_object(Chef::ApiClientV1, @client_name, "client") do object = Chef::ApiClientV1.load(@client_name) if object.validator unless config[:delete_validators] @@ -52,7 +52,7 @@ class Chef end end object.destroy - } + end end end diff --git a/lib/chef/knife/cookbook_bulk_delete.rb b/lib/chef/knife/cookbook_bulk_delete.rb index bd1c8a22cc..cdd1584e36 100644 --- a/lib/chef/knife/cookbook_bulk_delete.rb +++ b/lib/chef/knife/cookbook_bulk_delete.rb @@ -42,7 +42,7 @@ class Chef all_cookbooks = Chef::CookbookVersion.list cookbooks_names = all_cookbooks.keys.grep(regex) - cookbooks_to_delete = cookbooks_names.inject({}) { |hash, name| hash[name] = all_cookbooks[name];hash } + cookbooks_to_delete = cookbooks_names.inject({}) { |hash, name| hash[name] = all_cookbooks[name]; hash } ui.msg "All versions of the following cookbooks will be deleted:" ui.msg "" ui.msg ui.list(cookbooks_to_delete.keys.sort, :columns_down) diff --git a/lib/chef/knife/cookbook_show.rb b/lib/chef/knife/cookbook_show.rb index a20e62ffc2..d0c930de0a 100644 --- a/lib/chef/knife/cookbook_show.rb +++ b/lib/chef/knife/cookbook_show.rb @@ -63,7 +63,7 @@ class Chef node[:platform_version] = config[:platform_version] if config.has_key?(:platform_version) class << node - def attribute?(name) + def attribute?(name) # rubocop:disable Lint/NestedMethodDefinition has_key?(name) end end diff --git a/lib/chef/knife/cookbook_site_share.rb b/lib/chef/knife/cookbook_site_share.rb index f500ba2182..d55d6c123a 100644 --- a/lib/chef/knife/cookbook_site_share.rb +++ b/lib/chef/knife/cookbook_site_share.rb @@ -113,19 +113,13 @@ class Chef end def get_category(cookbook_name) - begin - data = noauth_rest.get("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}") - if !data["category"] && data["error_code"] - ui.fatal("Received an error from Supermarket: #{data["error_code"]}. On the first time you upload it, you are required to specify the category you want to share this cookbook to.") - exit(1) - else - data["category"] - end - rescue => e - ui.fatal("Unable to reach Supermarket: #{e.message}. Increase log verbosity (-VV) for more information.") - Chef::Log.debug("\n#{e.backtrace.join("\n")}") - exit(1) - end + data = noauth_rest.get("#{config[:supermarket_site]}/api/v1/cookbooks/#{@name_args[0]}") + data["category"] + rescue => e + return "Other" if e.kind_of?(Net::HTTPServerException) && e.response.code == "404" + ui.fatal("Unable to reach Supermarket: #{e.message}. Increase log verbosity (-VV) for more information.") + Chef::Log.debug("\n#{e.backtrace.join("\n")}") + exit(1) end def do_upload(cookbook_filename, cookbook_category, user_id, user_secret_filename) diff --git a/lib/chef/knife/core/bootstrap_context.rb b/lib/chef/knife/core/bootstrap_context.rb index 6db1a83c73..b2670f196b 100644 --- a/lib/chef/knife/core/bootstrap_context.rb +++ b/lib/chef/knife/core/bootstrap_context.rb @@ -114,6 +114,16 @@ validation_client_name "#{@chef_config[:validation_client_name]}" client_rb << %Q{https_proxy "#{knife_config[:bootstrap_proxy]}"\n} end + if knife_config[:bootstrap_proxy_user] + client_rb << %Q{http_proxy_user "#{knife_config[:bootstrap_proxy_user]}"\n} + client_rb << %Q{https_proxy_user "#{knife_config[:bootstrap_proxy_user]}"\n} + end + + if knife_config[:bootstrap_proxy_pass] + client_rb << %Q{http_proxy_pass "#{knife_config[:bootstrap_proxy_pass]}"\n} + client_rb << %Q{https_proxy_pass "#{knife_config[:bootstrap_proxy_pass]}"\n} + end + if knife_config[:bootstrap_no_proxy] client_rb << %Q{no_proxy "#{knife_config[:bootstrap_no_proxy]}"\n} end diff --git a/lib/chef/knife/core/gem_glob_loader.rb b/lib/chef/knife/core/gem_glob_loader.rb index f5eff26903..34c5c53d75 100644 --- a/lib/chef/knife/core/gem_glob_loader.rb +++ b/lib/chef/knife/core/gem_glob_loader.rb @@ -81,9 +81,9 @@ class Chef files = [] if check_load_path - files = $LOAD_PATH.map { |load_path| + files = $LOAD_PATH.map do |load_path| Dir["#{File.expand_path glob, Chef::Util::PathHelper.escape_glob_dir(load_path)}#{Gem.suffix_pattern}"] - }.flatten.select { |file| File.file? file.untaint } + end.flatten.select { |file| File.file? file.untaint } end gem_files = latest_gem_specs.map do |spec| @@ -110,7 +110,7 @@ class Chef end def check_spec_for_glob(spec, glob) - dirs = if spec.require_paths.size > 1 then + dirs = if spec.require_paths.size > 1 "{#{spec.require_paths.join(',')}}" else spec.require_paths.first diff --git a/lib/chef/knife/search.rb b/lib/chef/knife/search.rb index 38d1ab3f42..d102c1e955 100644 --- a/lib/chef/knife/search.rb +++ b/lib/chef/knife/search.rb @@ -18,6 +18,7 @@ require "chef/knife" require "chef/knife/core/node_presenter" +require "addressable/uri" class Chef class Knife @@ -85,8 +86,7 @@ class Chef end q = Chef::Search::Query.new - escaped_query = URI.escape(@query, - Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")) + escaped_query = Addressable::URI.encode_component(@query, Addressable::URI::CharacterClasses::QUERY) result_items = [] result_count = 0 diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb index 2bbcbfc79e..6f266b2719 100644 --- a/lib/chef/knife/ssh.rb +++ b/lib/chef/knife/ssh.rb @@ -164,9 +164,7 @@ class Chef end def configure_session - list = config[:manual] ? - @name_args[0].split(" ") : - search_nodes + list = config[:manual] ? @name_args[0].split(" ") : search_nodes if list.length == 0 if @action_nodes.length == 0 ui.fatal("No nodes returned from search") @@ -548,24 +546,24 @@ class Chef configure_session exit_status = - case @name_args[1] - when "interactive" - interactive - when "screen" - screen - when "tmux" - tmux - when "macterm" - macterm - when "cssh" - cssh - when "csshx" - Chef::Log.warn("knife ssh csshx will be deprecated in a future release") - Chef::Log.warn("please use knife ssh cssh instead") - cssh - else - ssh_command(@name_args[1..-1].join(" ")) - end + case @name_args[1] + when "interactive" + interactive + when "screen" + screen + when "tmux" + tmux + when "macterm" + macterm + when "cssh" + cssh + when "csshx" + Chef::Log.warn("knife ssh csshx will be deprecated in a future release") + Chef::Log.warn("please use knife ssh cssh instead") + cssh + else + ssh_command(@name_args[1..-1].join(" ")) + end session.close if exit_status != 0 diff --git a/lib/chef/knife/status.rb b/lib/chef/knife/status.rb index 551d5addfc..0e3cd7e7d6 100644 --- a/lib/chef/knife/status.rb +++ b/lib/chef/knife/status.rb @@ -96,13 +96,13 @@ class Chef all_nodes << node end - output(all_nodes.sort { |n1, n2| + output(all_nodes.sort do |n1, n2| if config[:sort_reverse] || Chef::Config[:knife][:sort_status_reverse] (n2["ohai_time"] || 0) <=> (n1["ohai_time"] || 0) else (n1["ohai_time"] || 0) <=> (n2["ohai_time"] || 0) end - }) + end) end end diff --git a/lib/chef/mixin/command/unix.rb b/lib/chef/mixin/command/unix.rb index bfd507979f..aa541c3637 100644 --- a/lib/chef/mixin/command/unix.rb +++ b/lib/chef/mixin/command/unix.rb @@ -64,7 +64,7 @@ class Chef $VERBOSE = nil ps.last.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) - cid = fork { + cid = fork do pw.last.close STDIN.reopen pw.first pw.first.close @@ -111,7 +111,7 @@ class Chef end ps.last.close unless ps.last.closed? exit! - } + end ensure $VERBOSE = verbose end diff --git a/lib/chef/mixin/powershell_type_coercions.rb b/lib/chef/mixin/powershell_type_coercions.rb index 381cbed637..6159c87948 100644 --- a/lib/chef/mixin/powershell_type_coercions.rb +++ b/lib/chef/mixin/powershell_type_coercions.rb @@ -63,7 +63,7 @@ class Chef end def unsafe?(s) - ["'", '#', "`", '"'].any? do |x| + ["'", "#", "`", '"'].any? do |x| s.include? x end end diff --git a/lib/chef/mixin/securable.rb b/lib/chef/mixin/securable.rb index a88d534b37..55b4e0a6d1 100644 --- a/lib/chef/mixin/securable.rb +++ b/lib/chef/mixin/securable.rb @@ -43,7 +43,7 @@ class Chef :mode, arg, :callbacks => { - "not in valid numeric range" => lambda { |m| + "not in valid numeric range" => lambda do |m| if m.kind_of?(String) m =~ /^0/ || m = "0#{m}" end @@ -54,7 +54,7 @@ class Chef else Integer(m) <= 07777 && Integer(m) >= 0 end - }, + end, } ) end diff --git a/lib/chef/mixin/uris.rb b/lib/chef/mixin/uris.rb index 24e8a4f9ed..7dc04d662b 100644 --- a/lib/chef/mixin/uris.rb +++ b/lib/chef/mixin/uris.rb @@ -17,6 +17,7 @@ # require "uri" +require "addressable/uri" class Chef module Mixin @@ -34,7 +35,7 @@ class Chef URI.parse(source) rescue URI::InvalidURIError Chef::Log.warn("#{source} was an invalid URI. Trying to escape invalid characters") - URI.parse(URI.escape(source)) + URI.parse(Addressable::URI.encode(source)) end end diff --git a/lib/chef/mixin/windows_architecture_helper.rb b/lib/chef/mixin/windows_architecture_helper.rb index 11e1b5559d..49252af484 100644 --- a/lib/chef/mixin/windows_architecture_helper.rb +++ b/lib/chef/mixin/windows_architecture_helper.rb @@ -74,16 +74,15 @@ class Chef def node_supports_windows_architecture?(node, desired_architecture) assert_valid_windows_architecture!(desired_architecture) - return (node_windows_architecture(node) == :x86_64 || - desired_architecture == :i386) ? true : false + return ( node_windows_architecture(node) == :x86_64 ) || ( desired_architecture == :i386 ) end def valid_windows_architecture?(architecture) - return (architecture == :x86_64) || (architecture == :i386) + return ( architecture == :x86_64 ) || ( architecture == :i386 ) end def assert_valid_windows_architecture!(architecture) - if ! valid_windows_architecture?(architecture) + if !valid_windows_architecture?(architecture) raise Chef::Exceptions::Win32ArchitectureIncorrect, "The specified architecture was not valid. It must be one of :i386 or :x86_64" end diff --git a/lib/chef/monkey_patches/webrick-utils.rb b/lib/chef/monkey_patches/webrick-utils.rb index 7880adb202..ccca5825e2 100644 --- a/lib/chef/monkey_patches/webrick-utils.rb +++ b/lib/chef/monkey_patches/webrick-utils.rb @@ -31,7 +31,7 @@ module WEBrick Socket::AI_PASSIVE) # flag last_error = nil sockets = [] - res.each {|ai| + res.each do |ai| begin logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger sock = TCPServer.new(ai[3], port) @@ -42,7 +42,7 @@ module WEBrick logger.warn("TCPServer Error: #{ex}") if logger last_error = ex end - } + end raise last_error if sockets.empty? return sockets end diff --git a/lib/chef/monologger.rb b/lib/chef/monologger.rb index 8bcdae1293..82816e887f 100644 --- a/lib/chef/monologger.rb +++ b/lib/chef/monologger.rb @@ -61,7 +61,7 @@ class MonoLogger < Logger @dev.close rescue nil end - private + private def open_logfile(filename) if FileTest.exist?(filename) diff --git a/lib/chef/node.rb b/lib/chef/node.rb index 54faab6d3e..212b1ced14 100644 --- a/lib/chef/node.rb +++ b/lib/chef/node.rb @@ -642,8 +642,8 @@ class Chef end end - def <=>(other_node) - self.name <=> other_node.name + def <=>(other) + self.name <=> other.name end private diff --git a/lib/chef/node/attribute.rb b/lib/chef/node/attribute.rb index f5fe89251d..95b3b09f7e 100644 --- a/lib/chef/node/attribute.rb +++ b/lib/chef/node/attribute.rb @@ -537,12 +537,12 @@ class Chef end def inspect - "#<#{self.class} " << (COMPONENTS + [:@merged_attributes, :@properties]).map {|iv| + "#<#{self.class} " << (COMPONENTS + [:@merged_attributes, :@properties]).map do |iv| "#{iv}=#{instance_variable_get(iv).inspect}" - }.join(", ") << ">" + end.join(", ") << ">" end - private + private # Helper method for merge_all/merge_defaults/merge_overrides. # diff --git a/lib/chef/platform/provider_mapping.rb b/lib/chef/platform/provider_mapping.rb index 40474242f0..bc565d92ef 100644 --- a/lib/chef/platform/provider_mapping.rb +++ b/lib/chef/platform/provider_mapping.rb @@ -197,8 +197,11 @@ class Chef def resource_matching_provider(platform, version, resource_type) if resource_type.kind_of?(Chef::Resource) - class_name = resource_type.class.name ? resource_type.class.name.split("::").last : - convert_to_class_name(resource_type.resource_name.to_s) + class_name = if resource_type.class.name + resource_type.class.name.split("::").last + else + convert_to_class_name(resource_type.resource_name.to_s) + end if Chef::Provider.const_defined?(class_name, false) Chef::Log.warn("Class Chef::Provider::#{class_name} does not declare 'provides #{convert_to_snake_case(class_name).to_sym.inspect}'.") diff --git a/lib/chef/property.rb b/lib/chef/property.rb index 0589cb4c54..3cb235b612 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -235,9 +235,9 @@ class Chef # @return [Hash<Symbol,Object>] # def validation_options - @validation_options ||= options.reject { |k, v| + @validation_options ||= options.reject do |k, v| [:declared_in, :name, :instance_variable_name, :desired_state, :identity, :default, :name_property, :coerce, :required, :nillable].include?(k) - } + end end # diff --git a/lib/chef/provider/apt_repository.rb b/lib/chef/provider/apt_repository.rb index 1e7db80620..3a1b247d17 100644 --- a/lib/chef/provider/apt_repository.rb +++ b/lib/chef/provider/apt_repository.rb @@ -254,4 +254,4 @@ class Chef end end -Chef::Provider::Noop.provides :apt_resource +Chef::Provider::Noop.provides :apt_repository diff --git a/lib/chef/provider/apt_update.rb b/lib/chef/provider/apt_update.rb index d2dd5cfb14..03598280c8 100644 --- a/lib/chef/provider/apt_update.rb +++ b/lib/chef/provider/apt_update.rb @@ -16,15 +16,17 @@ # limitations under the License. # -require "chef/resource" -require "chef/dsl/declare_resource" +require "chef/provider" +require "chef/provider/noop" class Chef class Provider class AptUpdate < Chef::Provider use_inline_resources - provides :apt_update, os: "linux" + provides :apt_update do + uses_apt? + end APT_CONF_DIR = "/etc/apt/apt.conf.d" STAMP_DIR = "/var/lib/apt/periodic" @@ -75,6 +77,13 @@ class Chef declare_resource(:execute, "apt-get -q update") end + def self.uses_apt? + ENV["PATH"] ||= "" + paths = %w{ /bin /usr/bin /sbin /usr/sbin } + ENV["PATH"].split(::File::PATH_SEPARATOR) + paths.any? { |path| ::File.executable?(::File.join(path, "apt-get")) } + end end end end + +Chef::Provider::Noop.provides :apt_update diff --git a/lib/chef/provider/cron.rb b/lib/chef/provider/cron.rb index 36b67ab6a5..7baaeec0c5 100644 --- a/lib/chef/provider/cron.rb +++ b/lib/chef/provider/cron.rb @@ -187,8 +187,7 @@ class Chef end crontab << line end - description = cron_found ? "remove #{@new_resource.name} from crontab" : - "save unmodified crontab" + description = cron_found ? "remove #{@new_resource.name} from crontab" : "save unmodified crontab" converge_by(description) do write_crontab crontab Chef::Log.info("#{@new_resource} deleted crontab entry") @@ -237,7 +236,7 @@ class Chef newcron = "" newcron << "# Chef Name: #{new_resource.name}\n" [ :mailto, :path, :shell, :home ].each do |v| - newcron << "#{v.to_s.upcase}=#{@new_resource.send(v)}\n" if @new_resource.send(v) + newcron << "#{v.to_s.upcase}=\"#{@new_resource.send(v)}\"\n" if @new_resource.send(v) end @new_resource.environment.each do |name, value| newcron << "#{name}=#{value}\n" diff --git a/lib/chef/provider/dsc_script.rb b/lib/chef/provider/dsc_script.rb index 79769d9773..66783ceb0f 100644 --- a/lib/chef/provider/dsc_script.rb +++ b/lib/chef/provider/dsc_script.rb @@ -32,12 +32,12 @@ class Chef @dsc_resource = dsc_resource @resource_converged = false @operations = { - :set => Proc.new { |config_manager, document, shellout_flags| + :set => Proc.new do |config_manager, document, shellout_flags| config_manager.set_configuration(document, shellout_flags) - }, - :test => Proc.new { |config_manager, document, shellout_flags| + end, + :test => Proc.new do |config_manager, document, shellout_flags| config_manager.test_configuration(document, shellout_flags) - } } + end } end def action_run diff --git a/lib/chef/provider/group/usermod.rb b/lib/chef/provider/group/usermod.rb index e4b19181aa..bef4b667a2 100644 --- a/lib/chef/provider/group/usermod.rb +++ b/lib/chef/provider/group/usermod.rb @@ -57,7 +57,7 @@ class Chef # This provider only supports adding members with # append. Only if the action is create we will go # ahead and add members. - if @new_resource.action == :create + if @new_resource.action.include?(:create) members.each do |member| add_member(member) end diff --git a/lib/chef/provider/osx_profile.rb b/lib/chef/provider/osx_profile.rb index f2e71a6621..f5535f5c37 100644 --- a/lib/chef/provider/osx_profile.rb +++ b/lib/chef/provider/osx_profile.rb @@ -66,33 +66,33 @@ class Chef def define_resource_requirements requirements.assert(:remove) do |a| if @new_profile_identifier - a.assertion { + a.assertion do !@new_profile_identifier.nil? && !@new_profile_identifier.end_with?(".mobileconfig") && /^\w+(?:\.\w+)+$/.match(@new_profile_identifier) - } + end a.failure_message RuntimeError, "when removing using the identifier attribute, it must match the profile identifier" else new_profile_name = @new_resource.profile_name - a.assertion { + a.assertion do !new_profile_name.end_with?(".mobileconfig") && /^\w+(?:\.\w+)+$/.match(new_profile_name) - } + end a.failure_message RuntimeError, "When removing by resource name, it must match the profile identifier " end end requirements.assert(:install) do |a| if @new_profile_hash.is_a?(Hash) - a.assertion { + a.assertion do @new_profile_hash.include?("PayloadIdentifier") - } + end a.failure_message RuntimeError, "The specified profile does not seem to be valid" end if @new_profile_hash.is_a?(String) - a.assertion { + a.assertion do @new_profile_hash.end_with?(".mobileconfig") - } + end a.failure_message RuntimeError, "#{new_profile_hash}' is not a valid profile" end end diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb index cac0fb6eb0..82b85fb1e4 100644 --- a/lib/chef/provider/package.rb +++ b/lib/chef/provider/package.rb @@ -194,12 +194,12 @@ class Chef end def action_reconfig - if @current_resource.version == nil then + if @current_resource.version == nil Chef::Log.debug("#{@new_resource} is NOT installed - nothing to do") return end - unless @new_resource.response_file then + unless @new_resource.response_file Chef::Log.debug("#{@new_resource} no response_file provided - nothing to do") return end diff --git a/lib/chef/provider/package/rubygems.rb b/lib/chef/provider/package/rubygems.rb index 0aeec951b1..0fd9373dbf 100644 --- a/lib/chef/provider/package/rubygems.rb +++ b/lib/chef/provider/package/rubygems.rb @@ -159,19 +159,22 @@ class Chef # Find the newest gem version available from Gem.sources that satisfies # the constraints of +gem_dependency+ def find_newest_remote_version(gem_dependency, *sources) - available_gems = dependency_installer.find_gems_with_sources(gem_dependency) - spec, source = if available_gems.respond_to?(:last) - # DependencyInstaller sorts the results such that the last one is - # always the one it considers best. - spec_with_source = available_gems.last - spec_with_source && spec_with_source - else - # Rubygems 2.0 returns a Gem::Available set, which is a - # collection of AvailableSet::Tuple structs - available_gems.pick_best! - best_gem = available_gems.set.first - best_gem && [best_gem.spec, best_gem.source] - end + spec, source = + if Chef::Config[:rubygems_cache_enabled] + # This code caches every gem on rubygems.org and uses lots of RAM + available_gems = dependency_installer.find_gems_with_sources(gem_dependency) + available_gems.pick_best! + best_gem = available_gems.set.first + best_gem && [best_gem.spec, best_gem.source] + else + # Use the API that 'gem install' calls which does not pull down the rubygems universe + begin + rs = dependency_installer.resolve_dependencies gem_dependency.name, gem_dependency.requirement + rs.specs.first + rescue Gem::UnsatisfiableDependencyError + nil + end + end version = spec && spec.version if version diff --git a/lib/chef/provider/package/windows/registry_uninstall_entry.rb b/lib/chef/provider/package/windows/registry_uninstall_entry.rb index 3fa00b6081..a693558883 100644 --- a/lib/chef/provider/package/windows/registry_uninstall_entry.rb +++ b/lib/chef/provider/package/windows/registry_uninstall_entry.rb @@ -79,8 +79,6 @@ class Chef attr_reader :uninstall_string attr_reader :data - private - UNINSTALL_SUBKEY = 'Software\Microsoft\Windows\CurrentVersion\Uninstall'.freeze end end diff --git a/lib/chef/provider/package/yum/rpm_utils.rb b/lib/chef/provider/package/yum/rpm_utils.rb index a748c664a9..032597d047 100644 --- a/lib/chef/provider/package/yum/rpm_utils.rb +++ b/lib/chef/provider/package/yum/rpm_utils.rb @@ -243,16 +243,16 @@ class Chef self.new(*args) end - def <=>(y) - compare_versions(y) + def <=>(other) + compare_versions(other) end - def compare(y) - compare_versions(y, false) + def compare(other) + compare_versions(other, false) end - def partial_compare(y) - compare_versions(y, true) + def partial_compare(other) + compare_versions(other, true) end # RPM::Version rpm_version_to_s equivalent @@ -352,8 +352,8 @@ class Chef alias :name :n alias :arch :a - def <=>(y) - compare(y) + def <=>(other) + compare(other) end def compare(y) diff --git a/lib/chef/provider/package/yum/yum_cache.rb b/lib/chef/provider/package/yum/yum_cache.rb index fb25a91c8c..7462529113 100644 --- a/lib/chef/provider/package/yum/yum_cache.rb +++ b/lib/chef/provider/package/yum/yum_cache.rb @@ -197,7 +197,7 @@ class Chef def shabang?(file) ::File.open(file, "r") do |f| - f.read(2) == '#!' + f.read(2) == "#!" end rescue Errno::ENOENT false diff --git a/lib/chef/provider/package/zypper.rb b/lib/chef/provider/package/zypper.rb index 5ee1dbea8e..e20a7332f7 100644 --- a/lib/chef/provider/package/zypper.rb +++ b/lib/chef/provider/package/zypper.rb @@ -38,15 +38,15 @@ class Chef status = shell_out_with_timeout!("zypper --non-interactive info #{package_name}") status.stdout.each_line do |line| case line - when /^Version: (.+)$/ - candidate_version = $1 - Chef::Log.debug("#{new_resource} version #{$1}") - when /^Installed: Yes$/ + when /^Version *: (.+) *$/ + candidate_version = $1.strip + Chef::Log.debug("#{new_resource} version #{candidate_version}") + when /^Installed *: Yes *$/ is_installed = true Chef::Log.debug("#{new_resource} is installed") - when /^Status: out-of-date \(version (.+) installed\)$/ - current_version = $1 - Chef::Log.debug("#{new_resource} out of date version #{$1}") + when /^Status *: out-of-date \(version (.+) installed\) *$/ + current_version = $1.strip + Chef::Log.debug("#{new_resource} out of date version #{current_version}") end end current_version = candidate_version if is_installed diff --git a/lib/chef/provider/remote_file/ftp.rb b/lib/chef/provider/remote_file/ftp.rb index 5935e83301..b382c20c31 100644 --- a/lib/chef/provider/remote_file/ftp.rb +++ b/lib/chef/provider/remote_file/ftp.rb @@ -153,9 +153,9 @@ class Chef def parse_path path = uri.path.sub(%r{\A/}, "%2F") # re-encode the beginning slash because uri library decodes it. directories = path.split(%r{/}, -1) - directories.each {|d| + directories.each do |d| d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") } - } + end unless filename = directories.pop raise ArgumentError, "no filename: #{path.inspect}" end diff --git a/lib/chef/provider/remote_file/sftp.rb b/lib/chef/provider/remote_file/sftp.rb index 530977e3c8..21c5c4ca04 100644 --- a/lib/chef/provider/remote_file/sftp.rb +++ b/lib/chef/provider/remote_file/sftp.rb @@ -68,9 +68,9 @@ class Chef def validate_path! path = uri.path.sub(%r{\A/}, "%2F") # re-encode the beginning slash because uri library decodes it. directories = path.split(%r{/}, -1) - directories.each {|d| + directories.each do |d| d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") } - } + end unless filename = directories.pop raise ArgumentError, "no filename: #{path.inspect}" end diff --git a/lib/chef/provider/service/debian.rb b/lib/chef/provider/service/debian.rb index 67b71953f7..9d11032055 100644 --- a/lib/chef/provider/service/debian.rb +++ b/lib/chef/provider/service/debian.rb @@ -106,13 +106,13 @@ class Chef def service_currently_enabled?(priority) enabled = false - priority.each { |runlevel, arguments| + priority.each do |runlevel, arguments| Chef::Log.debug("#{new_resource} runlevel #{runlevel}, action #{arguments[0]}, priority #{arguments[1]}") # if we are in a update-rc.d default startup runlevel && we start in this runlevel if %w{ 1 2 3 4 5 S }.include?(runlevel) && arguments[0] == :start enabled = true end - } + end enabled end diff --git a/lib/chef/provider/service/simple.rb b/lib/chef/provider/service/simple.rb index fe4768b2e8..d75e85989f 100644 --- a/lib/chef/provider/service/simple.rb +++ b/lib/chef/provider/service/simple.rb @@ -76,8 +76,9 @@ class Chef end requirements.assert(:all_actions) do |a| - a.assertion { @new_resource.status_command || supports[:status] || - (!ps_cmd.nil? && !ps_cmd.empty?) } + a.assertion do + @new_resource.status_command || supports[:status] || + (!ps_cmd.nil? && !ps_cmd.empty?) end a.failure_message Chef::Exceptions::Service, "#{@new_resource} could not determine how to inspect the process table, please set this node's 'command.ps' attribute" end requirements.assert(:all_actions) do |a| @@ -108,7 +109,7 @@ class Chef shell_out_with_systems_locale!(@new_resource.reload_command) end - protected + protected def determine_current_status! if @new_resource.status_command diff --git a/lib/chef/provider/service/solaris.rb b/lib/chef/provider/service/solaris.rb index 1e5398eba8..868b3e1ac1 100644 --- a/lib/chef/provider/service/solaris.rb +++ b/lib/chef/provider/service/solaris.rb @@ -40,7 +40,7 @@ class Chef @current_resource.service_name(@new_resource.service_name) [@init_command, @status_command].each do |cmd| - unless ::File.executable? cmd then + unless ::File.executable? cmd raise Chef::Exceptions::Service, "#{cmd} not executable!" end end diff --git a/lib/chef/provider/service/upstart.rb b/lib/chef/provider/service/upstart.rb index 3ac5ff51da..99ffc24653 100644 --- a/lib/chef/provider/service/upstart.rb +++ b/lib/chef/provider/service/upstart.rb @@ -80,8 +80,11 @@ class Chef shared_resource_requirements requirements.assert(:all_actions) do |a| if !@command_success - whyrun_msg = @new_resource.status_command ? "Provided status command #{@new_resource.status_command} failed." : - "Could not determine upstart state for service" + whyrun_msg = if @new_resource.status_command + "Provided status command #{@new_resource.status_command} failed." + else + "Could not determine upstart state for service" + end end a.assertion { @command_success } # no failure here, just document the assumptions made. diff --git a/lib/chef/provider/template_finder.rb b/lib/chef/provider/template_finder.rb index 67342a86ea..1e8b925071 100644 --- a/lib/chef/provider/template_finder.rb +++ b/lib/chef/provider/template_finder.rb @@ -40,7 +40,7 @@ class Chef cookbook.preferred_filename_on_disk_location(@node, :templates, template_name) end - protected + protected def template_source_name(name, options) if options[:source] diff --git a/lib/chef/provider/user/aix.rb b/lib/chef/provider/user/aix.rb index 3f168b8da3..8ac229ae4d 100644 --- a/lib/chef/provider/user/aix.rb +++ b/lib/chef/provider/user/aix.rb @@ -14,11 +14,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +require "chef/provider/user/useradd" + class Chef class Provider class User class Aix < Chef::Provider::User::Useradd - provides :user, platform: %w{aix} + provides :user, os: "aix" + provides :aix_user UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:shell, "-s"], [:uid, "-u"]] @@ -66,7 +69,7 @@ class Chef shell_out!("chuser account_locked=false #{new_resource.username}") end - private + private def add_password if @current_resource.password != @new_resource.password && @new_resource.password diff --git a/lib/chef/provider/user/dscl.rb b/lib/chef/provider/user/dscl.rb index e933bf9dc0..821fa8e8a7 100644 --- a/lib/chef/provider/user/dscl.rb +++ b/lib/chef/provider/user/dscl.rb @@ -48,6 +48,7 @@ class Chef attr_accessor :authentication_authority attr_accessor :password_shadow_conversion_algorithm + provides :dscl_user provides :user, os: "darwin" def define_resource_requirements diff --git a/lib/chef/provider/user/linux.rb b/lib/chef/provider/user/linux.rb new file mode 100644 index 0000000000..ca331311f1 --- /dev/null +++ b/lib/chef/provider/user/linux.rb @@ -0,0 +1,33 @@ +# +# Copyright:: Copyright 2016, Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require "chef/provider/user/useradd" + +class Chef + class Provider + class User + class Linux < Chef::Provider::User::Useradd + # MAJOR XXX: the implementation of "linux" is the base class and all needs to be moved here + provides :linux_user + provides :user, os: "linux" + + def managing_home_dir? + new_resource.manage_home # linux always 'supports' manage_home + end + end + end + end +end diff --git a/lib/chef/provider/user/pw.rb b/lib/chef/provider/user/pw.rb index 949a21790b..a1d7671c28 100644 --- a/lib/chef/provider/user/pw.rb +++ b/lib/chef/provider/user/pw.rb @@ -22,7 +22,8 @@ class Chef class Provider class User class Pw < Chef::Provider::User - provides :user, platform: %w{freebsd} + provides :pw_user + provides :user, os: "freebsd" def load_current_resource super diff --git a/lib/chef/provider/user/solaris.rb b/lib/chef/provider/user/solaris.rb index 1f0cbb6054..8d3df9e68b 100644 --- a/lib/chef/provider/user/solaris.rb +++ b/lib/chef/provider/user/solaris.rb @@ -24,7 +24,8 @@ class Chef class Provider class User class Solaris < Chef::Provider::User::Useradd - provides :user, platform: %w{omnios solaris2} + provides :solaris_user + provides :user, os: %w{omnios solaris2} UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:shell, "-s"], [:uid, "-u"]] attr_writer :password_file @@ -70,7 +71,7 @@ class Chef shell_out!("passwd", "-u", new_resource.username) end - private + private def manage_password if @current_resource.password != @new_resource.password && @new_resource.password diff --git a/lib/chef/provider/user/useradd.rb b/lib/chef/provider/user/useradd.rb index 3fef8d3642..68b62812a7 100644 --- a/lib/chef/provider/user/useradd.rb +++ b/lib/chef/provider/user/useradd.rb @@ -23,7 +23,7 @@ class Chef class Provider class User class Useradd < Chef::Provider::User - provides :user + # MAJOR XXX: this should become the base class of all Useradd providers instead of the linux implementation UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:password, "-p"], [:shell, "-s"], [:uid, "-u"]] @@ -116,15 +116,15 @@ class Chef update_options(field, option, opts) end if updating_home? + opts << "-d" << new_resource.home if managing_home_dir? Chef::Log.debug("#{new_resource} managing the users home directory") - opts << "-d" << new_resource.home << "-m" + opts << "-m" else Chef::Log.debug("#{new_resource} setting home to #{new_resource.home}") - opts << "-d" << new_resource.home end end - opts << "-o" if new_resource.non_unique || new_resource.supports[:non_unique] + opts << "-o" if new_resource.non_unique opts end end @@ -141,6 +141,7 @@ class Chef def useradd_options opts = [] opts << "-r" if new_resource.system + opts << "-M" unless managing_home_dir? opts end diff --git a/lib/chef/provider/user/windows.rb b/lib/chef/provider/user/windows.rb index 9545b1fd59..b086a1e32b 100644 --- a/lib/chef/provider/user/windows.rb +++ b/lib/chef/provider/user/windows.rb @@ -26,7 +26,7 @@ class Chef class Provider class User class Windows < Chef::Provider::User - + provides :windows_user provides :user, os: "windows" def initialize(new_resource, run_context) diff --git a/lib/chef/provider/windows_script.rb b/lib/chef/provider/windows_script.rb index 2de127addf..3b0202790c 100644 --- a/lib/chef/provider/windows_script.rb +++ b/lib/chef/provider/windows_script.rb @@ -33,8 +33,11 @@ class Chef super( new_resource, run_context ) @script_extension = script_extension - target_architecture = new_resource.architecture.nil? ? - node_windows_architecture(run_context.node) : new_resource.architecture + target_architecture = if new_resource.architecture.nil? + node_windows_architecture(run_context.node) + else + new_resource.architecture + end @is_wow64 = wow64_architecture_override_required?(run_context.node, target_architecture) diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb index 14c47df939..9e2a914b71 100644 --- a/lib/chef/providers.rb +++ b/lib/chef/providers.rb @@ -101,12 +101,13 @@ require "chef/provider/service/macosx" require "chef/provider/service/aixinit" require "chef/provider/service/aix" +require "chef/provider/user/aix" require "chef/provider/user/dscl" +require "chef/provider/user/linux" require "chef/provider/user/pw" +require "chef/provider/user/solaris" require "chef/provider/user/useradd" require "chef/provider/user/windows" -require "chef/provider/user/solaris" -require "chef/provider/user/aix" require "chef/provider/group/aix" require "chef/provider/group/dscl" diff --git a/lib/chef/recipe.rb b/lib/chef/recipe.rb index 3cc5634dc8..77d82f83ab 100644 --- a/lib/chef/recipe.rb +++ b/lib/chef/recipe.rb @@ -18,16 +18,7 @@ # require "chef/dsl/recipe" -require "chef/dsl/data_query" -require "chef/dsl/platform_introspection" -require "chef/dsl/include_recipe" -require "chef/dsl/registry_helper" -require "chef/dsl/reboot_pending" -require "chef/dsl/audit" -require "chef/dsl/powershell" - require "chef/mixin/from_file" - require "chef/mixin/deprecation" class Chef diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 262aa84781..0de5c89475 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -260,6 +260,18 @@ class Chef end # + # Token class to hold an unresolved subscribes call with an associated + # run context. + # + # @api private + # @see Resource#subscribes + class UnresolvedSubscribes < self + # The full key ise given as the name in {Resource#subscribes} + alias_method :to_s, :name + alias_method :declared_key, :name + end + + # # Subscribes to updates from other resources, causing a particular action to # run on *this* resource when the other resource is updated. # @@ -326,7 +338,7 @@ class Chef resources = [resources].flatten resources.each do |resource| if resource.is_a?(String) - resource = Chef::Resource.new(resource, run_context) + resource = UnresolvedSubscribes.new(resource, run_context) end if resource.run_context.nil? resource.run_context = run_context @@ -1264,15 +1276,15 @@ class Chef # resolve_resource_reference on each in turn, causing them to # resolve lazy/forward references. def resolve_notification_references - run_context.before_notifications(self).each { |n| + run_context.before_notifications(self).each do |n| n.resolve_resource_reference(run_context.resource_collection) - } - run_context.immediate_notifications(self).each { |n| + end + run_context.immediate_notifications(self).each do |n| n.resolve_resource_reference(run_context.resource_collection) - } - run_context.delayed_notifications(self).each {|n| + end + run_context.delayed_notifications(self).each do |n| n.resolve_resource_reference(run_context.resource_collection) - } + end end # Helper for #notifies @@ -1563,8 +1575,6 @@ class Chef end end - private - def self.remove_canonical_dsl if @resource_name remaining = Chef.resource_handler_map.delete_canonical(@resource_name, self) diff --git a/lib/chef/resource/freebsd_package.rb b/lib/chef/resource/freebsd_package.rb index 540774e864..a94dd0a928 100644 --- a/lib/chef/resource/freebsd_package.rb +++ b/lib/chef/resource/freebsd_package.rb @@ -45,7 +45,7 @@ class Chef def ships_with_pkgng? # It was not until __FreeBSD_version 1000017 that pkgng became # the default binary package manager. See '/usr/ports/Mk/bsd.port.mk'. - node.automatic[:os_version].to_i >= 1000017 + node[:os_version].to_i >= 1000017 end def assign_provider diff --git a/lib/chef/resource/user.rb b/lib/chef/resource/user.rb index 012fa278f1..a07ce8b24b 100644 --- a/lib/chef/resource/user.rb +++ b/lib/chef/resource/user.rb @@ -21,6 +21,7 @@ require "chef/resource" class Chef class Resource class User < Chef::Resource + resource_name :user_resource_abstract_base_class # this prevents magickal class name DSL wiring identity_attr :username state_attrs :uid, :gid, :home @@ -42,8 +43,8 @@ class Chef @force = false @non_unique = false @supports = { - :manage_home => false, - :non_unique => false, + manage_home: false, + non_unique: false, } @iterations = 27855 @salt = nil @@ -154,7 +155,6 @@ class Chef :kind_of => [ TrueClass, FalseClass ] ) end - end end end diff --git a/lib/chef/resource/user/aix_user.rb b/lib/chef/resource/user/aix_user.rb new file mode 100644 index 0000000000..7c07db2e25 --- /dev/null +++ b/lib/chef/resource/user/aix_user.rb @@ -0,0 +1,31 @@ +# +# Copyright:: Copyright 2016, Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource/user" + +class Chef + class Resource + class User + class AixUser < Chef::Resource::User + resource_name :aix_user + + provides :aix_user + provides :user, os: "aix" + end + end + end +end diff --git a/lib/chef/resource/user/dscl_user.rb b/lib/chef/resource/user/dscl_user.rb new file mode 100644 index 0000000000..61517d8b44 --- /dev/null +++ b/lib/chef/resource/user/dscl_user.rb @@ -0,0 +1,31 @@ +# +# Copyright:: Copyright 2016, Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource/user" + +class Chef + class Resource + class User + class DsclUser < Chef::Resource::User + resource_name :dscl_user + + provides :dscl_user + provides :user, os: "darwin" + end + end + end +end diff --git a/lib/chef/resource/user/linux_user.rb b/lib/chef/resource/user/linux_user.rb new file mode 100644 index 0000000000..3452459e39 --- /dev/null +++ b/lib/chef/resource/user/linux_user.rb @@ -0,0 +1,52 @@ +# +# Copyright:: Copyright 2016, Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource/user" + +class Chef + class Resource + class User + class LinuxUser < Chef::Resource::User + resource_name :linux_user + + provides :linux_user + provides :user, os: "linux" + + def initialize(name, run_context = nil) + super + @supports = { + manage_home: true, + non_unique: true, + } + @manage_home = true + end + + def supports(args = {}) + Chef.log_deprecation "setting supports on the linux_user resource is deprecated" + # setting is deliberately disabled + super({}) + end + + def supports=(args) + Chef.log_deprecation "setting supports on the linux_user resource is deprecated" + # setting is deliberately disabled + supports({}) + end + end + end + end +end diff --git a/lib/chef/resource/user/pw_user.rb b/lib/chef/resource/user/pw_user.rb new file mode 100644 index 0000000000..873be19d59 --- /dev/null +++ b/lib/chef/resource/user/pw_user.rb @@ -0,0 +1,31 @@ +# +# Copyright:: Copyright 2016, Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource/user" + +class Chef + class Resource + class User + class PwUser < Chef::Resource::User + resource_name :pw_user + + provides :pw_user + provides :user, os: "freebsd" + end + end + end +end diff --git a/lib/chef/resource/user/solaris_user.rb b/lib/chef/resource/user/solaris_user.rb new file mode 100644 index 0000000000..bb897228b9 --- /dev/null +++ b/lib/chef/resource/user/solaris_user.rb @@ -0,0 +1,31 @@ +# +# Copyright:: Copyright 2016, Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource/user" + +class Chef + class Resource + class User + class SolarisUser < Chef::Resource::User + resource_name :solaris_user + + provides :solaris_user + provides :user, os: %w{omnios solaris2} + end + end + end +end diff --git a/lib/chef/resource/user/windows_user.rb b/lib/chef/resource/user/windows_user.rb new file mode 100644 index 0000000000..d1a249fb50 --- /dev/null +++ b/lib/chef/resource/user/windows_user.rb @@ -0,0 +1,31 @@ +# +# Copyright:: Copyright 2016, Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource/user" + +class Chef + class Resource + class User + class WindowsUser < Chef::Resource::User + resource_name :windows_user + + provides :windows_user + provides :user, os: "windows" + end + end + end +end diff --git a/lib/chef/resource_builder.rb b/lib/chef/resource_builder.rb index 1641fe60f2..57c57dd8c3 100644 --- a/lib/chef/resource_builder.rb +++ b/lib/chef/resource_builder.rb @@ -31,7 +31,7 @@ class Chef attr_reader :resource # FIXME (ruby-2.1 syntax): most of these are mandatory - def initialize(type:nil, name:nil, created_at: nil, params: nil, run_context: nil, cookbook_name: nil, recipe_name: nil, enclosing_provider: nil) + def initialize(type: nil, name: nil, created_at: nil, params: nil, run_context: nil, cookbook_name: nil, recipe_name: nil, enclosing_provider: nil) @type = type @name = name @created_at = created_at diff --git a/lib/chef/resource_collection/stepable_iterator.rb b/lib/chef/resource_collection/stepable_iterator.rb index d1165764ca..958ffa28cb 100644 --- a/lib/chef/resource_collection/stepable_iterator.rb +++ b/lib/chef/resource_collection/stepable_iterator.rb @@ -100,9 +100,7 @@ class Chef end def iterate - while @position < size && !paused? - step - end + step while @position < size && !paused? collection end diff --git a/lib/chef/resource_reporter.rb b/lib/chef/resource_reporter.rb index 4135483441..8422870e2a 100644 --- a/lib/chef/resource_reporter.rb +++ b/lib/chef/resource_reporter.rb @@ -26,11 +26,11 @@ require "chef/event_dispatch/base" class Chef class ResourceReporter < EventDispatch::Base - class ResourceReport < Struct.new(:new_resource, - :current_resource, - :action, - :exception, - :elapsed_time) + ResourceReport = Struct.new(:new_resource, + :current_resource, + :action, + :exception, + :elapsed_time) do def self.new_with_current_state(new_resource, action, current_resource) report = new diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb index af9c918f55..0e73264832 100644 --- a/lib/chef/resources.rb +++ b/lib/chef/resources.rb @@ -82,6 +82,12 @@ require "chef/resource/smartos_package" require "chef/resource/template" require "chef/resource/timestamped_deploy" require "chef/resource/user" +require "chef/resource/user/aix_user" +require "chef/resource/user/dscl_user" +require "chef/resource/user/linux_user" +require "chef/resource/user/pw_user" +require "chef/resource/user/solaris_user" +require "chef/resource/user/windows_user" require "chef/resource/whyrun_safe_ruby_block" require "chef/resource/windows_package" require "chef/resource/yum_package" diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb index 29c936a932..7ef476c44b 100644 --- a/lib/chef/run_context.rb +++ b/lib/chef/run_context.rb @@ -194,12 +194,10 @@ class Chef # @param [Chef::Resource::Notification] The notification to add. # def notifies_before(notification) - nr = notification.notifying_resource - if nr.instance_of?(Chef::Resource) - before_notification_collection[nr.name] << notification - else - before_notification_collection[nr.declared_key] << notification - end + # Note for the future, notification.notifying_resource may be an instance + # of Chef::Resource::UnresolvedSubscribes when calling {Resource#subscribes} + # with a string value. + before_notification_collection[notification.notifying_resource.declared_key] << notification end # @@ -208,12 +206,10 @@ class Chef # @param [Chef::Resource::Notification] The notification to add. # def notifies_immediately(notification) - nr = notification.notifying_resource - if nr.instance_of?(Chef::Resource) - immediate_notification_collection[nr.name] << notification - else - immediate_notification_collection[nr.declared_key] << notification - end + # Note for the future, notification.notifying_resource may be an instance + # of Chef::Resource::UnresolvedSubscribes when calling {Resource#subscribes} + # with a string value. + immediate_notification_collection[notification.notifying_resource.declared_key] << notification end # @@ -222,12 +218,10 @@ class Chef # @param [Chef::Resource::Notification] The notification to add. # def notifies_delayed(notification) - nr = notification.notifying_resource - if nr.instance_of?(Chef::Resource) - delayed_notification_collection[nr.name] << notification - else - delayed_notification_collection[nr.declared_key] << notification - end + # Note for the future, notification.notifying_resource may be an instance + # of Chef::Resource::UnresolvedSubscribes when calling {Resource#subscribes} + # with a string value. + delayed_notification_collection[notification.notifying_resource.declared_key] << notification end # @@ -245,50 +239,29 @@ class Chef # # Get the list of before notifications sent by the given resource. # - # TODO seriously, this is actually wrong. resource.name is not unique, - # you need the type as well. - # # @return [Array[Notification]] # def before_notifications(resource) - if resource.instance_of?(Chef::Resource) - return before_notification_collection[resource.name] - else - return before_notification_collection[resource.declared_key] - end + return before_notification_collection[resource.declared_key] end # # Get the list of immediate notifications sent by the given resource. # - # TODO seriously, this is actually wrong. resource.name is not unique, - # you need the type as well. - # # @return [Array[Notification]] # def immediate_notifications(resource) - if resource.instance_of?(Chef::Resource) - return immediate_notification_collection[resource.name] - else - return immediate_notification_collection[resource.declared_key] - end + return immediate_notification_collection[resource.declared_key] end # # Get the list of delayed (end of run) notifications sent by the given # resource. # - # TODO seriously, this is actually wrong. resource.name is not unique, - # you need the type as well. - # # @return [Array[Notification]] # def delayed_notifications(resource) - if resource.instance_of?(Chef::Resource) - return delayed_notification_collection[resource.name] - else - return delayed_notification_collection[resource.declared_key] - end + return delayed_notification_collection[resource.declared_key] end # diff --git a/lib/chef/run_list.rb b/lib/chef/run_list.rb index 4dea938423..3ac5fab07b 100644 --- a/lib/chef/run_list.rb +++ b/lib/chef/run_list.rb @@ -47,13 +47,13 @@ class Chef end def role_names - @run_list_items.inject([]) { |memo, run_list_item| memo << run_list_item.name if run_list_item.role? ; memo } + @run_list_items.inject([]) { |memo, run_list_item| memo << run_list_item.name if run_list_item.role?; memo } end alias :roles :role_names def recipe_names - @run_list_items.inject([]) { |memo, run_list_item| memo << run_list_item.name if run_list_item.recipe? ; memo } + @run_list_items.inject([]) { |memo, run_list_item| memo << run_list_item.name if run_list_item.recipe?; memo } end alias :recipes :recipe_names diff --git a/lib/chef/search/query.rb b/lib/chef/search/query.rb index ebf13bec36..bea8205935 100644 --- a/lib/chef/search/query.rb +++ b/lib/chef/search/query.rb @@ -21,6 +21,7 @@ require "chef/exceptions" require "chef/server_api" require "uri" +require "addressable/uri" class Chef class Search @@ -29,7 +30,7 @@ class Chef attr_accessor :rest attr_reader :config - def initialize(url = nil, config:Chef::Config) + def initialize(url = nil, config: Chef::Config) @config = config @url = url end @@ -134,19 +135,21 @@ WARNDEP args_h end - def escape(s) - s && URI.escape(s.to_s) + QUERY_PARAM_VALUE = Addressable::URI::CharacterClasses::QUERY + "\\&\\;" + + def escape_value(s) + s && Addressable::URI.encode_component(s.to_s, QUERY_PARAM_VALUE) end def create_query_string(type, query, rows, start, sort) - qstr = "search/#{type}?q=#{escape(query)}" - qstr += "&sort=#{escape(sort)}" if sort - qstr += "&start=#{escape(start)}" if start - qstr += "&rows=#{escape(rows)}" if rows + qstr = "search/#{type}?q=#{escape_value(query)}" + qstr += "&sort=#{escape_value(sort)}" if sort + qstr += "&start=#{escape_value(start)}" if start + qstr += "&rows=#{escape_value(rows)}" if rows qstr end - def call_rest_service(type, query:"*:*", rows:nil, start:0, sort:"X_CHEF_id_CHEF_X asc", filter_result:nil) + def call_rest_service(type, query: "*:*", rows: nil, start: 0, sort: "X_CHEF_id_CHEF_X asc", filter_result: nil) query_string = create_query_string(type, query, rows, start, sort) if filter_result diff --git a/lib/chef/shell/ext.rb b/lib/chef/shell/ext.rb index 40d7e10d2e..0c10309521 100644 --- a/lib/chef/shell/ext.rb +++ b/lib/chef/shell/ext.rb @@ -39,13 +39,13 @@ module Shell # irb breaks if you prematurely define IRB::JobMangager # so these methods need to be defined at the latest possible time. unless jobs.respond_to?(:select_session_by_context) - def jobs.select_session_by_context(&block) + def jobs.select_session_by_context(&block) # rubocop:disable Lint/NestedMethodDefinition @jobs.select { |job| block.call(job[1].context.main) } end end unless jobs.respond_to?(:session_select) - def jobs.select_shell_session(target_context) + def jobs.select_shell_session(target_context) # rubocop:disable Lint/NestedMethodDefinition session = if target_context.kind_of?(Class) select_session_by_context { |main| main.kind_of?(target_context) } else diff --git a/lib/chef/shell/shell_session.rb b/lib/chef/shell/shell_session.rb index 0a8cba5be3..a458286157 100644 --- a/lib/chef/shell/shell_session.rb +++ b/lib/chef/shell/shell_session.rb @@ -126,7 +126,7 @@ module Shell end def shorten_node_inspect - def @node.inspect + def @node.inspect # rubocop:disable Lint/NestedMethodDefinition "<Chef::Node:0x#{self.object_id.to_s(16)} @name=\"#{self.name}\">" end end diff --git a/lib/chef/util/dsc/configuration_generator.rb b/lib/chef/util/dsc/configuration_generator.rb index 739a463ad5..8b492d483a 100644 --- a/lib/chef/util/dsc/configuration_generator.rb +++ b/lib/chef/util/dsc/configuration_generator.rb @@ -48,7 +48,7 @@ class Chef::Util::DSC configuration_document_location = find_configuration_document(configuration_name) if ! configuration_document_location - raise RuntimeError, "No DSC configuration for '#{configuration_name}' was generated from supplied DSC script" + raise "No DSC configuration for '#{configuration_name}' was generated from supplied DSC script" end configuration_document = get_configuration_document(configuration_document_location) diff --git a/lib/chef/util/powershell/cmdlet.rb b/lib/chef/util/powershell/cmdlet.rb index 6ab380c071..e300266b1e 100644 --- a/lib/chef/util/powershell/cmdlet.rb +++ b/lib/chef/util/powershell/cmdlet.rb @@ -62,8 +62,11 @@ class Chef json_depth = @output_format_options[:depth] end - json_command = @json_format ? " | convertto-json -compress -depth #{json_depth} "\ - "> #{streams[:json].path}" : "" + json_command = if @json_format + " | convertto-json -compress -depth #{json_depth} > #{streams[:json].path}" + else + "" + end redirections = "4> '#{streams[:verbose].path}'" command_string = "powershell.exe -executionpolicy bypass -noprofile -noninteractive "\ "-command \"trap [Exception] {write-error -exception "\ diff --git a/lib/chef/util/selinux.rb b/lib/chef/util/selinux.rb index 1aac7eeeca..edca589034 100644 --- a/lib/chef/util/selinux.rb +++ b/lib/chef/util/selinux.rb @@ -78,7 +78,7 @@ class Chef when 0 return true else - raise RuntimeError, "Unknown exit code from command #{selinuxenabled_path}: #{cmd.exitstatus}" + raise "Unknown exit code from command #{selinuxenabled_path}: #{cmd.exitstatus}" end else # We assume selinux is not enabled if selinux utils are not diff --git a/lib/chef/version.rb b/lib/chef/version.rb index 82060f7a3c..8bbfcd413f 100644 --- a/lib/chef/version.rb +++ b/lib/chef/version.rb @@ -21,7 +21,7 @@ class Chef CHEF_ROOT = File.expand_path("../..", __FILE__) - VERSION = "12.12.24" + VERSION = "12.14.24" end # diff --git a/lib/chef/version_class.rb b/lib/chef/version_class.rb index 35a9f3282f..f26368902d 100644 --- a/lib/chef/version_class.rb +++ b/lib/chef/version_class.rb @@ -32,10 +32,15 @@ class Chef "#{@major}.#{@minor}.#{@patch}" end - def <=>(v) + def <=>(other) [:major, :minor, :patch].each do |method| - ans = (self.send(method) <=> v.send(method)) - return ans if ans != 0 + version = self.send(method) + begin + ans = (version <=> other.send(method)) + rescue NoMethodError # if the other thing isn't a version object, return nil + return nil + end + return ans unless ans == 0 end 0 end diff --git a/lib/chef/version_constraint.rb b/lib/chef/version_constraint.rb index d4fa5df775..f10325f946 100644 --- a/lib/chef/version_constraint.rb +++ b/lib/chef/version_constraint.rb @@ -57,8 +57,8 @@ class Chef "#{@op} #{@raw_version}" end - def eql?(o) - o.class == self.class && @op == o.op && @version == o.version + def eql?(other) + other.class == self.class && @op == other.op && @version == other.version end alias_method :==, :eql? diff --git a/lib/chef/win32/api/error.rb b/lib/chef/win32/api/error.rb index dc83f9cb2b..12ccdb5ee9 100644 --- a/lib/chef/win32/api/error.rb +++ b/lib/chef/win32/api/error.rb @@ -194,12 +194,12 @@ class Chef ERROR_INVALID_EXE_SIGNATURE = 191 ERROR_EXE_MARKED_INVALID = 192 ERROR_BAD_EXE_FORMAT = 193 - ERROR_ITERATED_DATA_EXCEEDS_64k = 194 + ERROR_ITERATED_DATA_EXCEEDS_64k = 194 # rubocop:disable Style/ConstantName ERROR_INVALID_MINALLOCSIZE = 195 ERROR_DYNLINK_FROM_INVALID_RING = 196 ERROR_IOPL_NOT_ENABLED = 197 ERROR_INVALID_SEGDPL = 198 - ERROR_AUTODATASEG_EXCEEDS_64k = 199 + ERROR_AUTODATASEG_EXCEEDS_64k = 199 # rubocop:disable Style/ConstantName ERROR_RING2SEG_MUST_BE_MOVABLE = 200 ERROR_RELOC_CHAIN_XEEDS_SEGLIM = 201 ERROR_INFLOOP_IN_RELOC_CHAIN = 202 diff --git a/lib/chef/win32/api/net.rb b/lib/chef/win32/api/net.rb index bec00f638a..abf0dd83ec 100644 --- a/lib/chef/win32/api/net.rb +++ b/lib/chef/win32/api/net.rb @@ -45,7 +45,7 @@ class Chef USE_FORCE = 1 USE_LOTS_OF_FORCE = 2 #every windows API should support this flag - NERR_Success = 0 + NERR_Success = 0 # rubocop:disable Style/ConstantName ERROR_MORE_DATA = 234 ffi_lib "netapi32" diff --git a/lib/chef/win32/eventlog.rb b/lib/chef/win32/eventlog.rb index 4254b8ead3..eae0ae4abf 100644 --- a/lib/chef/win32/eventlog.rb +++ b/lib/chef/win32/eventlog.rb @@ -26,6 +26,6 @@ if Chef::Platform.windows? && (not Chef::Platform.windows_server_2003?) end require "win32/eventlog" - Chef::Win32EventLogLoaded = true + Chef::Win32EventLogLoaded = true # rubocop:disable Style/ConstantName end end diff --git a/lib/chef/win32/file.rb b/lib/chef/win32/file.rb index 2a8f453432..1009f8c5a9 100644 --- a/lib/chef/win32/file.rb +++ b/lib/chef/win32/file.rb @@ -39,7 +39,7 @@ class Chef # returns nil as per MRI. # def self.link(old_name, new_name) - raise Errno::ENOENT, "(#{old_name}, #{new_name})" unless ::File.exist?(old_name) + raise Errno::ENOENT, "(#{old_name}, #{new_name})" unless ::File.exist?(old_name) || ::File.symlink?(old_name) # TODO do a check for CreateHardLinkW and # raise NotImplemented exception on older Windows old_name = encode_path(old_name) @@ -56,7 +56,7 @@ class Chef # returns nil as per MRI. # def self.symlink(old_name, new_name) - # raise Errno::ENOENT, "(#{old_name}, #{new_name})" unless ::File.exist?(old_name) + # raise Errno::ENOENT, "(#{old_name}, #{new_name})" unless ::File.exist?(old_name) || ::File.symlink?(old_name) # TODO do a check for CreateSymbolicLinkW and # raise NotImplemented exception on older Windows flags = ::File.directory?(old_name) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 @@ -75,7 +75,7 @@ class Chef def self.symlink?(file_name) is_symlink = false path = encode_path(file_name) - if ::File.exists?(file_name) + if ::File.exists?(file_name) || ::File.symlink?(file_name) if (GetFileAttributesW(path) & FILE_ATTRIBUTE_REPARSE_POINT) > 0 file_search_handle(file_name) do |handle, find_data| if find_data[:dw_reserved_0] == IO_REPARSE_TAG_SYMLINK @@ -93,7 +93,7 @@ class Chef # will raise a NotImplementedError, as per MRI. # def self.readlink(link_name) - raise Errno::ENOENT, link_name unless ::File.exists?(link_name) + raise Errno::ENOENT, link_name unless ::File.exists?(link_name) || ::File.symlink?(link_name) symlink_file_handle(link_name) do |handle| # Go to DeviceIoControl to get the symlink information # http://msdn.microsoft.com/en-us/library/windows/desktop/aa364571(v=vs.85).aspx diff --git a/lib/chef/win32/net.rb b/lib/chef/win32/net.rb index 0454b17d49..09db2af89d 100644 --- a/lib/chef/win32/net.rb +++ b/lib/chef/win32/net.rb @@ -207,7 +207,7 @@ class Chef def self.members_to_lgrmi3(members) buf = FFI::MemoryPointer.new(LOCALGROUP_MEMBERS_INFO_3, members.size) - members.size.times.collect do |i| + Array.new(members.size) do |i| member_info = LOCALGROUP_MEMBERS_INFO_3.new( buf + i * LOCALGROUP_MEMBERS_INFO_3.size) member_info[:lgrmi3_domainandname] = FFI::MemoryPointer.from_string(wstring(members[i])) diff --git a/lib/chef/win32/security/sid.rb b/lib/chef/win32/security/sid.rb index 9951b931c9..f6b88c60ce 100644 --- a/lib/chef/win32/security/sid.rb +++ b/lib/chef/win32/security/sid.rb @@ -279,7 +279,7 @@ class Chef status = NetUserEnum(servername, level, filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle) if status == NERR_Success || status == ERROR_MORE_DATA - entriesread.read_long.times.collect do |i| + Array.new(entriesread.read_long) do |i| user_info = USER_INFO_3.new(bufptr.read_pointer + i * USER_INFO_3.size) # Check if the account is the Administrator account # RID for the Administrator account is always 500 and it's privilage is set to USER_PRIV_ADMIN diff --git a/omnibus/Gemfile b/omnibus/Gemfile index 3e19adfb39..12b6171271 100644 --- a/omnibus/Gemfile +++ b/omnibus/Gemfile @@ -1,7 +1,8 @@ source "https://rubygems.org" -gem "omnibus", git: "https://github.com/chef/omnibus.git" -gem "omnibus-software", git: "https://github.com/chef/omnibus-software.git" +gem "omnibus", github: "chef/omnibus", branch: "sersut/ff-ksubrama/gcc_investigate" +gem "omnibus-software", github: "chef/omnibus-software", branch: "sersut/ff-ksubrama/ruby23" +gem "license_scout", github: "chef/license_scout" # pedump pessimistically pins multipart-post to a version from 2013 which makes # bundler very unhappy. Remove this when upstream has merged zed-0xff/pedump#6 . diff --git a/omnibus/Gemfile.lock b/omnibus/Gemfile.lock index 39f5dbba9d..e3d0f24ead 100644 --- a/omnibus/Gemfile.lock +++ b/omnibus/Gemfile.lock @@ -1,19 +1,31 @@ GIT - remote: https://github.com/chef/omnibus-software.git - revision: cb6f0afa1cd334f25aece7deeef3a9454cecc0e7 + remote: git://github.com/chef/license_scout.git + revision: 3f33a3cb48cf4a796b2017a8fb25cf1cb22bf3ab + specs: + license_scout (0.1.0) + ffi-yajl (~> 2.2) + mixlib-shellout (~> 2.2) + +GIT + remote: git://github.com/chef/omnibus-software.git + revision: 676b89e48a213f34567f847c1c2aa20f08d5a2b7 + branch: sersut/ff-ksubrama/ruby23 specs: omnibus-software (4.0.0) - omnibus (>= 5.2.0) + chef-sugar (>= 3.4.0) + omnibus (>= 5.5.0) GIT - remote: https://github.com/chef/omnibus.git - revision: 56b8e507df41bc6fa6e452441dc9df5744892e34 + remote: git://github.com/chef/omnibus.git + revision: 96d4695285c9530ff3b6b8160bc46e3ac6b19dd0 + branch: sersut/ff-ksubrama/gcc_investigate specs: - omnibus (5.4.0) + omnibus (5.5.0) aws-sdk (~> 2) chef-sugar (~> 3.3) cleanroom (~> 1.0) ffi-yajl (~> 2.2) + license_scout mixlib-shellout (~> 2.0) mixlib-versioning ohai (~> 8.0) @@ -36,15 +48,15 @@ GEM remote: https://rubygems.org/ specs: addressable (2.4.0) - artifactory (2.3.2) + artifactory (2.3.3) awesome_print (1.7.0) - aws-sdk (2.3.14) - aws-sdk-resources (= 2.3.14) - aws-sdk-core (2.3.14) + aws-sdk (2.5.4) + aws-sdk-resources (= 2.5.4) + aws-sdk-core (2.5.4) jmespath (~> 1.0) - aws-sdk-resources (2.3.14) - aws-sdk-core (= 2.3.14) - berkshelf (4.3.3) + aws-sdk-resources (2.5.4) + aws-sdk-core (= 2.5.4) + berkshelf (4.3.5) addressable (~> 2.3, >= 2.3.4) berkshelf-api-client (~> 2.0, >= 2.0.2) buff-config (~> 1.0) @@ -56,6 +68,7 @@ GEM faraday (~> 0.9) httpclient (~> 2.7) minitar (~> 0.5, >= 0.5.4) + mixlib-archive (~> 0.1) octokit (~> 4.0) retryable (~> 2.0) ridley (~> 4.5) @@ -82,22 +95,22 @@ GEM celluloid-io (0.16.2) celluloid (>= 0.16.0) nio4r (>= 1.1.0) - chef-config (12.11.18) - fuzzyurl (~> 0.8.0) + chef-config (12.13.30) + fuzzyurl mixlib-config (~> 2.0) mixlib-shellout (~> 2.0) - chef-sugar (3.3.0) + chef-sugar (3.4.0) cleanroom (1.0.0) coderay (1.1.1) debug_inspector (0.0.2) erubis (2.7.0) faraday (0.9.2) multipart-post (>= 1.2, < 3) - ffi (1.9.10) - ffi (1.9.10-x86-mingw32) - ffi-yajl (2.2.3) + ffi (1.9.14) + ffi (1.9.14-x86-mingw32) + ffi-yajl (2.3.0) libyajl2 (~> 1.2) - fuzzyurl (0.8.0) + fuzzyurl (0.9.0) gssapi (1.2.0) ffi (>= 1.0.1) gyoku (1.3.1) @@ -108,10 +121,8 @@ GEM httpclient (2.7.2) iostruct (0.0.4) ipaddress (0.8.3) - jmespath (1.2.4) - json_pure (>= 1.8.1) - json (1.8.3) - json_pure (1.8.3) + jmespath (1.3.1) + json (2.0.2) kitchen-vagrant (0.19.0) test-kitchen (~> 1.4) libyajl2 (1.2.0) @@ -121,15 +132,17 @@ GEM multi_json (~> 1.10) method_source (0.8.2) minitar (0.5.4) + mixlib-archive (0.2.0) + mixlib-log mixlib-authentication (1.4.1) mixlib-log - mixlib-cli (1.6.0) + mixlib-cli (1.7.0) mixlib-config (2.2.1) - mixlib-install (1.0.12) + mixlib-install (1.1.0) artifactory mixlib-shellout mixlib-versioning - mixlib-log (1.6.0) + mixlib-log (1.7.1) mixlib-shellout (2.2.6) mixlib-shellout (2.2.6-universal-mingw32) win32-process (~> 0.8.2) @@ -140,26 +153,26 @@ GEM multipart-post (1.2.0) net-scp (1.2.1) net-ssh (>= 2.6.5) - net-ssh (3.1.1) + net-ssh (3.2.0) nio4r (1.2.1) nori (2.6.0) octokit (4.3.0) sawyer (~> 0.7.0, >= 0.5.3) - ohai (8.17.0) + ohai (8.19.2) chef-config (>= 12.5.0.alpha.1, < 13) ffi (~> 1.9) ffi-yajl (~> 2.2) ipaddress mixlib-cli mixlib-config (~> 2.0) - mixlib-log + mixlib-log (>= 1.7.1, < 2.0) mixlib-shellout (~> 2.0) plist (~> 3.1) systemu (~> 2.6.4) wmi-lite (~> 1.0) plist (3.2.0) progressbar (0.21.0) - pry (0.10.3) + pry (0.10.4) coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) @@ -169,12 +182,12 @@ GEM pry-stack_explorer (0.4.9.2) binding_of_caller (>= 0.7) pry (>= 0.9.11) - retryable (2.0.3) - ridley (4.5.1) + retryable (2.0.4) + ridley (4.6.1) addressable buff-config (~> 1.0) buff-extensions (~> 1.0) - buff-ignore (~> 1.1) + buff-ignore (~> 1.1.1) buff-shell_out (~> 0.1) celluloid (~> 0.16.0) celluloid-io (~> 0.16.1) @@ -201,7 +214,7 @@ GEM molinillo (~> 0.4.2) semverse (~> 1.1) systemu (2.6.5) - test-kitchen (1.9.2) + test-kitchen (1.10.2) mixlib-install (~> 1.0, >= 1.0.4) mixlib-shellout (>= 1.2, < 3.0) net-scp (~> 1.1) @@ -224,7 +237,7 @@ GEM logging (>= 1.6.1, < 3.0) nori (~> 2.0) rubyntlm (~> 0.6.0) - winrm-fs (0.4.2) + winrm-fs (0.4.3) erubis (~> 2.7) logging (>= 1.6.1, < 3.0) rubyzip (~> 1.1) @@ -239,6 +252,7 @@ PLATFORMS DEPENDENCIES berkshelf (~> 4.0) kitchen-vagrant (~> 0.19.0) + license_scout! omnibus! omnibus-software! pedump! diff --git a/omnibus/config/software/chef-appbundle.rb b/omnibus/config/software/chef-appbundle.rb index 495f58bfb1..8ea21103fb 100644 --- a/omnibus/config/software/chef-appbundle.rb +++ b/omnibus/config/software/chef-appbundle.rb @@ -2,6 +2,7 @@ name "chef-appbundle" default_version "local_source" license :project_license +skip_transitive_dependency_licensing true source path: project.files_path diff --git a/omnibus/config/software/chef-complete.rb b/omnibus/config/software/chef-complete.rb index 2c2b1ca205..8ca370c832 100644 --- a/omnibus/config/software/chef-complete.rb +++ b/omnibus/config/software/chef-complete.rb @@ -1,6 +1,7 @@ name "chef-complete" license :project_license +skip_transitive_dependency_licensing true dependency "chef" dependency "chef-appbundle" @@ -17,5 +18,3 @@ if windows? dependency "ruby-windows-devkit" dependency "ruby-windows-devkit-bash" end - -dependency "clean-static-libs" diff --git a/omnibus/config/software/chef-gem-binding_of_caller.rb b/omnibus/config/software/chef-gem-binding_of_caller.rb index ed9083f3b9..3e7a9f9c70 100644 --- a/omnibus/config/software/chef-gem-binding_of_caller.rb +++ b/omnibus/config/software/chef-gem-binding_of_caller.rb @@ -7,3 +7,4 @@ BuildChefGem::GemInstallSoftwareDef.define(self, __FILE__) license "MIT" license_file "https://github.com/banister/binding_of_caller/blob/master/LICENSE" +skip_transitive_dependency_licensing true diff --git a/omnibus/config/software/chef-gem-byebug.rb b/omnibus/config/software/chef-gem-byebug.rb index f16daa29a0..3aef706e82 100644 --- a/omnibus/config/software/chef-gem-byebug.rb +++ b/omnibus/config/software/chef-gem-byebug.rb @@ -7,3 +7,4 @@ BuildChefGem::GemInstallSoftwareDef.define(self, __FILE__) license "MIT" license_file "https://github.com/deivid-rodriguez/byebug/blob/master/LICENSE" +skip_transitive_dependency_licensing true diff --git a/omnibus/config/software/chef-gem-debug_inspector.rb b/omnibus/config/software/chef-gem-debug_inspector.rb index a3432a8de3..ab818768ea 100644 --- a/omnibus/config/software/chef-gem-debug_inspector.rb +++ b/omnibus/config/software/chef-gem-debug_inspector.rb @@ -7,3 +7,4 @@ BuildChefGem::GemInstallSoftwareDef.define(self, __FILE__) license "MIT" license_file "https://github.com/banister/debug_inspector/blob/master/README.md" +skip_transitive_dependency_licensing true diff --git a/omnibus/config/software/chef-gem-ffi-yajl.rb b/omnibus/config/software/chef-gem-ffi-yajl.rb index bba55a3882..44f98446bd 100644 --- a/omnibus/config/software/chef-gem-ffi-yajl.rb +++ b/omnibus/config/software/chef-gem-ffi-yajl.rb @@ -7,5 +7,6 @@ BuildChefGem::GemInstallSoftwareDef.define(self, __FILE__) license "MIT" license_file "https://github.com/chef/ffi-yajl/blob/master/LICENSE" +skip_transitive_dependency_licensing true dependency "chef-gem-libyajl2" diff --git a/omnibus/config/software/chef-gem-ffi.rb b/omnibus/config/software/chef-gem-ffi.rb index 4d54105a0c..ea8879c2ac 100644 --- a/omnibus/config/software/chef-gem-ffi.rb +++ b/omnibus/config/software/chef-gem-ffi.rb @@ -5,7 +5,8 @@ require_relative "../../files/chef-gem/build-chef-gem/gem-install-software-def" BuildChefGem::GemInstallSoftwareDef.define(self, __FILE__) -license "BSD-3-CLAUSE" +license "BSD-3-Clause" license_file "https://github.com/ffi/ffi/blob/master/LICENSE" license_file "https://github.com/ffi/ffi/blob/master/COPYING" license_file "https://github.com/ffi/ffi/blob/master/LICENSE.SPECS" +skip_transitive_dependency_licensing true diff --git a/omnibus/config/software/chef-gem-json.rb b/omnibus/config/software/chef-gem-json.rb index b2d848c77a..9217359ba2 100644 --- a/omnibus/config/software/chef-gem-json.rb +++ b/omnibus/config/software/chef-gem-json.rb @@ -8,3 +8,4 @@ BuildChefGem::GemInstallSoftwareDef.define(self, __FILE__) license "Ruby" license_file "https://github.com/flori/json/blob/master/README.md" license_file "https://www.ruby-lang.org/en/about/license.txt" +skip_transitive_dependency_licensing true diff --git a/omnibus/config/software/chef-gem-libyajl2.rb b/omnibus/config/software/chef-gem-libyajl2.rb index 609e3c3089..47ef42e1cf 100644 --- a/omnibus/config/software/chef-gem-libyajl2.rb +++ b/omnibus/config/software/chef-gem-libyajl2.rb @@ -7,3 +7,4 @@ BuildChefGem::GemInstallSoftwareDef.define(self, __FILE__) license "Apache-2.0" license_file "https://github.com/chef/libyajl2-gem/blob/master/LICENSE" +skip_transitive_dependency_licensing true diff --git a/omnibus/config/software/chef-gem-mini_portile2.rb b/omnibus/config/software/chef-gem-mini_portile2.rb index 9ffa040c14..36a2b833dd 100644 --- a/omnibus/config/software/chef-gem-mini_portile2.rb +++ b/omnibus/config/software/chef-gem-mini_portile2.rb @@ -7,3 +7,4 @@ BuildChefGem::GemInstallSoftwareDef.define(self, __FILE__) license "MIT" license_file "https://github.com/flavorjones/mini_portile/blob/master/LICENSE.txt" +skip_transitive_dependency_licensing true diff --git a/omnibus/config/software/chef-gem-nokogiri.rb b/omnibus/config/software/chef-gem-nokogiri.rb index a25a47d341..c6b8d03822 100644 --- a/omnibus/config/software/chef-gem-nokogiri.rb +++ b/omnibus/config/software/chef-gem-nokogiri.rb @@ -7,6 +7,7 @@ BuildChefGem::GemInstallSoftwareDef.define(self, __FILE__) license "MIT" license_file "https://github.com/ruby-prof/ruby-prof/blob/master/LICENSE" +skip_transitive_dependency_licensing true dependency "chef-gem-pkg-config" dependency "chef-gem-mini_portile2" diff --git a/omnibus/config/software/chef-gem-pkg-config.rb b/omnibus/config/software/chef-gem-pkg-config.rb index 9c6e6fa695..051091b73f 100644 --- a/omnibus/config/software/chef-gem-pkg-config.rb +++ b/omnibus/config/software/chef-gem-pkg-config.rb @@ -7,3 +7,4 @@ BuildChefGem::GemInstallSoftwareDef.define(self, __FILE__) license "LGPL-2.1" license_file "https://github.com/ruby-gnome2/pkg-config/blob/master/LGPL-2.1" +skip_transitive_dependency_licensing true diff --git a/omnibus/config/software/chef-gem-ruby-prof.rb b/omnibus/config/software/chef-gem-ruby-prof.rb index 47ecfea02a..af90212d23 100644 --- a/omnibus/config/software/chef-gem-ruby-prof.rb +++ b/omnibus/config/software/chef-gem-ruby-prof.rb @@ -5,5 +5,6 @@ require_relative "../../files/chef-gem/build-chef-gem/gem-install-software-def" BuildChefGem::GemInstallSoftwareDef.define(self, __FILE__) -license "BSD-2-CLAUSE" +license "BSD-2-Clause" license_file "https://github.com/ruby-prof/ruby-prof/blob/master/LICENSE" +skip_transitive_dependency_licensing true diff --git a/omnibus/config/software/chef-gem-ruby-shadow.rb b/omnibus/config/software/chef-gem-ruby-shadow.rb index 8091fd9460..02fc906d9d 100644 --- a/omnibus/config/software/chef-gem-ruby-shadow.rb +++ b/omnibus/config/software/chef-gem-ruby-shadow.rb @@ -8,3 +8,4 @@ BuildChefGem::GemInstallSoftwareDef.define(self, __FILE__) license "Public-Domain" license_file "https://github.com/apalmblad/ruby-shadow/blob/master/LICENSE" license_file "http://creativecommons.org/licenses/publicdomain/" +skip_transitive_dependency_licensing true diff --git a/omnibus/config/software/chef-remove-docs.rb b/omnibus/config/software/chef-remove-docs.rb index 2e71e63792..31e2797afd 100644 --- a/omnibus/config/software/chef-remove-docs.rb +++ b/omnibus/config/software/chef-remove-docs.rb @@ -17,6 +17,7 @@ name "chef-remove-docs" license :project_license +skip_transitive_dependency_licensing true build do # This is where we get the definitions below diff --git a/omnibus/omnibus.rb b/omnibus/omnibus.rb index 4eeee4abcb..c6f883adbc 100644 --- a/omnibus/omnibus.rb +++ b/omnibus/omnibus.rb @@ -26,8 +26,10 @@ # Windows architecture defaults - set to x86 unless otherwise specified. # ------------------------------ -windows_arch %w{x86 x64}.include?((ENV["OMNIBUS_WINDOWS_ARCH"] || "").downcase) ? - ENV["OMNIBUS_WINDOWS_ARCH"].downcase.to_sym : :x86 +env_omnibus_windows_arch = (ENV["OMNIBUS_WINDOWS_ARCH"] || "").downcase +env_omnibus_windows_arch = :x86 unless %w{x86 x64}.include?(env_omnibus_windows_arch) + +windows_arch env_omnibus_windows_arch # Disable git caching # ------------------------------ @@ -48,3 +50,5 @@ fetcher_read_timeout 120 # ------------------------------ # software_gems ['omnibus-software', 'my-company-software'] # local_software_dirs ['/path/to/local/software'] + +fatal_transitive_dependency_licensing_warnings true diff --git a/omnibus_overrides.rb b/omnibus_overrides.rb index 7771e805e3..e75ed3de92 100644 --- a/omnibus_overrides.rb +++ b/omnibus_overrides.rb @@ -1,5 +1,5 @@ # DO NOT EDIT. Generated by "rake dependencies". Edit version_policy.rb instead. -override :rubygems, version: "2.6.4" +override :rubygems, version: "2.6.6" override :bundler, version: "1.12.5" override "libffi", version: "3.2.1" override "libiconv", version: "1.14" @@ -11,7 +11,7 @@ override "libyaml", version: "0.1.6" override "makedepend", version: "1.0.5" override "ncurses", version: "5.9" override "pkg-config-lite", version: "0.28-1" -override "ruby", version: "2.1.8" +override "ruby", version: "2.3.1" override "ruby-windows-devkit-bash", version: "3.1.23-4-msys-1.0.18" override "util-macros", version: "1.19.0" override "xproto", version: "7.0.28" diff --git a/pkg.rb b/pkg.rb deleted file mode 100644 index bb26f257d0..0000000000 --- a/pkg.rb +++ /dev/null @@ -1 +0,0 @@ -package "chef-12.9.38-1.powerpc" diff --git a/spec/functional/assets/testchefsubsys b/spec/functional/assets/testchefsubsys index e9ff30d4aa..e5c2f8cfc4 100755 --- a/spec/functional/assets/testchefsubsys +++ b/spec/functional/assets/testchefsubsys @@ -5,7 +5,6 @@ sleep 120 & pid="$!" -trap 'echo I am going down, so killing off my processes..; kill $pid; exit' SIGHUP SIGINT - SIGQUIT SIGTERM +trap 'echo I am going down, so killing off my processes..; kill $pid; exit' SIGHUP SIGINT SIGQUIT SIGTERM -wait
\ No newline at end of file +wait diff --git a/spec/functional/event_loggers/windows_eventlog_spec.rb b/spec/functional/event_loggers/windows_eventlog_spec.rb index 78aed7409f..019595ea8d 100644 --- a/spec/functional/event_loggers/windows_eventlog_spec.rb +++ b/spec/functional/event_loggers/windows_eventlog_spec.rb @@ -48,25 +48,28 @@ describe Chef::EventLoggers::WindowsEventLogger, :windows_only, :not_supported_o it "writes run_start event with event_id 10000 and contains version" do logger.run_start(version) - expect(event_log.read(flags, offset).any? { |e| e.source == "Chef" && e.event_id == 10000 && - e.string_inserts[0].include?(version)}).to be_truthy + expect(event_log.read(flags, offset).any? do |e| + e.source == "Chef" && e.event_id == 10000 && + e.string_inserts[0].include?(version) end).to be_truthy end it "writes run_started event with event_id 10001 and contains the run_id" do logger.run_started(run_status) - expect(event_log.read(flags, offset).any? { |e| e.source == "Chef" && e.event_id == 10001 && - e.string_inserts[0].include?(run_id)}).to be_truthy + expect(event_log.read(flags, offset).any? do |e| + e.source == "Chef" && e.event_id == 10001 && + e.string_inserts[0].include?(run_id) end).to be_truthy end it "writes run_completed event with event_id 10002 and contains the run_id and elapsed time" do logger.run_started(run_status) logger.run_completed(node) - expect(event_log.read(flags, offset).any? { |e| e.source == "Chef" && e.event_id == 10002 && - e.string_inserts[0].include?(run_id) && - e.string_inserts[1].include?(elapsed_time.to_s) - }).to be_truthy + expect(event_log.read(flags, offset).any? do |e| + e.source == "Chef" && e.event_id == 10002 && + e.string_inserts[0].include?(run_id) && + e.string_inserts[1].include?(elapsed_time.to_s) + end).to be_truthy end it "writes run_failed event with event_id 10003 and contains the run_id, elapsed time, and exception info" do diff --git a/spec/functional/file_content_management/deploy_strategies_spec.rb b/spec/functional/file_content_management/deploy_strategies_spec.rb index 7c54af347c..9e2131388f 100644 --- a/spec/functional/file_content_management/deploy_strategies_spec.rb +++ b/spec/functional/file_content_management/deploy_strategies_spec.rb @@ -209,7 +209,7 @@ describe Chef::FileContentManagement::Deploy::MvUnix, :unix_only do end # On Unix we won't have loaded the file, avoid undefined constant errors: -class Chef::FileContentManagement::Deploy::MvWindows ; end +class Chef::FileContentManagement::Deploy::MvWindows; end describe Chef::FileContentManagement::Deploy::MvWindows, :windows_only do diff --git a/spec/functional/http/simple_spec.rb b/spec/functional/http/simple_spec.rb index aeb7be7d86..421045693a 100644 --- a/spec/functional/http/simple_spec.rb +++ b/spec/functional/http/simple_spec.rb @@ -26,11 +26,11 @@ describe Chef::HTTP::Simple do let(:http_client) { described_class.new(source) } let(:http_client_disable_gzip) { described_class.new(source, { :disable_gzip => true } ) } - before(:all) do + before(:each) do start_tiny_server end - after(:all) do + after(:each) do stop_tiny_server end diff --git a/spec/functional/knife/cookbook_delete_spec.rb b/spec/functional/knife/cookbook_delete_spec.rb index a43e3a36c4..99f3309752 100644 --- a/spec/functional/knife/cookbook_delete_spec.rb +++ b/spec/functional/knife/cookbook_delete_spec.rb @@ -20,11 +20,15 @@ require "spec_helper" require "tiny_server" describe Chef::Knife::CookbookDelete do - before(:all) do + before(:each) do @server = TinyServer::Manager.new @server.start end + after(:each) do + @server.stop + end + before(:each) do @knife = Chef::Knife::CookbookDelete.new @api = TinyServer::API.instance @@ -35,10 +39,6 @@ describe Chef::Knife::CookbookDelete do Chef::Config[:chef_server_url] = "http://localhost:9000" end - after(:all) do - @server.stop - end - context "when the cookbook doesn't exist" do let(:log_output) { StringIO.new } diff --git a/spec/functional/knife/exec_spec.rb b/spec/functional/knife/exec_spec.rb index 838d15671c..ac8f617a90 100644 --- a/spec/functional/knife/exec_spec.rb +++ b/spec/functional/knife/exec_spec.rb @@ -20,11 +20,15 @@ require "spec_helper" require "tiny_server" describe Chef::Knife::Exec do - before(:all) do - @server = TinyServer::Manager.new#(:debug => true) + before(:each) do + @server = TinyServer::Manager.new #(:debug => true) @server.start end + after(:each) do + @server.stop + end + before(:each) do @knife = Chef::Knife::Exec.new @api = TinyServer::API.instance @@ -37,10 +41,6 @@ describe Chef::Knife::Exec do $output = StringIO.new end - after(:all) do - @server.stop - end - it "executes a script in the context of the chef-shell main context" do @node = Chef::Node.new @node.name("ohai-world") diff --git a/spec/functional/knife/ssh_spec.rb b/spec/functional/knife/ssh_spec.rb index a23220ed52..065b646ac6 100644 --- a/spec/functional/knife/ssh_spec.rb +++ b/spec/functional/knife/ssh_spec.rb @@ -21,13 +21,13 @@ require "tiny_server" describe Chef::Knife::Ssh do - before(:all) do + before(:each) do Chef::Knife::Ssh.load_deps @server = TinyServer::Manager.new @server.start end - after(:all) do + after(:each) do @server.stop end @@ -276,9 +276,9 @@ describe Chef::Knife::Ssh do Chef::Config[:client_key] = nil Chef::Config[:chef_server_url] = "http://localhost:9000" - @api.get("/search/node?q=*:*&sort=X_CHEF_id_CHEF_X%20asc&start=0", 200) { + @api.get("/search/node?q=*:*&sort=X_CHEF_id_CHEF_X%20asc&start=0", 200) do %({"total":1, "start":0, "rows":[{"name":"i-xxxxxxxx", "json_class":"Chef::Node", "automatic":{"fqdn":"the.fqdn", "ec2":{"public_hostname":"the_public_hostname"}},"recipes":[]}]}) - } + end end end diff --git a/spec/functional/mixin/powershell_out_spec.rb b/spec/functional/mixin/powershell_out_spec.rb index 293e9552ab..66214cb0c7 100644 --- a/spec/functional/mixin/powershell_out_spec.rb +++ b/spec/functional/mixin/powershell_out_spec.rb @@ -23,7 +23,7 @@ describe Chef::Mixin::PowershellOut, windows_only: true do describe "#powershell_out" do it "runs a powershell command and collects stdout" do - expect(powershell_out("get-process").run_command.stdout).to match /Handles\s+NPM\(K\)\s+PM\(K\)\s+WS\(K\)\s+VM\(M\)\s+CPU\(s\)\s+Id\s+ProcessName/ + expect(powershell_out("get-process").run_command.stdout).to match /Handles\s+NPM\(K\)\s+PM\(K\)\s+WS\(K\)\s+VM\(M\)\s+CPU\(s\)\s+Id\s+/ end it "does not raise exceptions when the command is invalid" do @@ -33,7 +33,7 @@ describe Chef::Mixin::PowershellOut, windows_only: true do describe "#powershell_out!" do it "runs a powershell command and collects stdout" do - expect(powershell_out!("get-process").run_command.stdout).to match /Handles\s+NPM\(K\)\s+PM\(K\)\s+WS\(K\)\s+VM\(M\)\s+CPU\(s\)\s+Id\s+ProcessName/ + expect(powershell_out!("get-process").run_command.stdout).to match /Handles\s+NPM\(K\)\s+PM\(K\)\s+WS\(K\)\s+VM\(M\)\s+CPU\(s\)\s+Id\s+/ end it "raises exceptions when the command is invalid" do diff --git a/spec/functional/notifications_spec.rb b/spec/functional/notifications_spec.rb index 1b1ef83294..8d8b2d970c 100644 --- a/spec/functional/notifications_spec.rb +++ b/spec/functional/notifications_spec.rb @@ -13,11 +13,11 @@ describe "Notifications" do # We always pretend we are on OSx because that has a specific provider (HomebrewProvider) so it # tests the translation from Provider => HomebrewProvider - let(:node) { + let(:node) do n = Chef::Node.new n.override[:os] = "darwin" n - } + end let(:cookbook_collection) { double("Chef::CookbookCollection").as_null_object } let(:events) { double("Chef::EventDispatch::Dispatcher").as_null_object } let(:run_context) { Chef::RunContext.new(node, cookbook_collection, events) } diff --git a/spec/functional/provider/whyrun_safe_ruby_block_spec.rb b/spec/functional/provider/whyrun_safe_ruby_block_spec.rb index 892e1080db..1bb36f2cf6 100644 --- a/spec/functional/provider/whyrun_safe_ruby_block_spec.rb +++ b/spec/functional/provider/whyrun_safe_ruby_block_spec.rb @@ -21,10 +21,10 @@ require "spec_helper" describe Chef::Resource::WhyrunSafeRubyBlock do let(:node) { Chef::Node.new } - let(:run_context) { + let(:run_context) do events = Chef::EventDispatch::Dispatcher.new Chef::RunContext.new(node, {}, events) - } + end before do $evil_global_evil_laugh = :wahwah diff --git a/spec/functional/rebooter_spec.rb b/spec/functional/rebooter_spec.rb index 4b77c40e91..0006f3bcdb 100644 --- a/spec/functional/rebooter_spec.rb +++ b/spec/functional/rebooter_spec.rb @@ -50,15 +50,15 @@ describe Chef::Platform::Rebooter do let(:rebooter) { Chef::Platform::Rebooter } - describe '#reboot_if_needed!' do + describe "#reboot_if_needed!" do - it 'should not call #shell_out! when reboot has not been requested' do + it "should not call #shell_out! when reboot has not been requested" do expect(rebooter).to receive(:shell_out!).exactly(0).times expect(rebooter).to receive(:reboot_if_needed!).once.and_call_original rebooter.reboot_if_needed!(run_context.node) end - describe 'calling #shell_out! to reboot' do + describe "calling #shell_out! to reboot" do before(:each) do run_context.request_reboot(reboot_info) @@ -77,7 +77,7 @@ describe Chef::Platform::Rebooter do end end - describe 'when using #reboot_if_needed!' do + describe "when using #reboot_if_needed!" do include_context "test a reboot method" it "should produce the correct string on Windows" do @@ -89,7 +89,7 @@ describe Chef::Platform::Rebooter do end end - describe 'when using #reboot!' do + describe "when using #reboot!" do include_context "test a reboot method" it "should produce the correct string on Windows" do diff --git a/spec/functional/resource/bash_spec.rb b/spec/functional/resource/bash_spec.rb index 87211ec264..a2e174d557 100644 --- a/spec/functional/resource/bash_spec.rb +++ b/spec/functional/resource/bash_spec.rb @@ -21,11 +21,11 @@ require "functional/resource/base" describe Chef::Resource::Bash, :unix_only do let(:code) { "echo hello" } - let(:resource) { + let(:resource) do resource = Chef::Resource::Bash.new("foo_resource", run_context) resource.code(code) resource - } + end describe "when setting the command attribute" do let (:command) { "wizard racket" } diff --git a/spec/functional/resource/cron_spec.rb b/spec/functional/resource/cron_spec.rb index 3380eccb0d..f5948191c5 100644 --- a/spec/functional/resource/cron_spec.rb +++ b/spec/functional/resource/cron_spec.rb @@ -120,7 +120,7 @@ describe Chef::Resource::Cron, :requires_root, :unix_only do return if %w{aix solaris}.include?(ohai[:platform]) # Test if the attribute exists on newly created cron cron_should_exists(cron_name, "") - expect(shell_out("crontab -l -u #{new_resource.user} | grep \"#{attribute.upcase}=#{value}\"").exitstatus).to eq(0) + expect(shell_out("crontab -l -u #{new_resource.user} | grep '#{attribute.upcase}=\"#{value}\"'").exitstatus).to eq(0) end after do @@ -146,6 +146,13 @@ describe Chef::Resource::Cron, :requires_root, :unix_only do new_resource.home "/home/opscode" create_and_validate_with_attribute(new_resource, "home", "/home/opscode") end + + %i{ home mailto path shell }.each do |attr| + it "supports an empty string for #{attr} attribute" do + new_resource.send(attr, "") + create_and_validate_with_attribute(new_resource, attr.to_s, "") + end + end end describe "negative tests for create action" do diff --git a/spec/functional/resource/deploy_revision_spec.rb b/spec/functional/resource/deploy_revision_spec.rb index 72eaea3c12..572609d8ff 100644 --- a/spec/functional/resource/deploy_revision_spec.rb +++ b/spec/functional/resource/deploy_revision_spec.rb @@ -840,7 +840,7 @@ describe Chef::Resource::DeployRevision, :unix_only => true, :requires_git => tr end def run_action(action) - raise RuntimeError, "network error" + raise "network error" end end diff --git a/spec/functional/resource/dpkg_package_spec.rb b/spec/functional/resource/dpkg_package_spec.rb index d65256231b..1988fd0c7d 100644 --- a/spec/functional/resource/dpkg_package_spec.rb +++ b/spec/functional/resource/dpkg_package_spec.rb @@ -27,11 +27,11 @@ describe Chef::Resource::DpkgPackage, :requires_root, :debian_family_only, arch: let(:test1_1) { File.join(apt_data, "chef-integration-test_1.1-1_amd64.deb") } let(:test2_0) { File.join(apt_data, "chef-integration-test2_1.0-1_amd64.deb") } - let(:run_context) { + let(:run_context) do node = TEST_NODE.dup events = Chef::EventDispatch::Dispatcher.new Chef::RunContext.new(node, {}, events) - } + end let(:dpkg_package) { Chef::Resource::DpkgPackage.new(test1_0, run_context) } diff --git a/spec/functional/resource/dsc_resource_spec.rb b/spec/functional/resource/dsc_resource_spec.rb index 8e4940d475..bb3cf2157d 100644 --- a/spec/functional/resource/dsc_resource_spec.rb +++ b/spec/functional/resource/dsc_resource_spec.rb @@ -21,17 +21,17 @@ require "spec_helper" describe Chef::Resource::DscResource, :windows_powershell_dsc_only do let(:event_dispatch) { Chef::EventDispatch::Dispatcher.new } - let(:node) { + let(:node) do Chef::Node.new.tap do |n| n.consume_external_attrs(OHAI_SYSTEM.data, {}) end - } + end let(:run_context) { Chef::RunContext.new(node, {}, event_dispatch) } - let(:new_resource) { + let(:new_resource) do Chef::Resource::DscResource.new("dsc_resource_test", run_context) - } + end context "when Powershell does not support Invoke-DscResource" context "when Powershell supports Invoke-DscResource" do @@ -77,7 +77,7 @@ describe Chef::Resource::DscResource, :windows_powershell_dsc_only do new_resource.run_action(:run) expect(new_resource).to be_updated reresource = - Chef::Resource::DscResource.new("dsc_resource_retest", run_context) + Chef::Resource::DscResource.new("dsc_resource_retest", run_context) reresource.resource :File reresource.property :Contents, test_text reresource.property :DestinationPath, tmp_file_name diff --git a/spec/functional/resource/dsc_script_spec.rb b/spec/functional/resource/dsc_script_spec.rb index 5ee97f04a3..e2b58f6432 100644 --- a/spec/functional/resource/dsc_script_spec.rb +++ b/spec/functional/resource/dsc_script_spec.rb @@ -74,7 +74,7 @@ describe Chef::Resource::DscScript, :windows_powershell_dsc_only do let(:dsc_env_variable) { "chefenvtest" } let(:dsc_env_value1) { "value1" } let(:env_value2) { "value2" } - let(:dsc_test_run_context) { + let(:dsc_test_run_context) do node = Chef::Node.new node.automatic["platform"] = "windows" node.automatic["platform_version"] = "6.1" @@ -82,11 +82,11 @@ describe Chef::Resource::DscScript, :windows_powershell_dsc_only do node.automatic[:languages][:powershell][:version] = "4.0" empty_events = Chef::EventDispatch::Dispatcher.new Chef::RunContext.new(node, {}, empty_events) - } + end let(:dsc_test_resource_name) { "DSCTest" } - let(:dsc_test_resource_base) { + let(:dsc_test_resource_base) do Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context) - } + end let(:test_registry_key) { 'HKEY_LOCAL_MACHINE\Software\Chef\Spec\Functional\Resource\dsc_script_spec' } let(:test_registry_value) { "Registration" } let(:test_registry_data1) { "LL927" } @@ -94,7 +94,8 @@ describe Chef::Resource::DscScript, :windows_powershell_dsc_only do let(:reg_key_name_param_name) { "testregkeyname" } let(:reg_key_value_param_name) { "testregvaluename" } let(:registry_embedded_parameters) { "$#{reg_key_name_param_name} = '#{test_registry_key}';$#{reg_key_value_param_name} = '#{test_registry_value}'" } - let(:dsc_reg_code) { <<-EOH + let(:dsc_reg_code) do + <<-EOH #{registry_embedded_parameters} Registry "ChefRegKey" { @@ -104,14 +105,15 @@ describe Chef::Resource::DscScript, :windows_powershell_dsc_only do Ensure = 'Present' } EOH - } + end let(:dsc_code) { dsc_reg_code } - let(:dsc_reg_script) { <<-EOH + let(:dsc_reg_script) do + <<-EOH param($testregkeyname, $testregvaluename) #{dsc_reg_code} EOH - } + end let(:dsc_user_prefix) { "dsc" } let(:dsc_user_suffix) { "chefx" } @@ -128,7 +130,8 @@ EOH let(:dsc_user_param_code) { "\"$(#{dsc_user_prefix_param_code})_usr_$(#{dsc_user_suffix_param_code})\"" } let(:config_flags) { nil } - let(:config_params) { <<-EOH + let(:config_params) do + <<-EOH [CmdletBinding()] param @@ -137,14 +140,15 @@ EOH $#{dsc_user_suffix_param_name} ) EOH - } + end let(:config_param_section) { "" } let(:dsc_user_code) { "'#{dsc_user}'" } let(:dsc_user_prefix_code) { dsc_user_prefix } let(:dsc_user_suffix_code) { dsc_user_suffix } let(:dsc_script_environment_attribute) { nil } - let(:dsc_user_resources_code) { <<-EOH + let(:dsc_user_resources_code) do + <<-EOH #{config_param_section} node localhost { @@ -164,9 +168,9 @@ User dsctestusercreate } } EOH - } + end - let(:dsc_user_config_data) { + let(:dsc_user_config_data) do <<-EOH @{ AllNodes = @( @@ -178,13 +182,14 @@ EOH } EOH - } + end let(:dsc_environment_env_var_name) { "dsc_test_cwd" } let(:dsc_environment_no_fail_not_etc_directory) { "#{ENV['systemroot']}\\system32" } let(:dsc_environment_fail_etc_directory) { "#{ENV['systemroot']}\\system32\\drivers\\etc" } let(:exception_message_signature) { "LL927-LL928" } - let(:dsc_environment_config) {<<-EOH + let(:dsc_environment_config) do + <<-EOH if (($pwd.path -eq '#{dsc_environment_fail_etc_directory}') -and (test-path('#{dsc_environment_fail_etc_directory}'))) { throw 'Signature #{exception_message_signature}: Purposefully failing because cwd == #{dsc_environment_fail_etc_directory}' @@ -196,21 +201,21 @@ environment "whatsmydir" Ensure = 'Present' } EOH - } + end - let(:dsc_config_name) { + let(:dsc_config_name) do dsc_test_resource_base.name - } - let(:dsc_resource_from_code) { + end + let(:dsc_resource_from_code) do dsc_test_resource_base.code(dsc_code) dsc_test_resource_base - } + end let(:config_name_value) { dsc_test_resource_base.name } - let(:dsc_resource_from_path) { + let(:dsc_resource_from_path) do dsc_test_resource_base.command(create_config_script_from_code(dsc_code, config_name_value)) dsc_test_resource_base - } + end before(:each) do test_key_resource = Chef::Resource::RegistryKey.new(test_registry_key, dsc_test_run_context) diff --git a/spec/functional/resource/env_spec.rb b/spec/functional/resource/env_spec.rb index 83328a6738..4b0ff70c0b 100755 --- a/spec/functional/resource/env_spec.rb +++ b/spec/functional/resource/env_spec.rb @@ -27,17 +27,17 @@ describe Chef::Resource::Env, :windows_only do let(:env_value2) { "value2" } let(:env_value_expandable) { "%SystemRoot%" } - let(:test_run_context) { + let(:test_run_context) do node = Chef::Node.new node.default["os"] = "windows" node.default["platform"] = "windows" node.default["platform_version"] = "6.1" empty_events = Chef::EventDispatch::Dispatcher.new Chef::RunContext.new(node, {}, empty_events) - } - let(:test_resource) { + end + let(:test_resource) do Chef::Resource::Env.new("unknown", test_run_context) - } + end before(:each) do resource_lower = Chef::Resource::Env.new(chef_env_test_lower_case, test_run_context) diff --git a/spec/functional/resource/execute_spec.rb b/spec/functional/resource/execute_spec.rb index c5978da519..3c31537ebe 100644 --- a/spec/functional/resource/execute_spec.rb +++ b/spec/functional/resource/execute_spec.rb @@ -21,11 +21,11 @@ require "functional/resource/base" require "timeout" describe Chef::Resource::Execute do - let(:resource) { + let(:resource) do resource = Chef::Resource::Execute.new("foo_resource", run_context) resource.command("echo hello") resource - } + end describe "when guard is ruby block" do it "guard can still run" do @@ -41,10 +41,10 @@ describe Chef::Resource::Execute do end let(:guard) { "ruby -e 'exit 0'" } - let!(:guard_resource) { + let!(:guard_resource) do interpreter = Chef::GuardInterpreter::ResourceGuardInterpreter.new(resource, guard, nil) interpreter.send(:get_interpreter_resource, resource) - } + end it "executes the guard and not the regular resource" do expect_any_instance_of(Chef::GuardInterpreter::ResourceGuardInterpreter).to receive(:get_interpreter_resource).and_return(guard_resource) diff --git a/spec/functional/resource/group_spec.rb b/spec/functional/resource/group_spec.rb index a5de63b7c6..aa5a29f92c 100644 --- a/spec/functional/resource/group_spec.rb +++ b/spec/functional/resource/group_spec.rb @@ -85,8 +85,14 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte end end + def node + node = Chef::Node.new + node.consume_external_attrs(ohai.data, {}) + node + end + def user(username) - usr = Chef::Resource::User.new("#{username}", run_context) + usr = Chef::Resource.resource_for_node(:user, node).new(username, run_context) if ohai[:platform_family] == "windows" usr.password("ComplexPass11!") end @@ -99,7 +105,11 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte end def remove_user(username) - user(username).run_action(:remove) if ! windows_domain_user?(username) + if ! windows_domain_user?(username) + u = user(username) + u.manage_home false # jekins hosts throw mail spool file not owned by user if we use manage_home true + u.run_action(:remove) + end # TODO: User shouldn't exist end @@ -282,12 +292,12 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte let(:group_name) { "group#{SecureRandom.random_number(9999)}" } let(:included_members) { nil } let(:excluded_members) { nil } - let(:group_resource) { + let(:group_resource) do group = Chef::Resource::Group.new(group_name, run_context) group.members(included_members) group.excluded_members(excluded_members) group - } + end it "append should be false by default" do expect(group_resource.append).to eq(false) @@ -305,10 +315,11 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte end describe "when group name is length 256", :windows_only do - let!(:group_name) { "theoldmanwalkingdownthestreetalwayshadagood\ + let!(:group_name) do + "theoldmanwalkingdownthestreetalwayshadagood\ smileonhisfacetheoldmanwalkingdownthestreetalwayshadagoodsmileonhisface\ theoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalking\ -downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestree" } +downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestree" end it "should create a group" do group_resource.run_action(:create) @@ -317,10 +328,11 @@ downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestree" } end describe "when group name length is more than 256", :windows_only do - let!(:group_name) { "theoldmanwalkingdownthestreetalwayshadagood\ + let!(:group_name) do + "theoldmanwalkingdownthestreetalwayshadagood\ smileonhisfacetheoldmanwalkingdownthestreetalwayshadagoodsmileonhisface\ theoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalking\ -downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreeQQQQQQ" } +downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreeQQQQQQ" end it "should not create a group" do expect { group_resource.run_action(:create) }.to raise_error(ArgumentError) diff --git a/spec/functional/resource/link_spec.rb b/spec/functional/resource/link_spec.rb index 6dd6ad8422..5e58d0918a 100644 --- a/spec/functional/resource/link_spec.rb +++ b/spec/functional/resource/link_spec.rb @@ -580,12 +580,7 @@ describe Chef::Resource::Link do it "links to the target file" do skip("OS X/FreeBSD/AIX fails to create hardlinks to broken symlinks") if os_x? || freebsd? || aix? resource.run_action(:create) - # Windows and Unix have different definitions of exists? here, and that's OK. - if windows? - expect(File.exists?(target_file)).to be_truthy - else - expect(File.exists?(target_file)).to be_falsey - end + expect(File.exists?(target_file) || File.symlink?(target_file)).to be_truthy expect(symlink?(target_file)).to be_truthy expect(readlink(target_file)).to eq(canonicalize(@other_target)) end diff --git a/spec/functional/resource/ohai_spec.rb b/spec/functional/resource/ohai_spec.rb index 9ce989d8df..06bccfc398 100644 --- a/spec/functional/resource/ohai_spec.rb +++ b/spec/functional/resource/ohai_spec.rb @@ -19,18 +19,18 @@ require "spec_helper" describe Chef::Resource::Ohai do - let(:ohai) { + let(:ohai) do OHAI_SYSTEM - } + end let(:node) { Chef::Node.new } - let(:run_context) { + let(:run_context) do node.default[:platform] = ohai[:platform] node.default[:platform_version] = ohai[:platform_version] events = Chef::EventDispatch::Dispatcher.new Chef::RunContext.new(node, {}, events) - } + end shared_examples_for "reloaded :uptime" do it "should reload :uptime" do @@ -51,11 +51,11 @@ describe Chef::Resource::Ohai do end describe "when reloading only uptime" do - let(:ohai_resource) { + let(:ohai_resource) do r = Chef::Resource::Ohai.new("reload all", run_context) r.plugin("uptime") r - } + end it_behaves_like "reloaded :uptime" end diff --git a/spec/functional/resource/reboot_spec.rb b/spec/functional/resource/reboot_spec.rb index 3cf7f58e55..c264b122a7 100644 --- a/spec/functional/resource/reboot_spec.rb +++ b/spec/functional/resource/reboot_spec.rb @@ -80,9 +80,9 @@ describe Chef::Resource::Reboot do it "should have modified the run context correctly" do # this doesn't actually test the flow of Chef::Client#do_run, unfortunately. - expect { + expect do resource.run_action(:reboot_now) - }.to throw_symbol(:end_client_run_early) + end.to throw_symbol(:end_client_run_early) test_reboot_action(resource) end diff --git a/spec/functional/resource/remote_file_spec.rb b/spec/functional/resource/remote_file_spec.rb index b394bd0240..1f92a567f3 100644 --- a/spec/functional/resource/remote_file_spec.rb +++ b/spec/functional/resource/remote_file_spec.rb @@ -55,11 +55,11 @@ describe Chef::Resource::RemoteFile do let(:default_mode) { (0666 & ~File.umask).to_s(8) } context "when fetching files over HTTP" do - before(:all) do + before(:each) do start_tiny_server end - after(:all) do + after(:each) do stop_tiny_server end @@ -97,7 +97,7 @@ describe Chef::Resource::RemoteFile do context "when fetching files over HTTPS" do - before(:all) do + before(:each) do cert_text = File.read(File.expand_path("ssl/chef-rspec.cert", CHEF_SPEC_DATA)) cert = OpenSSL::X509::Certificate.new(cert_text) key_text = File.read(File.expand_path("ssl/chef-rspec.key", CHEF_SPEC_DATA)) @@ -111,7 +111,7 @@ describe Chef::Resource::RemoteFile do start_tiny_server(server_opts) end - after(:all) do + after(:each) do stop_tiny_server end @@ -124,11 +124,11 @@ describe Chef::Resource::RemoteFile do end context "when dealing with content length checking" do - before(:all) do + before(:each) do start_tiny_server end - after(:all) do + after(:each) do stop_tiny_server end @@ -232,7 +232,16 @@ describe Chef::Resource::RemoteFile do end it "should not create the file" do - expect { resource.run_action(:create) }.to raise_error + # This can legitimately raise either Errno::EADDRNOTAVAIL or Errno::ECONNREFUSED + # in different Ruby versions. + old_value = RSpec::Expectations.configuration.on_potential_false_positives + RSpec::Expectations.configuration.on_potential_false_positives = :nothing + begin + expect { resource.run_action(:create) }.to raise_error + ensure + RSpec::Expectations.configuration.on_potential_false_positives = old_value + end + expect(File).not_to exist(path) end end diff --git a/spec/functional/resource/user/dscl_spec.rb b/spec/functional/resource/user/dscl_spec.rb index 5d904a980b..bedb37838c 100644 --- a/spec/functional/resource/user/dscl_spec.rb +++ b/spec/functional/resource/user/dscl_spec.rb @@ -76,7 +76,7 @@ describe "Chef::Resource::User with Chef::Provider::User::Dscl provider", metada let(:iterations) { nil } let(:user_resource) do - r = Chef::Resource::User.new("TEST USER RESOURCE", run_context) + r = Chef::Resource::User::DsclUser.new("TEST USER RESOURCE", run_context) r.username(username) r.uid(uid) r.gid(gid) @@ -123,7 +123,7 @@ describe "Chef::Resource::User with Chef::Provider::User::Dscl provider", metada end describe "when password is being set via shadow hash" do - let(:password) { + let(:password) do if node[:platform_version].start_with?("10.7.") # On Mac 10.7 we only need to set the password "c9b3bd1a0cde797eef0eff16c580dab996ba3a21961cccc\ @@ -139,7 +139,7 @@ b1d4880833aa7a190afc13e2bf0936b8\ c5adbbac718b7eb99463a7b679571e0f\ 1c9fef2ef08d0b9e9c2bcf644eed2ffc" end - } + end let(:iterations) { 25000 } let(:salt) { "9e2e7d5ee473b496fd24cf0bbfcaedfcb291ee21740e570d1e917e874f8788ca" } diff --git a/spec/functional/resource/user/useradd_spec.rb b/spec/functional/resource/user/useradd_spec.rb index 43c26ac006..f13cd95d6f 100644 --- a/spec/functional/resource/user/useradd_spec.rb +++ b/spec/functional/resource/user/useradd_spec.rb @@ -21,19 +21,14 @@ require "spec_helper" require "functional/resource/base" require "chef/mixin/shell_out" -def user_provider_for_platform - case ohai[:platform] - when "aix" - Chef::Provider::User::Aix - else - Chef::Provider::User::Useradd - end +def resource_for_platform(username, run_context) + Chef::Resource.resource_for_node(:user, node).new(username, run_context) end -metadata = { :unix_only => true, - :requires_root => true, - :not_supported_on_mac_osx => true, - :provider => { :user => user_provider_for_platform }, +metadata = { + :unix_only => true, + :requires_root => true, + :not_supported_on_mac_osx => true, } describe Chef::Provider::User::Useradd, metadata do @@ -86,7 +81,7 @@ describe Chef::Provider::User::Useradd, metadata do end ["cf-test"].each do |u| - r = Chef::Resource::User.new("DELETE USER", run_context) + r = resource_for_platform("DELETE USER", run_context) r.username("cf-test") r.run_action(:remove) end @@ -134,10 +129,7 @@ describe Chef::Provider::User::Useradd, metadata do Chef::RunContext.new(node, {}, events) end - let(:username) do - "cf-test" - end - + let(:username) { "cf-test" } let(:uid) { nil } let(:home) { nil } let(:manage_home) { false } @@ -146,7 +138,7 @@ describe Chef::Provider::User::Useradd, metadata do let(:comment) { nil } let(:user_resource) do - r = Chef::Resource::User.new("TEST USER RESOURCE", run_context) + r = resource_for_platform("TEST USER RESOURCE", run_context) r.username(username) r.uid(uid) r.home(home) @@ -242,15 +234,8 @@ describe Chef::Provider::User::Useradd, metadata do expect(pw_entry.home).to eq(home) end - if %w{rhel fedora wrlinux}.include?(OHAI_SYSTEM["platform_family"]) - # Inconsistent behavior. See: CHEF-2205 - it "creates the home dir when not explicitly asked to on RHEL (XXX)" do - expect(File).to exist(home) - end - else - it "does not create the home dir without `manage_home'" do - expect(File).not_to exist(home) - end + it "does not create the home dir without `manage_home'" do + expect(File).not_to exist(home) end context "and manage_home is enabled" do @@ -310,8 +295,8 @@ describe Chef::Provider::User::Useradd, metadata do let(:existing_comment) { nil } let(:existing_user) do - r = Chef::Resource::User.new("TEST USER RESOURCE", run_context) - # username is identity attr, must match. + r = resource_for_platform("TEST USER RESOURCE", run_context) + # username is identity attr, must match. r.username(username) r.uid(existing_uid) r.home(existing_home) diff --git a/spec/functional/resource/windows_service_spec.rb b/spec/functional/resource/windows_service_spec.rb index b4af1e9e6a..531f9e9250 100644 --- a/spec/functional/resource/windows_service_spec.rb +++ b/spec/functional/resource/windows_service_spec.rb @@ -27,19 +27,19 @@ describe Chef::Resource::WindowsService, :windows_only, :system_windows_service_ let(:qualified_username) { "#{ENV['COMPUTERNAME']}\\#{username}" } let(:password) { "1a2b3c4X!&narf" } - let(:user_resource) { - r = Chef::Resource::User.new(username, run_context) + let(:user_resource) do + r = Chef::Resource::User::WindowsUser.new(username, run_context) r.username(username) r.password(password) r.comment("temp spec user") r - } + end - let(:global_service_file_path) { + let(:global_service_file_path) do "#{ENV['WINDIR']}\\temp\\#{File.basename(test_service[:service_file_path])}" - } + end - let(:service_params) { + let(:service_params) do id = "#{$$}_#{rand(1000)}" @@ -51,19 +51,19 @@ describe Chef::Resource::WindowsService, :windows_only, :system_windows_service_ service_description: "Test service for running the windows_service functional spec.", service_file_path: global_service_file_path, } ) - } + end - let(:manager) { + let(:manager) do Chef::Application::WindowsServiceManager.new(service_params) - } + end - let(:service_resource) { + let(:service_resource) do r = Chef::Resource::WindowsService.new(service_params[:service_name], run_context) [:run_as_user, :run_as_password].each { |prop| r.send(prop, service_params[prop]) } r - } + end - before { + before do user_resource.run_action(:create) # the service executable has to be outside the current user's home @@ -81,13 +81,13 @@ describe Chef::Resource::WindowsService, :windows_only, :system_windows_service_ file.run_action(:create) manager.run(%w{--action install}) - } + end - after { + after do user_resource.run_action(:remove) manager.run(%w{--action uninstall}) File.delete(global_service_file_path) - } + end describe "logon as a service" do it "successfully runs a service as another user" do diff --git a/spec/functional/rest_spec.rb b/spec/functional/rest_spec.rb index adafc18e5a..14e76087c4 100644 --- a/spec/functional/rest_spec.rb +++ b/spec/functional/rest_spec.rb @@ -83,11 +83,11 @@ describe Chef::REST do Chef::Config[:treat_deprecation_warnings_as_errors] = false end - before(:all) do + before(:each) do start_tiny_server end - after(:all) do + after(:each) do stop_tiny_server end diff --git a/spec/functional/run_lock_spec.rb b/spec/functional/run_lock_spec.rb index f1e480c917..d270803698 100644 --- a/spec/functional/run_lock_spec.rb +++ b/spec/functional/run_lock_spec.rb @@ -46,11 +46,9 @@ describe Chef::RunLock do end WAIT_ON_LOCK_TIME = 1.0 - def wait_on_lock + def wait_on_lock(from_fork) Timeout.timeout(WAIT_ON_LOCK_TIME) do - until File.exist?(lockfile) - sleep 0.1 - end + from_fork.readline end rescue Timeout::Error raise "Lockfile never created, abandoning test" @@ -258,37 +256,48 @@ describe Chef::RunLock do it "test returns true and acquires the lock" do run_lock = Chef::RunLock.new(lockfile) + from_tests, to_fork = IO.pipe + from_fork, to_tests = IO.pipe p1 = fork do expect(run_lock.test).to eq(true) - run_lock.save_pid - sleep 2 - exit! 1 + to_tests.puts "lock acquired" + # Wait for the test to tell us we can exit before exiting + from_tests.readline + exit! 0 end - wait_on_lock + wait_on_lock(from_fork) p2 = fork do expect(run_lock.test).to eq(false) exit! 0 end - Process.waitpid2(p2) - Process.waitpid2(p1) + pid, exit_status = Process.waitpid2(p2) + expect(exit_status).to eq(0) + to_fork.puts "you can exit now" + pid, exit_status = Process.waitpid2(p1) + expect(exit_status).to eq(0) end it "test returns without waiting when the lock is acquired" do run_lock = Chef::RunLock.new(lockfile) + from_tests, to_fork = IO.pipe + from_fork, to_tests = IO.pipe p1 = fork do run_lock.acquire - run_lock.save_pid - sleep 2 - exit! 1 + to_tests.puts "lock acquired" + # Wait for the test to tell us we can exit before exiting + from_tests.readline + exit! 0 end - wait_on_lock - + wait_on_lock(from_fork) expect(run_lock.test).to eq(false) - Process.waitpid2(p1) + + to_fork.puts "you can exit now" + pid, exit_status = Process.waitpid2(p1) + expect(exit_status).to eq(0) end end @@ -386,9 +395,7 @@ describe Chef::RunLock do # Send it the kill signal over and over until it dies Timeout.timeout(CLIENT_PROCESS_TIMEOUT) do Process.kill(:KILL, pid) - until Process.waitpid2(pid, Process::WNOHANG) - sleep(0.05) - end + sleep(0.05) until Process.waitpid2(pid, Process::WNOHANG) end example.log_event("#{name}.stop finished (stopped pid #{pid})") # Process not found is perfectly fine when we're trying to kill a process :) diff --git a/spec/functional/tiny_server_spec.rb b/spec/functional/tiny_server_spec.rb index 2a025a2ecd..1ec56bd490 100644 --- a/spec/functional/tiny_server_spec.rb +++ b/spec/functional/tiny_server_spec.rb @@ -65,14 +65,15 @@ end describe TinyServer::Manager do it "runs the server" do - @server = TinyServer::Manager.new - @server.start + server = TinyServer::Manager.new + server.start + begin + TinyServer::API.instance.get("/index", 200, "[\"hello\"]") - TinyServer::API.instance.get("/index", 200, "[\"hello\"]") - - rest = Chef::HTTP.new("http://localhost:9000") - expect(rest.get("index")).to eq("[\"hello\"]") - - @server.stop + rest = Chef::HTTP.new("http://localhost:9000") + expect(rest.get("index")).to eq("[\"hello\"]") + ensure + server.stop + end end end diff --git a/spec/functional/win32/crypto_spec.rb b/spec/functional/win32/crypto_spec.rb index 75a8bfbd24..145c9881b9 100644 --- a/spec/functional/win32/crypto_spec.rb +++ b/spec/functional/win32/crypto_spec.rb @@ -22,7 +22,7 @@ if Chef::Platform.windows? end describe "Chef::ReservedNames::Win32::Crypto", :windows_only do - describe '#encrypt' do + describe "#encrypt" do before(:all) do new_node = Chef::Node.new new_node.consume_external_attrs(OHAI_SYSTEM.data, {}) diff --git a/spec/functional/win32/security_spec.rb b/spec/functional/win32/security_spec.rb index c4951f375c..40ae99bfa4 100644 --- a/spec/functional/win32/security_spec.rb +++ b/spec/functional/win32/security_spec.rb @@ -45,27 +45,27 @@ describe "Chef::Win32::Security", :windows_only do end describe "access_check" do - let(:security_descriptor) { + let(:security_descriptor) do Chef::ReservedNames::Win32::Security.get_file_security( "C:\\Program Files") - } + end let(:token_rights) { Chef::ReservedNames::Win32::Security::TOKEN_ALL_ACCESS } - let(:token) { + let(:token) do Chef::ReservedNames::Win32::Security.open_process_token( Chef::ReservedNames::Win32::Process.get_current_process, token_rights).duplicate_token(:SecurityImpersonation) - } + end - let(:mapping) { + let(:mapping) do mapping = Chef::ReservedNames::Win32::Security::GENERIC_MAPPING.new mapping[:GenericRead] = Chef::ReservedNames::Win32::Security::FILE_GENERIC_READ mapping[:GenericWrite] = Chef::ReservedNames::Win32::Security::FILE_GENERIC_WRITE mapping[:GenericExecute] = Chef::ReservedNames::Win32::Security::FILE_GENERIC_EXECUTE mapping[:GenericAll] = Chef::ReservedNames::Win32::Security::FILE_ALL_ACCESS mapping - } + end let(:desired_access) { Chef::ReservedNames::Win32::Security::FILE_GENERIC_READ } @@ -76,11 +76,11 @@ describe "Chef::Win32::Security", :windows_only do end describe "Chef::Win32::Security::Token" do - let(:token) { + let(:token) do Chef::ReservedNames::Win32::Security.open_process_token( Chef::ReservedNames::Win32::Process.get_current_process, token_rights) - } + end context "with all rights" do let(:token_rights) { Chef::ReservedNames::Win32::Security::TOKEN_ALL_ACCESS } diff --git a/spec/integration/client/client_spec.rb b/spec/integration/client/client_spec.rb index f6e50066bf..da3a2b98e4 100644 --- a/spec/integration/client/client_spec.rb +++ b/spec/integration/client/client_spec.rb @@ -19,11 +19,11 @@ describe "chef-client" do # # just a normal file # (expected_content should be uncompressed) - @api.get("/recipes.tgz", 200) { + @api.get("/recipes.tgz", 200) do File.open(recipes_filename, "rb") do |f| f.read end - } + end end def stop_tiny_server @@ -376,6 +376,8 @@ EOM end it "the cheffish DSL tries to load but fails (because chef-provisioning is not there)" do + # we'd need to have a custom bundle to fix this that omitted chef-provisioning, but that would dig our crazy even deeper, so lets not + skip "but if chef-provisioning is in our bundle or in our gemset then this test, very annoyingly, always fails" command = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o 'x::default' --no-fork", :cwd => chef_dir) expect(command.exitstatus).to eql(1) expect(command.stdout).to match(/cannot load such file -- chef\/provisioning/) @@ -474,11 +476,11 @@ end # Fails on appveyor, but works locally on windows and on windows hosts in Ci. context "when using recipe-url", :skip_appveyor do - before(:all) do + before(:each) do start_tiny_server end - after(:all) do + after(:each) do stop_tiny_server end diff --git a/spec/integration/knife/chef_repo_path_spec.rb b/spec/integration/knife/chef_repo_path_spec.rb index cf12b7ddfe..1388aa8716 100644 --- a/spec/integration/knife/chef_repo_path_spec.rb +++ b/spec/integration/knife/chef_repo_path_spec.rb @@ -48,7 +48,7 @@ describe "chef_repo_path tests", :workstation do directory "chef_repo2" do file "clients/client3.json", {} - file "cookbooks/cookbook3/metadata.rb", "" + file "cookbooks/cookbook3/metadata.rb", "name 'cookbook3'" file "data_bags/bag3/item3.json", {} file "environments/env3.json", {} file "nodes/node3.json", {} @@ -79,6 +79,75 @@ describe "chef_repo_path tests", :workstation do EOM end + it "knife list --local -Rfp --chef-repo-path chef_r~1 / grabs chef_repo2 stuff", :windows_only do + Chef::Config.delete(:chef_repo_path) + knife("list --local -Rfp --chef-repo-path #{path_to('chef_r~1')} /").should_succeed <<EOM +/clients/ +/clients/client3.json +/cookbooks/ +/cookbooks/cookbook3/ +/cookbooks/cookbook3/metadata.rb +/data_bags/ +/data_bags/bag3/ +/data_bags/bag3/item3.json +/environments/ +/environments/env3.json +/nodes/ +/nodes/node3.json +/roles/ +/roles/role3.json +/users/ +/users/user3.json +EOM + end + + it "knife list --local -Rfp --chef-repo-path chef_r~1 / grabs chef_repo2 stuff", :windows_only do + Chef::Config.delete(:chef_repo_path) + knife("list -z -Rfp --chef-repo-path #{path_to('chef_r~1')} /").should_succeed <<EOM +/acls/ +/acls/clients/ +/acls/clients/client3.json +/acls/containers/ +/acls/cookbook_artifacts/ +/acls/cookbooks/ +/acls/cookbooks/cookbook3.json +/acls/data_bags/ +/acls/data_bags/bag3.json +/acls/environments/ +/acls/environments/env3.json +/acls/groups/ +/acls/nodes/ +/acls/nodes/node3.json +/acls/organization.json +/acls/policies/ +/acls/policy_groups/ +/acls/roles/ +/acls/roles/role3.json +/clients/ +/clients/client3.json +/containers/ +/cookbook_artifacts/ +/cookbooks/ +/cookbooks/cookbook3/ +/cookbooks/cookbook3/metadata.rb +/data_bags/ +/data_bags/bag3/ +/data_bags/bag3/item3.json +/environments/ +/environments/env3.json +/groups/ +/invitations.json +/members.json +/nodes/ +/nodes/node3.json +/org.json +/policies/ +/policy_groups/ +/roles/ +/roles/role3.json +EOM + end + context "when all _paths are set to alternates" do before :each do %w{client cookbook data_bag environment node role user}.each do |object_name| diff --git a/spec/integration/knife/diff_spec.rb b/spec/integration/knife/diff_spec.rb index b7d2f4d1c3..b3bd23f48e 100644 --- a/spec/integration/knife/diff_spec.rb +++ b/spec/integration/knife/diff_spec.rb @@ -72,7 +72,7 @@ EOM file "data_bags/x/y.json", {} file "environments/_default.json", { "description" => "The default Chef environment" } file "environments/x.json", {} - file "nodes/x.json", {} + file "nodes/x.json", { "normal" => { "tags" => [] } } file "roles/x.json", {} file "users/admin.json", { "admin" => true, "public_key" => ChefZero::PUBLIC_KEY } file "users/x.json", { "public_key" => ChefZero::PUBLIC_KEY } @@ -366,7 +366,7 @@ EOM file "data_bags/x/y.json", {} file "environments/_default.json", { "description" => "The default Chef environment" } file "environments/x.json", {} - file "nodes/x.json", {} + file "nodes/x.json", { "normal" => { "tags" => [] } } file "roles/x.json", {} file "users/admin.json", { "admin" => true, "public_key" => ChefZero::PUBLIC_KEY } file "users/x.json", { "public_key" => ChefZero::PUBLIC_KEY } diff --git a/spec/integration/knife/download_spec.rb b/spec/integration/knife/download_spec.rb index a924226ea2..be0fc9d708 100644 --- a/spec/integration/knife/download_spec.rb +++ b/spec/integration/knife/download_spec.rb @@ -76,7 +76,7 @@ EOM file "data_bags/x/y.json", {} file "environments/_default.json", { "description" => "The default Chef environment" } file "environments/x.json", {} - file "nodes/x.json", {} + file "nodes/x.json", { "normal" => { "tags" => [] } } file "roles/x.json", {} file "users/admin.json", { "admin" => true, "public_key" => ChefZero::PUBLIC_KEY } file "users/x.json", { "public_key" => ChefZero::PUBLIC_KEY } @@ -645,7 +645,7 @@ EOM file "data_bags/x/y.json", {} file "environments/_default.json", { "description" => "The default Chef environment" } file "environments/x.json", {} - file "nodes/x.json", {} + file "nodes/x.json", { "normal" => { "tags" => [] } } file "roles/x.json", {} file "users/admin.json", { "admin" => true, "public_key" => ChefZero::PUBLIC_KEY } file "users/x.json", { "public_key" => ChefZero::PUBLIC_KEY } @@ -1271,7 +1271,7 @@ EOM file "groups/x.json", {} file "invitations.json", [ "foo" ] file "members.json", [ "bar" ] - file "nodes/x.json", {} + file "nodes/x.json", { "normal" => { "tags" => [] } } file "org.json", { "full_name" => "Something" } file "policies/x-1.0.0.json", {} file "policies/blah-1.0.0.json", {} @@ -1295,7 +1295,7 @@ EOM file "environments/x.json", { "description" => "foo" } file "groups/x.json", { "description" => "foo" } file "groups/x.json", { "groups" => [ "admin" ] } - file "nodes/x.json", { "run_list" => [ "blah" ] } + file "nodes/x.json", { "normal" => { "tags" => [] }, "run_list" => [ "blah" ] } file "org.json", { "full_name" => "Something Else " } file "policies/x-1.0.0.json", { "run_list" => [ "blah" ] } file "policy_groups/x.json", { diff --git a/spec/integration/knife/raw_spec.rb b/spec/integration/knife/raw_spec.rb index 9078bf09a1..5e0d3a3d11 100644 --- a/spec/integration/knife/raw_spec.rb +++ b/spec/integration/knife/raw_spec.rb @@ -49,7 +49,9 @@ describe "knife raw", :workstation do }, "normal": { + "tags": [ + ] }, "default": { diff --git a/spec/integration/knife/upload_spec.rb b/spec/integration/knife/upload_spec.rb index 55c95b59b7..d372a83a35 100644 --- a/spec/integration/knife/upload_spec.rb +++ b/spec/integration/knife/upload_spec.rb @@ -96,7 +96,7 @@ EOM file "data_bags/x/y.json", {} file "environments/_default.json", { "description" => "The default Chef environment" } file "environments/x.json", {} - file "nodes/x.json", {} + file "nodes/x.json", { "normal" => { "tags" => [] } } file "roles/x.json", {} file "users/admin.json", { "admin" => true, "public_key" => ChefZero::PUBLIC_KEY } file "users/x.json", { "public_key" => ChefZero::PUBLIC_KEY } @@ -802,7 +802,7 @@ EOM file "data_bags/x/y.json", {} file "environments/_default.json", { "description" => "The default Chef environment" } file "environments/x.json", {} - file "nodes/x.json", {} + file "nodes/x.json", { "normal" => { "tags" => [] } } file "roles/x.json", {} file "users/admin.json", { "admin" => true, "public_key" => ChefZero::PUBLIC_KEY } file "users/x.json", { "public_key" => ChefZero::PUBLIC_KEY } @@ -1064,7 +1064,7 @@ EOM when_the_repository "has a modified, extra and missing file for the cookbook" do before do - file "cookbooks/x-1.0.0/metadata.rb", cb_metadata("x", "1.0.0", '#modified') + file "cookbooks/x-1.0.0/metadata.rb", cb_metadata("x", "1.0.0", "#modified") file "cookbooks/x-1.0.0/y.rb", "hi" end @@ -1313,7 +1313,7 @@ EOM file "invitations.json", [ "foo" ] file "members.json", [ "bar" ] file "org.json", { "full_name" => "wootles" } - file "nodes/x.json", {} + file "nodes/x.json", { "normal" => { "tags" => [] } } file "policies/x-1.0.0.json", {} file "policies/blah-1.0.0.json", {} file "policy_groups/x.json", { "policies" => { "x" => { "revision_id" => "1.0.0" }, "blah" => { "revision_id" => "1.0.0" } } } diff --git a/spec/integration/recipes/lwrp_inline_resources_spec.rb b/spec/integration/recipes/lwrp_inline_resources_spec.rb index 46fd83423d..65931d4764 100644 --- a/spec/integration/recipes/lwrp_inline_resources_spec.rb +++ b/spec/integration/recipes/lwrp_inline_resources_spec.rb @@ -38,9 +38,9 @@ describe "LWRPs with inline resources" do it "this is totally a bug, but for backcompat purposes, it adds the resources to the main resource collection and does not get marked updated" do r = nil - expect_recipe { + expect_recipe do r = lwrp_inline_resources_test "hi" - }.to have_updated("ruby_block[run a]", :run) + end.to have_updated("ruby_block[run a]", :run) expect(r.ran_a).to eq "ran a" end end @@ -64,11 +64,11 @@ describe "LWRPs with inline resources" do # https://github.com/chef/chef/issues/4334 it "does not warn spuriously" do expect(Chef::Log).to_not receive(:warn).with(/is declared in both/) - expect_recipe { + expect_recipe do lwrp_shadowed_property_test "fnord" do action :fiddle end - } + end end end @@ -104,11 +104,11 @@ describe "LWRPs with inline resources" do it "resources declared in b are executed immediately inline" do r = nil - expect_recipe { + expect_recipe do r = lwrp_inline_resources_test2 "hi" do action :b end - }.to have_updated("lwrp_inline_resources_test2[hi]", :b). + end.to have_updated("lwrp_inline_resources_test2[hi]", :b). and have_updated("ruby_block[run a]", :run). and have_updated("ruby_block[run b]", :run) expect(r.ran_b).to eq "ran b: ran_a value was \"ran a\"" diff --git a/spec/integration/recipes/noop_resource_spec.rb b/spec/integration/recipes/noop_resource_spec.rb index c8ff3e6b5e..e0cf47c371 100644 --- a/spec/integration/recipes/noop_resource_spec.rb +++ b/spec/integration/recipes/noop_resource_spec.rb @@ -4,20 +4,20 @@ describe "Resources with a no-op provider" do include IntegrationSupport context "with noop provider providing foo" do - before(:context) { + before(:context) do class NoOpFoo < Chef::Resource resource_name "hi_there" default_action :update end Chef::Provider::Noop.provides :hi_there - } + end it "does not blow up a run with a noop'd resource" do - recipe = converge { + recipe = converge do hi_there "blah" do action :update end - } + end expect(recipe.logged_warnings).to eq "" end end diff --git a/spec/integration/recipes/provider_choice.rb b/spec/integration/recipes/provider_choice.rb index a9fc06038a..1895d93891 100644 --- a/spec/integration/recipes/provider_choice.rb +++ b/spec/integration/recipes/provider_choice.rb @@ -26,9 +26,9 @@ describe "Recipe DSL methods" do end it "provider_thingy 'blah' runs the provider and warns" do - recipe = converge { - provider_thingy "blah" do; end - } + recipe = converge do + provider_thingy("blah") {} + end expect(recipe.logged_warnings).to match /hello from Chef::Provider::ProviderThingy/ expect(recipe.logged_warnings).to match /you must use 'provides' to provide DSL/i end diff --git a/spec/integration/recipes/recipe_dsl_spec.rb b/spec/integration/recipes/recipe_dsl_spec.rb index f96be7ea91..456319c306 100644 --- a/spec/integration/recipes/recipe_dsl_spec.rb +++ b/spec/integration/recipes/recipe_dsl_spec.rb @@ -12,7 +12,7 @@ describe "Recipe DSL methods" do before { Namer.current_index += 1 } context "with resource 'base_thingy' declared as BaseThingy" do - before(:context) { + before(:context) do class BaseThingy < Chef::Resource resource_name "base_thingy" @@ -43,7 +43,7 @@ describe "Recipe DSL methods" do module RecipeDSLSpecNamespace; end module RecipeDSLSpecNamespace::Bar; end - } + end before :each do BaseThingy.created_resource = nil @@ -51,26 +51,26 @@ describe "Recipe DSL methods" do end it "creates base_thingy when you call base_thingy in a recipe" do - recipe = converge { - base_thingy "blah" do; end - } + recipe = converge do + base_thingy("blah") {} + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_name).to eq "blah" expect(BaseThingy.created_resource).to eq BaseThingy end it "errors out when you call base_thingy do ... end in a recipe" do - expect_converge { - base_thingy do; end - }.to raise_error(ArgumentError, "You must supply a name when declaring a base_thingy resource") + expect_converge do + base_thingy { ; } + end.to raise_error(ArgumentError, "You must supply a name when declaring a base_thingy resource") end it "emits a warning when you call base_thingy 'foo', 'bar' do ... end in a recipe" do Chef::Config[:treat_deprecation_warnings_as_errors] = false - recipe = converge { + recipe = converge do base_thingy "foo", "bar" do end - } + end expect(recipe.logged_warnings).to match(/Cannot create resource base_thingy with more than one argument. All arguments except the name \("foo"\) will be ignored. This will cause an error in Chef 13. Arguments: \["foo", "bar"\]/) expect(BaseThingy.created_name).to eq "foo" expect(BaseThingy.created_resource).to eq BaseThingy @@ -82,7 +82,7 @@ describe "Recipe DSL methods" do end context "with a resource 'backcompat_thingy' declared in Chef::Resource and Chef::Provider" do - before(:context) { + before(:context) do class Chef::Resource::BackcompatThingy < Chef::Resource default_action :create @@ -97,30 +97,30 @@ describe "Recipe DSL methods" do end end - } + end it "backcompat_thingy creates a Chef::Resource::BackcompatThingy" do - recipe = converge { - backcompat_thingy "blah" do; end - } + recipe = converge do + backcompat_thingy("blah") {} + end expect(BaseThingy.created_resource).to eq Chef::Resource::BackcompatThingy expect(BaseThingy.created_provider).to eq Chef::Provider::BackcompatThingy end context "and another resource 'backcompat_thingy' in BackcompatThingy with 'provides'" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::BackcompatThingy < BaseThingy provides :backcompat_thingy resource_name :backcompat_thingy end - } + end it "backcompat_thingy creates a BackcompatThingy" do - recipe = converge { - backcompat_thingy "blah" do; end - } + recipe = converge do + backcompat_thingy("blah") {} + end expect(recipe.logged_warnings).to match(/Class Chef::Provider::BackcompatThingy does not declare 'provides :backcompat_thingy'./) expect(BaseThingy.created_resource).not_to be_nil end @@ -128,86 +128,86 @@ describe "Recipe DSL methods" do end context "with a resource named RecipeDSLSpecNamespace::Bar::BarThingy" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Bar::BarThingy < BaseThingy end - } + end it "bar_thingy does not work" do - expect_converge { - bar_thingy "blah" do; end - }.to raise_error(NoMethodError) + expect_converge do + bar_thingy("blah") {} + end.to raise_error(NoMethodError) end end context "with a resource named Chef::Resource::NoNameThingy with resource_name nil" do - before(:context) { + before(:context) do class Chef::Resource::NoNameThingy < BaseThingy resource_name nil end - } + end it "no_name_thingy does not work" do - expect_converge { - no_name_thingy "blah" do; end - }.to raise_error(NoMethodError) + expect_converge do + no_name_thingy("blah") {} + end.to raise_error(NoMethodError) end end context "with a resource named AnotherNoNameThingy with resource_name :another_thingy_name" do - before(:context) { + before(:context) do class AnotherNoNameThingy < BaseThingy resource_name :another_thingy_name end - } + end it "another_no_name_thingy does not work" do - expect_converge { - another_no_name_thingy "blah" do; end - }.to raise_error(NoMethodError) + expect_converge do + another_no_name_thingy("blah") {} + end.to raise_error(NoMethodError) end it "another_thingy_name works" do - recipe = converge { - another_thingy_name "blah" do; end - } + recipe = converge do + another_thingy_name("blah") {} + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq(AnotherNoNameThingy) end end context "with a resource named AnotherNoNameThingy2 with resource_name :another_thingy_name2; resource_name :another_thingy_name3" do - before(:context) { + before(:context) do class AnotherNoNameThingy2 < BaseThingy resource_name :another_thingy_name2 resource_name :another_thingy_name3 end - } + end it "another_no_name_thingy does not work" do - expect_converge { - another_no_name_thingy2 "blah" do; end - }.to raise_error(NoMethodError) + expect_converge do + another_no_name_thingy2("blah") {} + end.to raise_error(NoMethodError) end it "another_thingy_name2 does not work" do - expect_converge { - another_thingy_name2 "blah" do; end - }.to raise_error(NoMethodError) + expect_converge do + another_thingy_name2("blah") {} + end.to raise_error(NoMethodError) end it "yet_another_thingy_name3 works" do - recipe = converge { - another_thingy_name3 "blah" do; end - } + recipe = converge do + another_thingy_name3("blah") {} + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq(AnotherNoNameThingy2) end @@ -215,36 +215,36 @@ describe "Recipe DSL methods" do context "provides overriding resource_name" do context "with a resource named AnotherNoNameThingy3 with provides :another_no_name_thingy3, os: 'blarghle'" do - before(:context) { + before(:context) do class AnotherNoNameThingy3 < BaseThingy resource_name :another_no_name_thingy_3 provides :another_no_name_thingy3, os: "blarghle" end - } + end it "and os = linux, another_no_name_thingy3 does not work" do - expect_converge { + expect_converge do # TODO this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "linux" - another_no_name_thingy3 "blah" do; end - }.to raise_error(Chef::Exceptions::NoSuchResourceType) + another_no_name_thingy3("blah") {} + end.to raise_error(Chef::Exceptions::NoSuchResourceType) end it "and os = blarghle, another_no_name_thingy3 works" do - recipe = converge { + recipe = converge do # TODO this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "blarghle" - another_no_name_thingy3 "blah" do; end - } + another_no_name_thingy3("blah") {} + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq (AnotherNoNameThingy3) end end context "with a resource named AnotherNoNameThingy4 with two provides" do - before(:context) { + before(:context) do class AnotherNoNameThingy4 < BaseThingy resource_name :another_no_name_thingy_4 @@ -252,183 +252,183 @@ describe "Recipe DSL methods" do provides :another_no_name_thingy4, platform_family: "foo" end - } + end it "and os = linux, another_no_name_thingy4 does not work" do - expect_converge { + expect_converge do # TODO this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "linux" - another_no_name_thingy4 "blah" do; end - }.to raise_error(Chef::Exceptions::NoSuchResourceType) + another_no_name_thingy4("blah") {} + end.to raise_error(Chef::Exceptions::NoSuchResourceType) end it "and os = blarghle, another_no_name_thingy4 works" do - recipe = converge { + recipe = converge do # TODO this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "blarghle" - another_no_name_thingy4 "blah" do; end - } + another_no_name_thingy4("blah") {} + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq (AnotherNoNameThingy4) end it "and platform_family = foo, another_no_name_thingy4 works" do - recipe = converge { + recipe = converge do # TODO this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:platform_family] = "foo" - another_no_name_thingy4 "blah" do; end - } + another_no_name_thingy4("blah") {} + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq (AnotherNoNameThingy4) end end context "with a resource named AnotherNoNameThingy5, a different resource_name, and a provides with the original resource_name" do - before(:context) { + before(:context) do class AnotherNoNameThingy5 < BaseThingy resource_name :another_thingy_name_for_another_no_name_thingy5 provides :another_no_name_thingy5, os: "blarghle" end - } + end it "and os = linux, another_no_name_thingy5 does not work" do - expect_converge { + expect_converge do # this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "linux" - another_no_name_thingy5 "blah" do; end - }.to raise_error(Chef::Exceptions::NoSuchResourceType) + another_no_name_thingy5("blah") {} + end.to raise_error(Chef::Exceptions::NoSuchResourceType) end it "and os = blarghle, another_no_name_thingy5 works" do - recipe = converge { + recipe = converge do # this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "blarghle" - another_no_name_thingy5 "blah" do; end - } + another_no_name_thingy5("blah") {} + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq (AnotherNoNameThingy5) end it "the new resource name can be used in a recipe" do - recipe = converge { - another_thingy_name_for_another_no_name_thingy5 "blah" do; end - } + recipe = converge do + another_thingy_name_for_another_no_name_thingy5("blah") {} + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq (AnotherNoNameThingy5) end end context "with a resource named AnotherNoNameThingy6, a provides with the original resource name, and a different resource_name" do - before(:context) { + before(:context) do class AnotherNoNameThingy6 < BaseThingy provides :another_no_name_thingy6, os: "blarghle" resource_name :another_thingy_name_for_another_no_name_thingy6 end - } + end it "and os = linux, another_no_name_thingy6 does not work" do - expect_converge { + expect_converge do # this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "linux" - another_no_name_thingy6 "blah" do; end - }.to raise_error(Chef::Exceptions::NoSuchResourceType) + another_no_name_thingy6("blah") {} + end.to raise_error(Chef::Exceptions::NoSuchResourceType) end it "and os = blarghle, another_no_name_thingy6 works" do - recipe = converge { + recipe = converge do # this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "blarghle" - another_no_name_thingy6 "blah" do; end - } + another_no_name_thingy6("blah") {} + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq (AnotherNoNameThingy6) end it "the new resource name can be used in a recipe" do - recipe = converge { - another_thingy_name_for_another_no_name_thingy6 "blah" do; end - } + recipe = converge do + another_thingy_name_for_another_no_name_thingy6("blah") {} + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq (AnotherNoNameThingy6) end end context "with a resource named AnotherNoNameThingy7, a new resource_name, and provides with that new resource name" do - before(:context) { + before(:context) do class AnotherNoNameThingy7 < BaseThingy resource_name :another_thingy_name_for_another_no_name_thingy7 provides :another_thingy_name_for_another_no_name_thingy7, os: "blarghle" end - } + end it "and os = linux, another_thingy_name_for_another_no_name_thingy7 does not work" do - expect_converge { + expect_converge do # this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "linux" - another_thingy_name_for_another_no_name_thingy7 "blah" do; end - }.to raise_error(Chef::Exceptions::NoSuchResourceType) + another_thingy_name_for_another_no_name_thingy7("blah") {} + end.to raise_error(Chef::Exceptions::NoSuchResourceType) end it "and os = blarghle, another_thingy_name_for_another_no_name_thingy7 works" do - recipe = converge { + recipe = converge do # this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "blarghle" - another_thingy_name_for_another_no_name_thingy7 "blah" do; end - } + another_thingy_name_for_another_no_name_thingy7("blah") {} + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq (AnotherNoNameThingy7) end it "the old resource name does not work" do - expect_converge { + expect_converge do # this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "linux" - another_no_name_thingy_7 "blah" do; end - }.to raise_error(NoMethodError) + another_no_name_thingy_7("blah") {} + end.to raise_error(NoMethodError) end end # opposite order from the previous test (provides, then resource_name) context "with a resource named AnotherNoNameThingy8, a provides with a new resource name, and resource_name with that new resource name" do - before(:context) { + before(:context) do class AnotherNoNameThingy8 < BaseThingy provides :another_thingy_name_for_another_no_name_thingy8, os: "blarghle" resource_name :another_thingy_name_for_another_no_name_thingy8 end - } + end it "and os = linux, another_thingy_name_for_another_no_name_thingy8 does not work" do - expect_converge { + expect_converge do # this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "linux" - another_thingy_name_for_another_no_name_thingy8 "blah" do; end - }.to raise_error(Chef::Exceptions::NoSuchResourceType) + another_thingy_name_for_another_no_name_thingy8("blah") {} + end.to raise_error(Chef::Exceptions::NoSuchResourceType) end it "and os = blarghle, another_thingy_name_for_another_no_name_thingy8 works" do - recipe = converge { + recipe = converge do # this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "blarghle" - another_thingy_name_for_another_no_name_thingy8 "blah" do; end - } + another_thingy_name_for_another_no_name_thingy8("blah") {} + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq (AnotherNoNameThingy8) end it "the old resource name does not work" do - expect_converge { + expect_converge do # this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "linux" - another_thingy_name8 "blah" do; end - }.to raise_error(NoMethodError) + another_thingy_name8("blah") {} + end.to raise_error(NoMethodError) end end end @@ -436,64 +436,64 @@ describe "Recipe DSL methods" do context "provides" do context "when MySupplier provides :hemlock" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::MySupplier < BaseThingy resource_name :hemlock end - } + end it "my_supplier does not work in a recipe" do - expect_converge { - my_supplier "blah" do; end - }.to raise_error(NoMethodError) + expect_converge do + my_supplier("blah") {} + end.to raise_error(NoMethodError) end it "hemlock works in a recipe" do - expect_recipe { - hemlock "blah" do; end - }.to emit_no_warnings_or_errors + expect_recipe do + hemlock("blah") {} + end.to emit_no_warnings_or_errors expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::MySupplier end end context "when Thingy3 has resource_name :thingy3" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Thingy3 < BaseThingy resource_name :thingy3 end - } + end it "thingy3 works in a recipe" do - expect_recipe { - thingy3 "blah" do; end - }.to emit_no_warnings_or_errors + expect_recipe do + thingy3("blah") {} + end.to emit_no_warnings_or_errors expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy3 end context "and Thingy4 has resource_name :thingy3" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Thingy4 < BaseThingy resource_name :thingy3 end - } + end it "thingy3 works in a recipe and yields Thingy3 (the alphabetical one)" do - recipe = converge { - thingy3 "blah" do; end - } + recipe = converge do + thingy3("blah") {} + end expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy3 end it "thingy4 does not work in a recipe" do - expect_converge { - thingy4 "blah" do; end - }.to raise_error(NoMethodError) + expect_converge do + thingy4("blah") {} + end.to raise_error(NoMethodError) end it "resource_matching_short_name returns Thingy4" do @@ -503,7 +503,7 @@ describe "Recipe DSL methods" do end context "when Thingy5 has resource_name :thingy5 and provides :thingy5reverse, :thingy5_2 and :thingy5_2reverse" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Thingy5 < BaseThingy resource_name :thingy5 @@ -512,36 +512,36 @@ describe "Recipe DSL methods" do provides :thingy5_2reverse end - } + end it "thingy5 works in a recipe" do - expect_recipe { - thingy5 "blah" do; end - }.to emit_no_warnings_or_errors + expect_recipe do + thingy5("blah") {} + end.to emit_no_warnings_or_errors expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy5 end context "and Thingy6 provides :thingy5" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Thingy6 < BaseThingy resource_name :thingy6 provides :thingy5 end - } + end it "thingy6 works in a recipe and yields Thingy6" do - recipe = converge { - thingy6 "blah" do; end - } + recipe = converge do + thingy6("blah") {} + end expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy6 end it "thingy5 works in a recipe and yields Foo::Thingy5 (the alphabetical one)" do - recipe = converge { - thingy5 "blah" do; end - } + recipe = converge do + thingy5("blah") {} + end expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy5 end @@ -550,24 +550,24 @@ describe "Recipe DSL methods" do end context "and AThingy5 provides :thingy5reverse" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::AThingy5 < BaseThingy resource_name :thingy5reverse end - } + end it "thingy5reverse works in a recipe and yields AThingy5 (the alphabetical one)" do - recipe = converge { - thingy5reverse "blah" do; end - } + recipe = converge do + thingy5reverse("blah") {} + end expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::AThingy5 end end context "and ZRecipeDSLSpecNamespace::Thingy5 provides :thingy5_2" do - before(:context) { + before(:context) do module ZRecipeDSLSpecNamespace class Thingy5 < BaseThingy @@ -575,18 +575,18 @@ describe "Recipe DSL methods" do end end - } + end it "thingy5_2 works in a recipe and yields the RecipeDSLSpaceNamespace one (the alphabetical one)" do - recipe = converge { - thingy5_2 "blah" do; end - } + recipe = converge do + thingy5_2("blah") {} + end expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy5 end end context "and ARecipeDSLSpecNamespace::Thingy5 provides :thingy5_2" do - before(:context) { + before(:context) do module ARecipeDSLSpecNamespace class Thingy5 < BaseThingy @@ -594,53 +594,53 @@ describe "Recipe DSL methods" do end end - } + end it "thingy5_2reverse works in a recipe and yields the ARecipeDSLSpaceNamespace one (the alphabetical one)" do - recipe = converge { - thingy5_2reverse "blah" do; end - } + recipe = converge do + thingy5_2reverse("blah") {} + end expect(BaseThingy.created_resource).to eq ARecipeDSLSpecNamespace::Thingy5 end end end context "when Thingy3 has resource_name :thingy3" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Thingy3 < BaseThingy resource_name :thingy3 end - } + end it "thingy3 works in a recipe" do - expect_recipe { - thingy3 "blah" do; end - }.to emit_no_warnings_or_errors + expect_recipe do + thingy3("blah") {} + end.to emit_no_warnings_or_errors expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy3 end context "and Thingy4 has resource_name :thingy3" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Thingy4 < BaseThingy resource_name :thingy3 end - } + end it "thingy3 works in a recipe and yields Thingy3 (the alphabetical one)" do - recipe = converge { - thingy3 "blah" do; end - } + recipe = converge do + thingy3("blah") {} + end expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy3 end it "thingy4 does not work in a recipe" do - expect_converge { - thingy4 "blah" do; end - }.to raise_error(NoMethodError) + expect_converge do + thingy4("blah") {} + end.to raise_error(NoMethodError) end it "resource_matching_short_name returns Thingy4" do @@ -649,25 +649,25 @@ describe "Recipe DSL methods" do end context "and Thingy4 has resource_name :thingy3" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Thingy4 < BaseThingy resource_name :thingy3 end - } + end it "thingy3 works in a recipe and yields Thingy3 (the alphabetical one)" do - recipe = converge { - thingy3 "blah" do; end - } + recipe = converge do + thingy3("blah") {} + end expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy3 end it "thingy4 does not work in a recipe" do - expect_converge { - thingy4 "blah" do; end - }.to raise_error(NoMethodError) + expect_converge do + thingy4("blah") {} + end.to raise_error(NoMethodError) end it "resource_matching_short_name returns Thingy4" do @@ -679,35 +679,35 @@ describe "Recipe DSL methods" do end context "when Thingy7 provides :thingy8" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Thingy7 < BaseThingy resource_name :thingy7 provides :thingy8 end - } + end context "and Thingy8 has resource_name :thingy8" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Thingy8 < BaseThingy resource_name :thingy8 end - } + end it "thingy7 works in a recipe and yields Thingy7" do - recipe = converge { - thingy7 "blah" do; end - } + recipe = converge do + thingy7("blah") {} + end expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy7 end it "thingy8 works in a recipe and yields Thingy7 (alphabetical)" do - recipe = converge { - thingy8 "blah" do; end - } + recipe = converge do + thingy8("blah") {} + end expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy7 end @@ -718,7 +718,7 @@ describe "Recipe DSL methods" do end context "when Thingy12 provides :thingy12, :twizzle and :twizzle2" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Thingy12 < BaseThingy resource_name :thingy12 @@ -726,32 +726,32 @@ describe "Recipe DSL methods" do provides :twizzle2 end - } + end it "thingy12 works in a recipe and yields Thingy12" do - expect_recipe { - thingy12 "blah" do; end - }.to emit_no_warnings_or_errors + expect_recipe do + thingy12("blah") {} + end.to emit_no_warnings_or_errors expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy12 end it "twizzle works in a recipe and yields Thingy12" do - expect_recipe { - twizzle "blah" do; end - }.to emit_no_warnings_or_errors + expect_recipe do + twizzle("blah") {} + end.to emit_no_warnings_or_errors expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy12 end it "twizzle2 works in a recipe and yields Thingy12" do - expect_recipe { - twizzle2 "blah" do; end - }.to emit_no_warnings_or_errors + expect_recipe do + twizzle2("blah") {} + end.to emit_no_warnings_or_errors expect(BaseThingy.created_resource).to eq RecipeDSLSpecNamespace::Thingy12 end end context "with platform-specific resources 'my_super_thingy_foo' and 'my_super_thingy_bar'" do - before(:context) { + before(:context) do class MySuperThingyFoo < BaseThingy resource_name :my_super_thingy_foo provides :my_super_thingy, platform: "foo" @@ -761,14 +761,14 @@ describe "Recipe DSL methods" do resource_name :my_super_thingy_bar provides :my_super_thingy, platform: "bar" end - } + end it "A run with platform 'foo' uses MySuperThingyFoo" do r = Cheffish::ChefRun.new(chef_config) r.client.run_context.node.automatic["platform"] = "foo" - r.compile_recipe { - my_super_thingy "blah" do; end - } + r.compile_recipe do + my_super_thingy("blah") {} + end r.converge expect(r).to emit_no_warnings_or_errors expect(BaseThingy.created_resource).to eq MySuperThingyFoo @@ -777,9 +777,9 @@ describe "Recipe DSL methods" do it "A run with platform 'bar' uses MySuperThingyBar" do r = Cheffish::ChefRun.new(chef_config) r.client.run_context.node.automatic["platform"] = "bar" - r.compile_recipe { - my_super_thingy "blah" do; end - } + r.compile_recipe do + my_super_thingy("blah") {} + end r.converge expect(r).to emit_no_warnings_or_errors expect(BaseThingy.created_resource).to eq MySuperThingyBar @@ -788,20 +788,20 @@ describe "Recipe DSL methods" do it "A run with platform 'x' reports that my_super_thingy is not supported" do r = Cheffish::ChefRun.new(chef_config) r.client.run_context.node.automatic["platform"] = "x" - expect { - r.compile_recipe { - my_super_thingy "blah" do; end - } - }.to raise_error(Chef::Exceptions::NoSuchResourceType) + expect do + r.compile_recipe do + my_super_thingy("blah") {} + end + end.to raise_error(Chef::Exceptions::NoSuchResourceType) end end context "when Thingy10 provides :thingy10" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Thingy10 < BaseThingy resource_name :thingy10 end - } + end it "declaring a resource providing the same :thingy10 with override: true does not produce a warning" do expect(Chef::Log).not_to receive(:warn) @@ -812,11 +812,11 @@ describe "Recipe DSL methods" do end context "when Thingy11 provides :thingy11" do - before(:context) { + before(:context) do class RecipeDSLSpecNamespace::Thingy11 < BaseThingy resource_name :thingy10 end - } + end it "declaring a resource providing the same :thingy11 with os: 'linux' does not produce a warning" do expect(Chef::Log).not_to receive(:warn) @@ -829,7 +829,7 @@ describe "Recipe DSL methods" do context "with a resource named 'B' with resource name :two_classes_one_dsl" do let(:two_classes_one_dsl) { :"two_classes_one_dsl#{Namer.current_index}" } - let(:resource_class) { + let(:resource_class) do result = Class.new(BaseThingy) do def self.name "B" @@ -841,11 +841,11 @@ describe "Recipe DSL methods" do end result.resource_name two_classes_one_dsl result - } + end before { resource_class } # pull on it so it gets defined before the recipe runs context "and another resource named 'A' with resource_name :two_classes_one_dsl" do - let(:resource_class_a) { + let(:resource_class_a) do result = Class.new(BaseThingy) do def self.name "A" @@ -857,14 +857,14 @@ describe "Recipe DSL methods" do end result.resource_name two_classes_one_dsl result - } + end before { resource_class_a } # pull on it so it gets defined before the recipe runs it "two_classes_one_dsl resolves to A (alphabetically earliest)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq resource_class_a end @@ -875,7 +875,7 @@ describe "Recipe DSL methods" do end context "and another resource named 'Z' with resource_name :two_classes_one_dsl" do - let(:resource_class_z) { + let(:resource_class_z) do result = Class.new(BaseThingy) do def self.name "Z" @@ -887,14 +887,14 @@ describe "Recipe DSL methods" do end result.resource_name two_classes_one_dsl result - } + end before { resource_class_z } # pull on it so it gets defined before the recipe runs it "two_classes_one_dsl resolves to B (alphabetically earliest)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq resource_class end @@ -910,9 +910,9 @@ describe "Recipe DSL methods" do it "two_classes_one_dsl resolves to Z (respects the priority array)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq resource_class_z end @@ -928,9 +928,9 @@ describe "Recipe DSL methods" do it "two_classes_one_dsl resolves to B (picks the next thing in the priority array)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq resource_class end @@ -949,9 +949,9 @@ describe "Recipe DSL methods" do it "two_classes_one_dsl resolves to Z (respects the most recent priority array)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq resource_class_z end @@ -967,9 +967,9 @@ describe "Recipe DSL methods" do it "two_classes_one_dsl resolves to B (picks the first match from the other priority array)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq resource_class end @@ -992,9 +992,9 @@ describe "Recipe DSL methods" do it "two_classes_one_dsl resolves to B (picks the first match outside the priority array)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq resource_class end @@ -1012,7 +1012,7 @@ describe "Recipe DSL methods" do resource_class.send(:define_method, :provider) { nil } end - let(:provider_class) { + let(:provider_class) do result = Class.new(BaseThingy::Provider) do def self.name "B" @@ -1024,11 +1024,11 @@ describe "Recipe DSL methods" do end result.provides two_classes_one_dsl result - } + end before { provider_class } # pull on it so it gets defined before the recipe runs context "and another provider named 'A'" do - let(:provider_class_a) { + let(:provider_class_a) do result = Class.new(BaseThingy::Provider) do def self.name "A" @@ -1039,15 +1039,15 @@ describe "Recipe DSL methods" do def self.inspect; name.inspect; end end result - } + end context "which provides :two_classes_one_dsl" do before { provider_class_a.provides two_classes_one_dsl } it "two_classes_one_dsl resolves to A (alphabetically earliest)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_provider).to eq provider_class_a end @@ -1057,9 +1057,9 @@ describe "Recipe DSL methods" do it "two_classes_one_dsl resolves to B (since A declined)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_provider).to eq provider_class end @@ -1067,7 +1067,7 @@ describe "Recipe DSL methods" do end context "and another provider named 'Z'" do - let(:provider_class_z) { + let(:provider_class_z) do result = Class.new(BaseThingy::Provider) do def self.name "Z" @@ -1078,7 +1078,7 @@ describe "Recipe DSL methods" do def self.inspect; name.inspect; end end result - } + end before { provider_class_z } # pull on it so it gets defined before the recipe runs context "which provides :two_classes_one_dsl" do @@ -1086,9 +1086,9 @@ describe "Recipe DSL methods" do it "two_classes_one_dsl resolves to B (alphabetically earliest)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_provider).to eq provider_class end @@ -1098,9 +1098,9 @@ describe "Recipe DSL methods" do it "two_classes_one_dsl resolves to Z (respects the priority map)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_provider).to eq provider_class_z end @@ -1115,9 +1115,9 @@ describe "Recipe DSL methods" do it "two_classes_one_dsl resolves to B (the next one in the priority map)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_provider).to eq provider_class end @@ -1129,9 +1129,9 @@ describe "Recipe DSL methods" do it "two_classes_one_dsl resolves to B (the one in the next priority map)" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do instance_eval("#{two_classes_one_dsl} 'blah'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_provider).to eq provider_class end @@ -1141,7 +1141,7 @@ describe "Recipe DSL methods" do end context "and another resource Blarghle with provides :two_classes_one_dsl, os: 'blarghle'" do - let(:resource_class_blarghle) { + let(:resource_class_blarghle) do result = Class.new(BaseThingy) do def self.name "Blarghle" @@ -1154,27 +1154,27 @@ describe "Recipe DSL methods" do result.resource_name two_classes_one_dsl result.provides two_classes_one_dsl, os: "blarghle" result - } + end before { resource_class_blarghle } # pull on it so it gets defined before the recipe runs it "on os = blarghle, two_classes_one_dsl resolves to Blarghle" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do # this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "blarghle" instance_eval("#{two_classes_one_dsl} 'blah' do; end") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq resource_class_blarghle end it "on os = linux, two_classes_one_dsl resolves to B" do two_classes_one_dsl = self.two_classes_one_dsl - recipe = converge { + recipe = converge do # this is an ugly way to test, make Cheffish expose node attrs run_context.node.automatic[:os] = "linux" instance_eval("#{two_classes_one_dsl} 'blah' do; end") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq resource_class end @@ -1182,37 +1182,38 @@ describe "Recipe DSL methods" do end context "with a resource MyResource" do - let(:resource_class) { Class.new(BaseThingy) do - def self.called_provides - @called_provides - end + let(:resource_class) do + Class.new(BaseThingy) do + def self.called_provides + @called_provides + end - def to_s - "MyResource" - end - end } + def to_s + "MyResource" + end + end end let(:my_resource) { :"my_resource#{Namer.current_index}" } let(:blarghle_blarghle_little_star) { :"blarghle_blarghle_little_star#{Namer.current_index}" } context "with resource_name :my_resource" do - before { + before do resource_class.resource_name my_resource - } + end context "with provides? returning true to my_resource" do - before { + before do my_resource = self.my_resource resource_class.define_singleton_method(:provides?) do |node, resource_name| @called_provides = true resource_name == my_resource end - } + end it "my_resource returns the resource and calls provides?, but does not emit a warning" do dsl_name = self.my_resource - recipe = converge { + recipe = converge do instance_eval("#{dsl_name} 'foo'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_resource).to eq resource_class expect(resource_class.called_provides).to be_truthy @@ -1230,18 +1231,18 @@ describe "Recipe DSL methods" do it "my_resource does not return the resource" do dsl_name = self.my_resource - expect_converge { + expect_converge do instance_eval("#{dsl_name} 'foo'") - }.to raise_error(Chef::Exceptions::NoSuchResourceType) + end.to raise_error(Chef::Exceptions::NoSuchResourceType) expect(resource_class.called_provides).to be_truthy end it "blarghle_blarghle_little_star 'foo' returns the resource and emits a warning" do Chef::Config[:treat_deprecation_warnings_as_errors] = false dsl_name = self.blarghle_blarghle_little_star - recipe = converge { + recipe = converge do instance_eval("#{dsl_name} 'foo'") - } + end expect(recipe.logged_warnings).to include "WARN: #{resource_class}.provides? returned true when asked if it provides DSL #{dsl_name}, but provides :#{dsl_name} was never called!" expect(BaseThingy.created_resource).to eq resource_class expect(resource_class.called_provides).to be_truthy @@ -1281,9 +1282,9 @@ describe "Recipe DSL methods" do it "my_resource runs the provider and does not emit a warning" do my_resource = self.my_resource - recipe = converge { + recipe = converge do instance_eval("#{my_resource} 'foo'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_provider).to eq provider_class end @@ -1311,9 +1312,9 @@ describe "Recipe DSL methods" do it "my_resource runs the first provider" do my_resource = self.my_resource - recipe = converge { + recipe = converge do instance_eval("#{my_resource} 'foo'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_provider).to eq provider_class end @@ -1328,9 +1329,9 @@ describe "Recipe DSL methods" do # TODO no warning? ick it "my_resource runs the provider anyway" do my_resource = self.my_resource - recipe = converge { + recipe = converge do instance_eval("#{my_resource} 'foo'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_provider).to eq provider_class end @@ -1360,9 +1361,9 @@ describe "Recipe DSL methods" do it "my_resource runs the other provider" do my_resource = self.my_resource - recipe = converge { + recipe = converge do instance_eval("#{my_resource} 'foo'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_provider).to eq provider_class2 end @@ -1371,24 +1372,24 @@ describe "Recipe DSL methods" do end context "with provides? returning true" do - before { + before do my_resource = self.my_resource provider_class.define_singleton_method(:provides?) do |node, resource| @called_provides = true resource.declared_type == my_resource end - } + end context "that provides :my_resource" do - before { + before do provider_class.provides my_resource - } + end it "my_resource calls the provider (and calls provides?), but does not emit a warning" do my_resource = self.my_resource - recipe = converge { + recipe = converge do instance_eval("#{my_resource} 'foo'") - } + end expect(recipe.logged_warnings).to eq "" expect(BaseThingy.created_provider).to eq provider_class expect(provider_class.called_provides).to be_truthy @@ -1399,9 +1400,9 @@ describe "Recipe DSL methods" do it "my_resource calls the provider (and calls provides?), and emits a warning" do Chef::Config[:treat_deprecation_warnings_as_errors] = false my_resource = self.my_resource - recipe = converge { + recipe = converge do instance_eval("#{my_resource} 'foo'") - } + end expect(recipe.logged_warnings).to include("WARN: #{provider_class}.provides? returned true when asked if it provides DSL #{my_resource}, but provides :#{my_resource} was never called!") expect(BaseThingy.created_provider).to eq provider_class expect(provider_class.called_provides).to be_truthy @@ -1410,24 +1411,24 @@ describe "Recipe DSL methods" do end context "with provides? returning false to my_resource" do - before { + before do my_resource = self.my_resource provider_class.define_singleton_method(:provides?) do |node, resource| @called_provides = true false end - } + end context "that provides :my_resource" do - before { + before do provider_class.provides my_resource - } + end it "my_resource fails to find a provider (and calls provides)" do my_resource = self.my_resource - expect_converge { + expect_converge do instance_eval("#{my_resource} 'foo'") - }.to raise_error(Chef::Exceptions::ProviderNotFound) + end.to raise_error(Chef::Exceptions::ProviderNotFound) expect(provider_class.called_provides).to be_truthy end end @@ -1435,9 +1436,9 @@ describe "Recipe DSL methods" do context "that does not provide :my_resource" do it "my_resource fails to find a provider (and calls provides)" do my_resource = self.my_resource - expect_converge { + expect_converge do instance_eval("#{my_resource} 'foo'") - }.to raise_error(Chef::Exceptions::ProviderNotFound) + end.to raise_error(Chef::Exceptions::ProviderNotFound) expect(provider_class.called_provides).to be_truthy end end @@ -1451,15 +1452,15 @@ describe "Recipe DSL methods" do before { Namer.current_index += 1 } context "with an LWRP that declares actions" do - let(:resource_class) { + let(:resource_class) do Class.new(Chef::Resource::LWRPBase) do provides :"recipe_dsl_spec#{Namer.current_index}" actions :create end - } - let(:resource) { + end + let(:resource) do resource_class.new("blah", run_context) - } + end it "The actions are part of actions along with :nothing" do expect(resource_class.actions).to eq [ :nothing, :create ] end @@ -1468,15 +1469,15 @@ describe "Recipe DSL methods" do end context "and a subclass that declares more actions" do - let(:subresource_class) { + let(:subresource_class) do Class.new(Chef::Resource::LWRPBase) do provides :"recipe_dsl_spec_sub#{Namer.current_index}" actions :delete end - } - let(:subresource) { + end + let(:subresource) do subresource_class.new("subblah", run_context) - } + end it "The parent class actions are not part of actions" do expect(subresource_class.actions).to eq [ :nothing, :delete ] @@ -1510,9 +1511,9 @@ describe "Recipe DSL methods" do it "looks up the provider in Chef::Provider converting the resource name from snake case to camel case" do resource = nil - recipe = converge { - resource = lw_resource_with_hw_provider_test_case "blah" do; end - } + recipe = converge do + resource = lw_resource_with_hw_provider_test_case("blah") {} + end expect(resource.created_provider).to eq(Chef::Provider::LwResourceWithHwProviderTestCase) end end diff --git a/spec/integration/recipes/resource_action_spec.rb b/spec/integration/recipes/resource_action_spec.rb index 8f6f4b7f46..0f90ed62f8 100644 --- a/spec/integration/recipes/resource_action_spec.rb +++ b/spec/integration/recipes/resource_action_spec.rb @@ -62,14 +62,14 @@ module ResourceActionSpec end it "the action cannot access private methods" do - expect { + expect do converge(<<-EOM, __FILE__, __LINE__ + 1) #{resource_dsl} "hi" do foo "foo!" action :access_private_method end EOM - }.to raise_error(NameError) + end.to raise_error(NameError) expect(ActionJackson.ran_action).to eq :access_private_method end @@ -139,26 +139,6 @@ module ResourceActionSpec attr_accessor :ruby_block_converged end - public - - def foo_public - "foo_public!" - end - - protected - - def foo_protected - "foo_protected!" - end - - private - - def foo_private - "foo_private!" - end - - public - action :access_recipe_dsl do ActionJackson.ran_action = :access_recipe_dsl ruby_block "hi there" do @@ -199,13 +179,29 @@ module ResourceActionSpec ActionJackson.ran_action = :access_class_method ActionJackson.succeeded = ActionJackson.ruby_block_converged end + + def foo_public + "foo_public!" + end + + protected + + def foo_protected + "foo_protected!" + end + + private + + def foo_private + "foo_private!" + end end - before(:each) { + before(:each) do ActionJackson.ran_action = :error ActionJackson.succeeded = :error ActionJackson.ruby_block_converged = :error - } + end it_behaves_like "ActionJackson" do let(:resource_dsl) { :action_jackson } @@ -217,11 +213,11 @@ module ResourceActionSpec end context "And 'action_jackgrandson' inheriting from ActionJackson and changing nothing" do - before(:context) { + before(:context) do class ActionJackgrandson < ActionJackson use_automatic_resource_name end - } + end it_behaves_like "ActionJackson" do let(:resource_dsl) { :action_jackgrandson } @@ -267,38 +263,38 @@ module ResourceActionSpec end it "the default action remains the same even though new actions were specified first" do - converge { + converge do action_jackalope "hi" do foo "foo!" bar "bar!" end - } + end expect(ActionJackson.ran_action).to eq :access_recipe_dsl expect(ActionJackson.succeeded).to eq true end it "new actions run, and can access overridden, new, and overridden attributes" do - converge { + converge do action_jackalope "hi" do foo "foo!" bar "bar!" blarghle "blarghle!" action :access_jackalope end - } + end expect(ActionJackalope.jackalope_ran).to eq :access_jackalope expect(ActionJackalope.succeeded).to eq "foo!alope blarghle! bar!alope" end it "overridden actions run, call super, and can access overridden, new, and overridden attributes" do - converge { + converge do action_jackalope "hi" do foo "foo!" bar "bar!" blarghle "blarghle!" action :access_attribute end - } + end expect(ActionJackson.ran_action).to eq :access_attribute expect(ActionJackson.succeeded).to eq "foo!alope blarghle! bar!alope" expect(ActionJackalope.jackalope_ran).to eq :access_attribute @@ -306,14 +302,14 @@ module ResourceActionSpec end it "non-overridden actions run and can access overridden and non-overridden variables (but not necessarily new ones)" do - converge { + converge do action_jackalope "hi" do foo "foo!" bar "bar!" blarghle "blarghle!" action :access_attribute2 end - } + end expect(ActionJackson.ran_action).to eq :access_attribute2 expect(ActionJackson.succeeded).to eq("foo!alope blarghle! bar!alope").or(eq("foo!alope blarghle!")) end @@ -335,12 +331,12 @@ module ResourceActionSpec end it "the default action is :nothing" do - converge { + converge do no_action_jackson "hi" do foo "foo!" NoActionJackson.action_was = action end - } + end expect(NoActionJackson.action_was).to eq [:nothing] end end @@ -359,9 +355,9 @@ module ResourceActionSpec end it "Running the action works" do - expect_recipe { + expect_recipe do weird_action_jackson "hi" - }.to be_up_to_date + end.to be_up_to_date expect(WeirdActionJackson.action_was).to eq :"a-b-c d" end end @@ -404,41 +400,41 @@ module ResourceActionSpec attr_reader :x_warning_line it "Using the enclosing resource to set x to x emits a warning that you're using the wrong x" do - recipe = converge { + recipe = converge do resource_action_spec_also_with_x "hi" do x 1 action :set_x_to_x end - } + end warnings = recipe.logs.lines.select { |l| l =~ /warn/i } expect(warnings.size).to eq 1 expect(warnings[0]).to match(/property x is declared in both resource_action_spec_with_x\[hi\] and resource_action_spec_also_with_x\[hi\] action :set_x_to_x. Use new_resource.x instead. At #{__FILE__}:#{ResourceActionSpecAlsoWithX.x_warning_line}/) end it "Using the enclosing resource to set x to x outside the initializer emits no warning" do - expect_recipe { + expect_recipe do resource_action_spec_also_with_x "hi" do x 1 action :set_x_to_x_in_non_initializer end - }.to emit_no_warnings_or_errors + end.to emit_no_warnings_or_errors end it "Using the enclosing resource to set x to 10 emits no warning" do - expect_recipe { + expect_recipe do resource_action_spec_also_with_x "hi" do x 1 action :set_x_to_10 end - }.to emit_no_warnings_or_errors + end.to emit_no_warnings_or_errors end it "Using the enclosing resource to set x to 10 emits no warning" do - expect_recipe { + expect_recipe do r = resource_action_spec_also_with_x "hi" r.x 1 r.action :set_x_to_10 - }.to emit_no_warnings_or_errors + end.to emit_no_warnings_or_errors end end @@ -464,11 +460,11 @@ module ResourceActionSpec end it "Setting group to nil in an action does not emit a warning about it being defined in two places" do - expect_recipe { + expect_recipe do resource_action_spec_set_group_to_nil "hi" do action :set_group_to_nil end - }.to emit_no_warnings_or_errors + end.to emit_no_warnings_or_errors end end @@ -484,9 +480,9 @@ module ResourceActionSpec end it "Raises an error when attempting to use a template in the action" do - expect_converge { + expect_converge do has_property_named_template "hi" - }.to raise_error(/Property template of has_property_named_template\[hi\] cannot be passed a block! If you meant to create a resource named template instead, you'll need to first rename the property./) + end.to raise_error(/Property template of has_property_named_template\[hi\] cannot be passed a block! If you meant to create a resource named template instead, you'll need to first rename the property./) end end @@ -528,9 +524,9 @@ module ResourceActionSpec it "the methods are available to the action" do r = nil - expect_recipe { + expect_recipe do r = declares_action_class_methods "hi" - }.to emit_no_warnings_or_errors + end.to emit_no_warnings_or_errors expect(r.x).to eq(10) end @@ -557,9 +553,9 @@ module ResourceActionSpec it "the methods are available to the action" do r = nil - expect_recipe { + expect_recipe do r = declares_action_class_methods_too "hi" - }.to emit_no_warnings_or_errors + end.to emit_no_warnings_or_errors expect(r.x).to eq(15) end end diff --git a/spec/integration/recipes/resource_converge_if_changed_spec.rb b/spec/integration/recipes/resource_converge_if_changed_spec.rb index 4e5fd526fc..89d831ddec 100644 --- a/spec/integration/recipes/resource_converge_if_changed_spec.rb +++ b/spec/integration/recipes/resource_converge_if_changed_spec.rb @@ -19,7 +19,7 @@ describe "Resource::ActionClass#converge_if_changed" do context "when the resource has identity, state and control properties" do let(:resource_name) { :"converge_if_changed_dsl#{Namer.current_index}" } - let(:resource_class) { + let(:resource_class) do result = Class.new(Chef::Resource) do def self.to_s; resource_name.to_s; end @@ -36,7 +36,7 @@ describe "Resource::ActionClass#converge_if_changed" do end result.resource_name resource_name result - } + end let(:converged_recipe) { converge(converge_recipe) } let(:resource) { converged_recipe.resources.first } @@ -70,13 +70,13 @@ describe "Resource::ActionClass#converge_if_changed" do end context "and state1 is set to a new value" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do state1 'new_state1' end EOM - } + end it "the resource updates state1" do expect(resource.converged).to eq 1 @@ -90,14 +90,14 @@ describe "Resource::ActionClass#converge_if_changed" do end context "and state1 and state2 are set to new values" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do state1 'new_state1' state2 'new_state2' end EOM - } + end it "the resource updates state1 and state2" do expect(resource.converged).to eq 1 @@ -112,7 +112,7 @@ EOM end context "and state1 and state2 are set to new sensitive values" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do sensitive true @@ -120,7 +120,7 @@ EOM state2 'new_state2' end EOM - } + end it "the resource updates state1 and state2" do expect(resource.converged).to eq 1 @@ -135,14 +135,14 @@ EOM end context "and state1 is set to its current value but state2 is set to a new value" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do state1 'current_state1' state2 'new_state2' end EOM - } + end it "the resource updates state2" do expect(resource.converged).to eq 1 @@ -156,14 +156,14 @@ EOM end context "and state1 and state2 are set to their current values" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do state1 'current_state1' state2 'current_state2' end EOM - } + end it "the resource updates nothing" do expect(resource.converged).to eq 0 @@ -175,14 +175,14 @@ EOM end context "and identity1 and control1 are set to new values" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do identity1 'new_identity1' control1 'new_control1' end EOM - } + end # Because the identity value is copied over to the new resource, by # default they do not register as "changed" @@ -205,14 +205,14 @@ EOM end context "and identity1 and control1 are set to new values" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do identity1 'new_identity1' control1 'new_control1' end EOM - } + end # Control values are not desired state and are therefore not considered # a reason for converging. @@ -252,14 +252,14 @@ EOM end context "and state1 and state2 are set" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do state1 'new_state1' state2 'new_state2' end EOM - } + end it "the resource is created" do expect(resource.converged).to eq 1 @@ -275,7 +275,7 @@ EOM end context "and state1 and state2 are set with sensitive property" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do sensitive true @@ -283,7 +283,7 @@ EOM state2 'new_state2' end EOM - } + end it "the resource is created" do expect(resource.converged).to eq 1 @@ -334,13 +334,13 @@ EOM context "and state1 is set to a new value" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do state1 'new_state1' end EOM - } + end it "the resource updates state1" do expect(resource.converged).to eq 1 @@ -354,14 +354,14 @@ EOM end context "and state1 and state2 are set to new values" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do state1 'new_state1' state2 'new_state2' end EOM - } + end it "the resource updates state1 and state2" do expect(resource.converged).to eq 2 @@ -377,14 +377,14 @@ EOM end context "and state1 is set to its current value but state2 is set to a new value" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do state1 'current_state1' state2 'new_state2' end EOM - } + end it "the resource updates state2" do expect(resource.converged).to eq 1 @@ -398,14 +398,14 @@ EOM end context "and state1 and state2 are set to their current values" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do state1 'current_state1' state2 'current_state2' end EOM - } + end it "the resource updates nothing" do expect(resource.converged).to eq 0 @@ -425,9 +425,9 @@ EOM end context "and nothing is set" do - let(:converge_recipe) { + let(:converge_recipe) do "#{resource_name} 'blah'" - } + end it "the resource is created" do expect(resource.converged).to eq 2 @@ -443,14 +443,14 @@ EOM end context "and state1 and state2 are set to new values" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do state1 'new_state1' state2 'new_state2' end EOM - } + end it "the resource is created" do expect(resource.converged).to eq 2 @@ -466,7 +466,7 @@ EOM end context "and state1 and state2 are set to new sensitive values" do - let(:converge_recipe) { + let(:converge_recipe) do <<-EOM #{resource_name} 'blah' do sensitive true @@ -474,7 +474,7 @@ EOM state2 'new_state2' end EOM - } + end it "the resource is created" do expect(resource.converged).to eq 2 diff --git a/spec/integration/recipes/resource_load_spec.rb b/spec/integration/recipes/resource_load_spec.rb index 53ce1c91b3..954fbf53a4 100644 --- a/spec/integration/recipes/resource_load_spec.rb +++ b/spec/integration/recipes/resource_load_spec.rb @@ -18,7 +18,7 @@ describe "Resource.load_current_value" do before { Namer.incrementing_value = 0 } let(:resource_name) { :"load_current_value_dsl#{Namer.current_index}" } - let(:resource_class) { + let(:resource_class) do result = Class.new(Chef::Resource) do def self.to_s; resource_name.to_s; end @@ -37,7 +37,7 @@ describe "Resource.load_current_value" do end result.resource_name resource_name result - } + end # Pull on resource_class to initialize it before { resource_class } @@ -56,11 +56,11 @@ describe "Resource.load_current_value" do let(:resource) do e = self r = nil - converge { + converge do r = public_send(e.resource_name, "blah") do x "desired" end - } + end r end @@ -83,17 +83,17 @@ describe "Resource.load_current_value" do end context "and identity: :i and :d with desired_state: false" do - before { + before do resource_class.class_eval do property :i, identity: true property :d, desired_state: false end - } + end - before { + before do resource.i "desired_i" resource.d "desired_d" - } + end it "i, name and d are passed to load_current_value, but not x" do expect(resource.current_value.x).to eq "loaded 2 (d=desired_d, i=desired_i, name=blah)" @@ -101,17 +101,17 @@ describe "Resource.load_current_value" do end context "and name_property: :i and :d with desired_state: false" do - before { + before do resource_class.class_eval do property :i, name_property: true property :d, desired_state: false end - } + end - before { + before do resource.i "desired_i" resource.d "desired_d" - } + end it "i, name and d are passed to load_current_value, but not x" do expect(resource.current_value.x).to eq "loaded 2 (d=desired_d, i=desired_i, name=blah)" @@ -123,10 +123,10 @@ describe "Resource.load_current_value" do let(:resource) do e = self r = nil - converge { + converge do r = public_send(e.resource_name, "blah") do end - } + end r end @@ -135,16 +135,16 @@ describe "Resource.load_current_value" do end end - let (:subresource_name) { + let (:subresource_name) do :"load_current_value_subresource_dsl#{Namer.current_index}" - } - let (:subresource_class) { + end + let (:subresource_class) do r = Class.new(resource_class) do property :y, default: lazy { "default_y #{Namer.incrementing_value}" } end r.resource_name subresource_name r - } + end # Pull on subresource_class to initialize it before { subresource_class } @@ -152,11 +152,11 @@ describe "Resource.load_current_value" do let(:subresource) do e = self r = nil - converge { + converge do r = public_send(e.subresource_name, "blah") do x "desired" end - } + end r end @@ -170,14 +170,14 @@ describe "Resource.load_current_value" do end context "And a child resource class with load_current_value" do - before { + before do subresource_class.load_current_value do y "loaded_y #{Namer.incrementing_value} (#{self.class.properties.sort_by { |name, p| name }. select { |name, p| p.is_set?(self) }. map { |name, p| "#{name}=#{p.get(self)}" }. join(", ") })" end - } + end it "the overridden load_current_value is used" do current_resource = subresource.current_value @@ -187,7 +187,7 @@ describe "Resource.load_current_value" do end context "and a child resource class with load_current_value calling super()" do - before { + before do subresource_class.load_current_value do super() y "loaded_y #{Namer.incrementing_value} (#{self.class.properties.sort_by { |name, p| name }. @@ -195,7 +195,7 @@ describe "Resource.load_current_value" do map { |name, p| "#{name}=#{p.get(self)}" }. join(", ") })" end - } + end it "the original load_current_value is called as well as the child one" do current_resource = subresource.current_value diff --git a/spec/integration/solo/solo_spec.rb b/spec/integration/solo/solo_spec.rb index f142798546..c4a7ca44ce 100644 --- a/spec/integration/solo/solo_spec.rb +++ b/spec/integration/solo/solo_spec.rb @@ -112,7 +112,11 @@ EOM file "cookbooks/x/recipes/default.rb", <<EOM ruby_block "sleeping" do block do - sleep 10 + retries = 200 + while IO.read(Chef::Config[:log_location]) !~ /Chef client [0-9]+ is running, will wait for it to finish and then run./ + sleep 0.1 + last if ( retries -= 1 ) <= 0 + end end end EOM @@ -125,7 +129,7 @@ file_cache_path "#{path_to('config/cache')}" EOM # We have a timeout protection here so that if due to some bug # run_lock gets stuck we can discover it. - expect { + expect do Timeout.timeout(120) do chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..") @@ -133,9 +137,6 @@ EOM s1 = Process.spawn("#{chef_solo} -c \"#{path_to('config/solo.rb')}\" -o 'x::default' \ -l debug -L #{path_to('logs/runs.log')}", :chdir => chef_dir) - # Give it some time to progress - sleep 5 - # Instantiate the second chef-solo run s2 = Process.spawn("#{chef_solo} -c \"#{path_to('config/solo.rb')}\" -o 'x::default' \ -l debug -L #{path_to('logs/runs.log')}", :chdir => chef_dir) @@ -143,7 +144,7 @@ EOM Process.waitpid(s1) Process.waitpid(s2) end - }.not_to raise_error + end.not_to raise_error # Unfortunately file / directory helpers in integration tests # are implemented using before(:each) so we need to do all below @@ -154,22 +155,7 @@ EOM expect(run_log.lines.reject { |l| !l.include? "INFO: Chef Run complete in" }.length).to eq(2) # second run should have a message which indicates it's waiting for the first run - pid_lines = run_log.lines.reject { |l| !l.include? "Chef-client pid:" } - expect(pid_lines.length).to eq(2) - pids = pid_lines.map { |l| l.split(" ").last } - expect(run_log).to include("Chef client #{pids[0]} is running, will wait for it to finish and then run.") - - # second run should start after first run ends - starts = [ ] - ends = [ ] - run_log.lines.each_with_index do |line, index| - if line.include? "Chef-client pid:" - starts << index - elsif line.include? "INFO: Chef Run complete in" - ends << index - end - end - expect(starts[1]).to be > ends[0] + expect(run_log).to match(/Chef client [0-9]+ is running, will wait for it to finish and then run./) end end diff --git a/spec/scripts/ssl-serve.rb b/spec/scripts/ssl-serve.rb index c05aa2c285..3f4e343926 100644 --- a/spec/scripts/ssl-serve.rb +++ b/spec/scripts/ssl-serve.rb @@ -42,6 +42,6 @@ webrick_opts = DEFAULT_OPTIONS.merge(server_opts) pp :webrick_opts => webrick_opts server = WEBrick::HTTPServer.new(webrick_opts) -trap "INT" do server.shutdown end +trap("INT") { server.shutdown } server.start diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2f6747c9af..ba44f7c3f7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -66,6 +66,8 @@ require "chef/util/file_edit" require "chef/config" +require "chef/chef_fs/file_system_cache" + if ENV["CHEF_FIPS"] == "1" Chef::Config.init_openssl end @@ -200,6 +202,8 @@ RSpec.configure do |config| config.before(:each) do Chef.reset! + Chef::ChefFS::FileSystemCache.instance.reset! + Chef::Config.reset # By default, treat deprecation warnings as errors in tests. @@ -220,6 +224,7 @@ RSpec.configure do |config| end require "webrick/utils" +require "thread" # Webrick uses a centralized/synchronized timeout manager. It works by # starting a thread to check for timeouts on an interval. The timeout @@ -238,7 +243,12 @@ module WEBrick module Utils class TimeoutHandler def initialize - @timeout_info = Hash.new + end + + def register(*args) + end + + def cancel(*args) end end end diff --git a/spec/stress/win32/security_spec.rb b/spec/stress/win32/security_spec.rb index 58cf7b3357..3c03a657b2 100644 --- a/spec/stress/win32/security_spec.rb +++ b/spec/stress/win32/security_spec.rb @@ -49,21 +49,21 @@ describe "Chef::ReservedNames::Win32::Security", :windows_only do end it "should not leak when retrieving and reading the ACE from a file", :volatile do - expect { + expect do sids = Chef::ReservedNames::Win32::Security::SecurableObject.new(@monkeyfoo).security_descriptor.dacl.select { |ace| ace.sid } GC.start - }.not_to leak_memory(:warmup => 50, :iterations => 100) + end.not_to leak_memory(:warmup => 50, :iterations => 100) end it "should not leak when creating a new ACL and setting it on a file", :volatile do securable_object = Security::SecurableObject.new(@monkeyfoo) - expect { + expect do securable_object.dacl = Chef::ReservedNames::Win32::Security::ACL.create([ Chef::ReservedNames::Win32::Security::ACE.access_allowed(Chef::ReservedNames::Win32::Security::SID.Everyone, Chef::ReservedNames::Win32::API::Security::GENERIC_READ), Chef::ReservedNames::Win32::Security::ACE.access_denied(Chef::ReservedNames::Win32::Security::SID.from_account("Users"), Chef::ReservedNames::Win32::API::Security::GENERIC_ALL), ]) GC.start - }.not_to leak_memory(:warmup => 50, :iterations => 100) + end.not_to leak_memory(:warmup => 50, :iterations => 100) end end diff --git a/spec/support/chef_helpers.rb b/spec/support/chef_helpers.rb index f64c14da4d..d0b5ad0bfd 100644 --- a/spec/support/chef_helpers.rb +++ b/spec/support/chef_helpers.rb @@ -84,6 +84,28 @@ def canonicalize_path(path) windows? ? path.tr("/", '\\') : path end +# Makes a temp directory with a canonical path on any platform. +# Only really needed to work around an issue on Windows where +# Ruby's temp library generates paths with short names. +def make_canonical_temp_directory + temp_directory = Dir.mktmpdir + if windows? + # On Windows, temporary file / directory path names may have shortened + # subdirectory names due to reliance on the TMP and TEMP environment variables + # in some Windows APIs and duplicated logic in Ruby's temp file implementation. + # To work around this in the unit test context, we obtain the long (canonical) + # path name via a Windows system call so that this path name can be used + # in expectations that assume the ability to canonically name paths in comparisons. + # Note that this was not an issue prior to Ruby 2.2 -- with Ruby 2.2, + # some Chef code started to use long file names, while Ruby's temp file implementation + # continued to return the shortened names -- this would cause these particular tests to + # fail if the username happened to be longer than 8 characters. + Chef::ReservedNames::Win32::File.get_long_path_name(temp_directory) + else + temp_directory + end +end + # Check if a cmd exists on the PATH def which(cmd) paths = ENV["PATH"].split(File::PATH_SEPARATOR) + [ "/bin", "/usr/bin", "/sbin", "/usr/sbin" ] diff --git a/spec/support/platform_helpers.rb b/spec/support/platform_helpers.rb index 9ba56a15e3..4b727a18ca 100644 --- a/spec/support/platform_helpers.rb +++ b/spec/support/platform_helpers.rb @@ -169,7 +169,7 @@ def selinux_enabled? when 0 return true else - raise RuntimeError, "Unknown exit code from command #{selinuxenabled_path}: #{cmd.exitstatus}" + raise "Unknown exit code from command #{selinuxenabled_path}: #{cmd.exitstatus}" end else # We assume selinux is not enabled if selinux utils are not diff --git a/spec/support/shared/context/client.rb b/spec/support/shared/context/client.rb index d8676ef168..b0530ab497 100644 --- a/spec/support/shared/context/client.rb +++ b/spec/support/shared/context/client.rb @@ -230,8 +230,9 @@ shared_context "audit phase failed with error" do end shared_context "audit phase completed with failed controls" do - let(:audit_runner) { instance_double("Chef::Audit::Runner", :failed? => true, - :num_failed => 1, :num_total => 3) } + let(:audit_runner) do + instance_double("Chef::Audit::Runner", :failed? => true, + :num_failed => 1, :num_total => 3) end let(:audit_error) do err = Chef::Exceptions::AuditsFailed.new(audit_runner.num_failed, audit_runner.num_total) diff --git a/spec/support/shared/functional/file_resource.rb b/spec/support/shared/functional/file_resource.rb index bb8db772be..eb7a378db9 100644 --- a/spec/support/shared/functional/file_resource.rb +++ b/spec/support/shared/functional/file_resource.rb @@ -400,9 +400,9 @@ shared_examples_for "a configured file resource" do end context "when the target file is a symlink", :not_supported_on_win2k3 do - let(:symlink_target) { + let(:symlink_target) do File.join(CHEF_SPEC_DATA, "file-test-target") - } + end describe "when configured not to manage symlink's target" do before(:each) do @@ -820,9 +820,9 @@ shared_examples_for "a configured file resource" do end describe "when path is specified with windows separator", :windows_only do - let(:path) { + let(:path) do File.join(test_file_dir, make_tmpname(file_base)).gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR) - } + end before do @notified_resource = Chef::Resource.new("punk", resource.run_context) @@ -1035,6 +1035,7 @@ shared_context Chef::Resource::File do end before do + FileUtils.rm_rf(test_file_dir) FileUtils.mkdir_p(test_file_dir) end diff --git a/spec/support/shared/functional/http.rb b/spec/support/shared/functional/http.rb index 7e9e3f34c5..76faaaed47 100644 --- a/spec/support/shared/functional/http.rb +++ b/spec/support/shared/functional/http.rb @@ -52,27 +52,27 @@ module ChefHTTPShared # just a normal file # (expected_content should be uncompressed) - @api.get("/nyan_cat.png", 200) { + @api.get("/nyan_cat.png", 200) do File.open(nyan_uncompressed_filename, "rb") do |f| f.read end - } + end # this ends in .gz, we do not uncompress it and drop it on the filesystem as a .gz file (the internet often lies) # (expected_content should be compressed) - @api.get("/nyan_cat.png.gz", 200, nil, { "Content-Type" => "application/gzip", "Content-Encoding" => "gzip" } ) { + @api.get("/nyan_cat.png.gz", 200, nil, { "Content-Type" => "application/gzip", "Content-Encoding" => "gzip" } ) do File.open(nyan_compressed_filename, "rb") do |f| f.read end - } + end # this is an uncompressed file that was compressed by some mod_gzip-ish webserver thingy, so we will expand it # (expected_content should be uncompressed) - @api.get("/nyan_cat_compressed.png", 200, nil, { "Content-Type" => "application/gzip", "Content-Encoding" => "gzip" } ) { + @api.get("/nyan_cat_compressed.png", 200, nil, { "Content-Type" => "application/gzip", "Content-Encoding" => "gzip" } ) do File.open(nyan_compressed_filename, "rb") do |f| f.read end - } + end # # endpoints that set Content-Length correctly @@ -83,11 +83,11 @@ module ChefHTTPShared { "Content-Length" => nyan_uncompressed_size.to_s, } - ) { + ) do File.open(nyan_uncompressed_filename, "rb") do |f| f.read end - } + end # (expected_content should be uncompressed) @api.get("/nyan_cat_content_length_compressed.png", 200, nil, @@ -96,11 +96,11 @@ module ChefHTTPShared "Content-Type" => "application/gzip", "Content-Encoding" => "gzip", } - ) { + ) do File.open(nyan_compressed_filename, "rb") do |f| f.read end - } + end # # endpoints that simulate truncated downloads (bad content-length header) @@ -111,11 +111,11 @@ module ChefHTTPShared { "Content-Length" => (nyan_uncompressed_size + 1).to_s, } - ) { + ) do File.open(nyan_uncompressed_filename, "rb") do |f| f.read end - } + end # (expected_content should be uncompressed) @api.get("/nyan_cat_truncated_compressed.png", 200, nil, @@ -124,11 +124,11 @@ module ChefHTTPShared "Content-Type" => "application/gzip", "Content-Encoding" => "gzip", } - ) { + ) do File.open(nyan_compressed_filename, "rb") do |f| f.read end - } + end # # in the presence of a transfer-encoding header, we must ignore the content-length (this bad content-length should work) @@ -140,11 +140,11 @@ module ChefHTTPShared "Content-Length" => (nyan_uncompressed_size + 1).to_s, "Transfer-Encoding" => "anything", } - ) { + ) do File.open(nyan_uncompressed_filename, "rb") do |f| f.read end - } + end # # 403 with a Content-Length diff --git a/spec/support/shared/functional/securable_resource.rb b/spec/support/shared/functional/securable_resource.rb index 506b96736c..95f4f4bd49 100644 --- a/spec/support/shared/functional/securable_resource.rb +++ b/spec/support/shared/functional/securable_resource.rb @@ -81,7 +81,7 @@ shared_context "use Windows permissions", :windows_only do SID ||= Chef::ReservedNames::Win32::Security::SID ACE ||= Chef::ReservedNames::Win32::Security::ACE ACL ||= Chef::ReservedNames::Win32::Security::ACL - SecurableObject ||= Chef::ReservedNames::Win32::Security::SecurableObject + SecurableObject ||= Chef::ReservedNames::Win32::Security::SecurableObject # rubocop:disable Style/ConstantName end def get_security_descriptor(path) @@ -138,9 +138,9 @@ shared_context "use Windows permissions", :windows_only do RSpec::Matchers.define :have_expected_properties do |mask, type, flags| match do |ace| - ace.mask == mask - ace.type == type - ace.flags == flags + ace.mask == mask && + ace.type == type && + ace.flags == flags end end @@ -439,7 +439,7 @@ shared_examples_for "a securable resource without existing target" do context "with a mode attribute" do if windows? - Security ||= Chef::ReservedNames::Win32::API::Security + Security ||= Chef::ReservedNames::Win32::API::Security # rubocop:disable Style/ConstantName end it "respects mode in string form as an octal number" do diff --git a/spec/support/shared/functional/win32_service.rb b/spec/support/shared/functional/win32_service.rb index 0f9072bdef..3199caa34f 100644 --- a/spec/support/shared/functional/win32_service.rb +++ b/spec/support/shared/functional/win32_service.rb @@ -23,9 +23,7 @@ shared_context "using Win32::Service" do # We can only uninstall when the service is stopped. if test_service_state != "stopped" ::Win32::Service.send("stop", "spec-service") - while test_service_state != "stopped" - sleep 1 - end + sleep 1 while test_service_state != "stopped" end ::Win32::Service.delete("spec-service") @@ -39,7 +37,7 @@ shared_context "using Win32::Service" do # Definition for the test-service - let(:test_service) { + let(:test_service) do { :service_name => "spec-service", :service_display_name => "Spec Test Service", @@ -47,13 +45,13 @@ shared_context "using Win32::Service" do :service_file_path => File.expand_path(File.join(File.dirname(__FILE__), "../../platforms/win32/spec_service.rb")), :delayed_start => true, } - } + end # Test service creates a file for us to verify that it is running. # Since our test service is running as Local System we should look # for the file it creates under SYSTEM temp directory - let(:test_service_file) { + let(:test_service_file) do "#{ENV['SystemDrive']}\\windows\\temp\\spec_service_file" - } + end end diff --git a/spec/support/shared/integration/app_server_support.rb b/spec/support/shared/integration/app_server_support.rb index 9bc48dbd93..4dfa3fa155 100644 --- a/spec/support/shared/integration/app_server_support.rb +++ b/spec/support/shared/integration/app_server_support.rb @@ -33,9 +33,7 @@ module AppServerSupport end end Timeout.timeout(30) do - until server && server.status == :Running - sleep(0.01) - end + sleep(0.01) until server && server.status == :Running end [server, thread] end diff --git a/spec/support/shared/integration/knife_support.rb b/spec/support/shared/integration/knife_support.rb index 398d90dff0..1a374e1b84 100644 --- a/spec/support/shared/integration/knife_support.rb +++ b/spec/support/shared/integration/knife_support.rb @@ -20,6 +20,7 @@ require "chef/knife" require "chef/application/knife" require "logger" require "chef/log" +require "chef/chef_fs/file_system_cache" module KnifeSupport DEBUG = ENV["DEBUG"] @@ -70,6 +71,9 @@ module KnifeSupport Chef::Config[:verbosity] = ( DEBUG ? 2 : 0 ) instance.config[:config_file] = File.join(CHEF_SPEC_DATA, "null_config.rb") + # Ensure the ChefFS cache is empty + Chef::ChefFS::FileSystemCache.instance.reset! + # Configure chef with a (mostly) blank knife.rb # We set a global and then mutate it in our stub knife.rb so we can be # extra sure that we're not loading someone's real knife.rb and then @@ -107,8 +111,6 @@ module KnifeSupport end end - private - class KnifeResult include ::RSpec::Matchers diff --git a/spec/support/shared/shared_examples.rb b/spec/support/shared/shared_examples.rb index 550fa2eb68..0c031bbafd 100644 --- a/spec/support/shared/shared_examples.rb +++ b/spec/support/shared/shared_examples.rb @@ -3,9 +3,9 @@ # Any object which defines a .to_json should import this test shared_examples "to_json equivalent to Chef::JSONCompat.to_json" do - let(:jsonable) { + let(:jsonable) do raise "You must define the subject when including this test" - } + end it "should allow consumers to call #to_json or Chef::JSONCompat.to_json" do expect(jsonable.to_json).to eq(Chef::JSONCompat.to_json(jsonable)) diff --git a/spec/support/shared/unit/api_versioning.rb b/spec/support/shared/unit/api_versioning.rb index b61469a2d0..28141b73b1 100644 --- a/spec/support/shared/unit/api_versioning.rb +++ b/spec/support/shared/unit/api_versioning.rb @@ -43,13 +43,13 @@ shared_examples_for "user and client reregister" do let(:generic_exception) { Exception.new } let(:min_version) { "2" } let(:max_version) { "5" } - let(:return_hash_406) { + let(:return_hash_406) do { "min_version" => min_version, "max_version" => max_version, "request_version" => "30", } - } + end context "when V0 is not supported by the server" do context "when the exception is 406 and returns x-ops-server-api-version header" do diff --git a/spec/support/shared/unit/application_dot_d.rb b/spec/support/shared/unit/application_dot_d.rb index a8769d6d03..da4eb88edd 100644 --- a/spec/support/shared/unit/application_dot_d.rb +++ b/spec/support/shared/unit/application_dot_d.rb @@ -31,8 +31,9 @@ shared_examples_for "an application that loads a dot d" do context "when client_d_dir is set to a directory with configuration" do # We're not going to mock out globbing the directory. We want to # make sure that we are correctly globbing. - let(:client_d_dir) { Chef::Util::PathHelper.cleanpath( - File.join(File.dirname(__FILE__), "../../../data/client.d_00")) } + let(:client_d_dir) do + Chef::Util::PathHelper.cleanpath( + File.join(File.dirname(__FILE__), "../../../data/client.d_00")) end it "loads the configuration in order" do expect(IO).to receive(:read).with(Pathname.new("#{client_d_dir}/00-foo.rb").cleanpath.to_s).and_return("foo 0") @@ -45,8 +46,9 @@ shared_examples_for "an application that loads a dot d" do end context "when client_d_dir is set to a directory without configuration" do - let(:client_d_dir) { Chef::Util::PathHelper.cleanpath( - File.join(File.dirname(__FILE__), "../../data/client.d_01")) } + let(:client_d_dir) do + Chef::Util::PathHelper.cleanpath( + File.join(File.dirname(__FILE__), "../../data/client.d_01")) end # client.d_01 has a nested folder with a rb file that if # executed, would raise an exception. If it is executed, @@ -60,8 +62,9 @@ shared_examples_for "an application that loads a dot d" do context "when client_d_dir is set to a directory containing a directory named foo.rb" do # foo.rb as a directory should be ignored - let(:client_d_dir) { Chef::Util::PathHelper.cleanpath( - File.join(File.dirname(__FILE__), "../../data/client.d_02")) } + let(:client_d_dir) do + Chef::Util::PathHelper.cleanpath( + File.join(File.dirname(__FILE__), "../../data/client.d_02")) end it "does not raise an exception" do expect { app.reconfigure }.not_to raise_error diff --git a/spec/support/shared/unit/provider/file.rb b/spec/support/shared/unit/provider/file.rb index cb539ffbc3..394fdaa02f 100644 --- a/spec/support/shared/unit/provider/file.rb +++ b/spec/support/shared/unit/provider/file.rb @@ -459,11 +459,11 @@ shared_examples_for Chef::Provider::File do context "do_validate_content" do before { setup_normal_file } - let(:tempfile) { + let(:tempfile) do t = double("Tempfile", :path => "/tmp/foo-bar-baz", :closed? => true) allow(content).to receive(:tempfile).and_return(t) t - } + end context "with user-supplied verifications" do it "calls #verify on each verification with tempfile path" do diff --git a/spec/support/shared/unit/provider/useradd_based_user_provider.rb b/spec/support/shared/unit/provider/useradd_based_user_provider.rb index 6677a069ea..de851c4ad4 100644 --- a/spec/support/shared/unit/provider/useradd_based_user_provider.rb +++ b/spec/support/shared/unit/provider/useradd_based_user_provider.rb @@ -18,13 +18,18 @@ # limitations under the License. # +# XXX: this used to be shared by solaris and linux classes, but at some +# point became linux-specific. it is now a misnomer to call these 'shared' +# examples and they should either realy get turned into shared examples or +# should be copypasta'd back directly into the linux tests. + shared_examples_for "a useradd-based user provider" do |supported_useradd_options| before(:each) do @node = Chef::Node.new @events = Chef::EventDispatch::Dispatcher.new @run_context = Chef::RunContext.new(@node, {}, @events) - @new_resource = Chef::Resource::User.new("adam", @run_context) + @new_resource = Chef::Resource::User::LinuxUser.new("adam", @run_context) @new_resource.comment "Adam Jacob" @new_resource.uid 1000 @new_resource.gid 1000 @@ -35,7 +40,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option @new_resource.manage_home false @new_resource.force false @new_resource.non_unique false - @current_resource = Chef::Resource::User.new("adam", @run_context) + @current_resource = Chef::Resource::User::LinuxUser.new("adam", @run_context) @current_resource.comment "Adam Jacob" @current_resource.uid 1000 @current_resource.gid 1000 @@ -46,7 +51,6 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option @current_resource.manage_home false @current_resource.force false @current_resource.non_unique false - @current_resource.supports({ :manage_home => false, :non_unique => false }) end describe "when setting option" do @@ -102,9 +106,8 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option describe "when the resource has a different home directory and supports home directory management" do before do - allow(@new_resource).to receive(:home).and_return("/wowaweea") - allow(@new_resource).to receive(:supports).and_return({ :manage_home => true, - :non_unique => false }) + @new_resource.home "/wowaweea" + @new_resource.manage_home true end it "should set -m -d /homedir" do @@ -126,32 +129,20 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option end end - describe "when the resource supports non_unique ids" do - before do - allow(@new_resource).to receive(:supports).and_return({ :manage_home => false, - :non_unique => true }) - end - - it "should set -m -o" do - expect(provider.universal_options).to eql([ "-o" ]) - end + it "when non_unique is false should not set -m" do + @new_resource.non_unique false + expect(provider.universal_options).to eql([ ]) end - describe "when the resource supports non_unique ids (using real attributes)" do - before do - allow(@new_resource).to receive(:manage_home).and_return(false) - allow(@new_resource).to receive(:non_unique).and_return(true) - end - - it "should set -m -o" do - expect(provider.universal_options).to eql([ "-o" ]) - end + it "when non_unique is true should set -o" do + @new_resource.non_unique true + expect(provider.universal_options).to eql([ "-o" ]) end end describe "when creating a user" do before(:each) do - @current_resource = Chef::Resource::User.new(@new_resource.name, @run_context) + @current_resource = Chef::Resource::User::LinuxUser.new(@new_resource.name, @run_context) @current_resource.username(@new_resource.username) provider.current_resource = @current_resource provider.new_resource.manage_home true @@ -246,15 +237,12 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option end it "should run userdel with the new resources user name and -r if manage_home is true" do - @new_resource.supports({ :manage_home => true, - :non_unique => false }) + @new_resource.manage_home true expect(provider).to receive(:shell_out!).with("userdel", "-r", @new_resource.username).and_return(true) provider.remove_user end it "should run userdel with the new resources user name if non_unique is true" do - @new_resource.supports({ :manage_home => false, - :non_unique => true }) expect(provider).to receive(:shell_out!).with("userdel", @new_resource.username).and_return(true) provider.remove_user end @@ -420,9 +408,9 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option end end it "should return true if the current home does not exist but a home is specified by the new resource" do - @new_resource = Chef::Resource::User.new("adam", @run_context) - @current_resource = Chef::Resource::User.new("adam", @run_context) - provider = Chef::Provider::User::Useradd.new(@new_resource, @run_context) + @new_resource = Chef::Resource::User::LinuxUser.new("adam", @run_context) + @current_resource = Chef::Resource::User::LinuxUser.new("adam", @run_context) + provider = Chef::Provider::User::Linux.new(@new_resource, @run_context) provider.current_resource = @current_resource @current_resource.home nil @new_resource.home "/home/kitten" diff --git a/spec/support/shared/unit/resource/static_provider_resolution.rb b/spec/support/shared/unit/resource/static_provider_resolution.rb index 4ae5d4576f..e68b805d7d 100644 --- a/spec/support/shared/unit/resource/static_provider_resolution.rb +++ b/spec/support/shared/unit/resource/static_provider_resolution.rb @@ -33,13 +33,13 @@ def static_provider_resolution(opts = {}) platform_version = opts[:platform_version] describe resource_class, "static provider initialization" do - let(:node) { + let(:node) do node = Chef::Node.new node.automatic_attrs[:os] = os node.automatic_attrs[:platform_family] = platform_family node.automatic_attrs[:platform_version] = platform_version node - } + end let(:events) { Chef::EventDispatch::Dispatcher.new } let(:run_context) { Chef::RunContext.new(node, {}, events) } let(:resource) { resource_class.new("foo", run_context) } diff --git a/spec/support/shared/unit/script_resource.rb b/spec/support/shared/unit/script_resource.rb index 732b07d4ef..27864e1625 100644 --- a/spec/support/shared/unit/script_resource.rb +++ b/spec/support/shared/unit/script_resource.rb @@ -57,18 +57,18 @@ shared_examples_for "a script resource" do end describe "when executing guards" do - let(:resource) { + let(:resource) do resource = script_resource resource.run_context = run_context resource.code "echo hi" resource - } - let(:node) { + end + let(:node) do node = Chef::Node.new node.automatic[:platform] = "debian" node.automatic[:platform_version] = "6.0" node - } + end let(:events) { Chef::EventDispatch::Dispatcher.new } let(:run_context) { Chef::RunContext.new(node, {}, events) } diff --git a/spec/support/shared/unit/user_and_client_shared.rb b/spec/support/shared/unit/user_and_client_shared.rb index e3481dfeca..6c31ca22d1 100644 --- a/spec/support/shared/unit/user_and_client_shared.rb +++ b/spec/support/shared/unit/user_and_client_shared.rb @@ -55,13 +55,13 @@ shared_examples_for "user or client create" do end context "when chef_key is returned by the server" do - let(:chef_key) { + let(:chef_key) do { "chef_key" => { "public_key" => "some_public_key", }, } - } + end it "puts the public key into the objectr returned by create" do expect(rest_v1).to receive(:post).with(url, payload).and_return(payload.merge(chef_key)) @@ -70,14 +70,14 @@ shared_examples_for "user or client create" do end context "when private_key is returned in chef_key" do - let(:chef_key) { + let(:chef_key) do { "chef_key" => { "public_key" => "some_public_key", "private_key" => "some_private_key", }, } - } + end it "puts the private key into the object returned by create" do expect(rest_v1).to receive(:post).with(url, payload).and_return(payload.merge(chef_key)) diff --git a/spec/tiny_server.rb b/spec/tiny_server.rb index a3711e4dbd..83c5bf4a42 100644 --- a/spec/tiny_server.rb +++ b/spec/tiny_server.rb @@ -20,97 +20,82 @@ require "rubygems" require "webrick" require "webrick/https" require "rack" -#require 'thin' +require "thread" require "singleton" require "open-uri" require "chef/config" module TinyServer - class Server < Rack::Server - - attr_writer :app - - def self.setup(options = nil, &block) - tiny_app = new(options) - app_code = Rack::Builder.new(&block).to_app - tiny_app.app = app_code - tiny_app - end - - def shutdown - server.shutdown - end - end - class Manager # 5 == debug, 3 == warning LOGGER = WEBrick::Log.new(STDOUT, 3) DEFAULT_OPTIONS = { - :server => "webrick", - :Port => 9000, - :Host => "localhost", - :environment => :none, - :Logger => LOGGER, - :AccessLog => [] # Remove this option to enable the access log when debugging. + Port: 9000, + Host: "localhost", + Logger: LOGGER, + # SSLEnable: options[:ssl], + # SSLCertName: [ [ 'CN', WEBrick::Utils::getservername ] ], + AccessLog: [], # Remove this option to enable the access log when debugging. } - def initialize(options = nil) - @options = options ? DEFAULT_OPTIONS.merge(options) : DEFAULT_OPTIONS + def initialize(**options) + @options = DEFAULT_OPTIONS.merge(options) @creator = caller.first end - def start + attr_reader :options + attr_reader :creator + attr_reader :server + + def start(timeout = 5) + raise "Server already started!" if server + + # Create the server (but don't start yet) + start_queue = Queue.new + @server = create_server(StartCallback: proc { start_queue << true }) + @server_thread = Thread.new do - @server = Server.setup(@options) do - run API.instance - end - @old_handler = trap(:INT, "EXIT") - @server.start + # Ensure any exceptions will cause the main rspec thread to fail too + Thread.current.abort_on_exception = true + server.start end - block_until_started - trap(:INT, @old_handler) - end - def url - "http://localhost:#{@options[:Port]}" + # Wait for the StartCallback to tell us we've started + Timeout.timeout(timeout) do + start_queue.pop + end end - def block_until_started - 200.times do - if started? && !@server.nil? - return true + def stop(timeout = 5) + if server + server.shutdown + @server = nil + end + + if server_thread + begin + # Wait for a normal shutdown + server_thread.join(timeout) + rescue + # If it wouldn't shut down normally, kill it. + server_thread.kill + server_thread.join(timeout) end + @server_thread = nil end - raise "ivar weirdness" if started? && @server.nil? - raise "TinyServer failed to boot :/" - end - - def started? - open(url) - true - rescue OpenURI::HTTPError - true - rescue Errno::ECONNREFUSED, EOFError, Errno::ECONNRESET => e - sleep 0.1 - true - # If the host has ":::1 localhost" in its hosts file and if IPv6 - # is not enabled we can get NetworkUnreachable exception... - rescue Errno::ENETUNREACH, Net::ReadTimeout, IO::EAGAINWaitReadable, - Errno::EHOSTUNREACH => e - sleep 0.1 - false - end - - def stop - # yes, this is terrible. - @server.shutdown - @server_thread.kill - @server_thread.join - @server_thread = nil end + private + + attr_reader :server_thread + + def create_server(**extra_options) + server = WEBrick::HTTPServer.new(**options, **extra_options) + server.mount("/", Rack::Handler::WEBrick, API.instance) + server + end end class API diff --git a/spec/unit/api_client_v1_spec.rb b/spec/unit/api_client_v1_spec.rb index 8c90d5ad38..9c643fa492 100644 --- a/spec/unit/api_client_v1_spec.rb +++ b/spec/unit/api_client_v1_spec.rb @@ -326,13 +326,13 @@ describe Chef::ApiClientV1 do describe "Versioned API Interactions" do let(:response_406) { OpenStruct.new(:code => "406") } let(:exception_406) { Net::HTTPServerException.new("406 Not Acceptable", response_406) } - let(:payload) { + let(:payload) do { :name => "some_name", :validator => true, :admin => true, } - } + end before do @client = Chef::ApiClientV1.new diff --git a/spec/unit/application/client_spec.rb b/spec/unit/application/client_spec.rb index 6765ca93ae..30fc58b84c 100644 --- a/spec/unit/application/client_spec.rb +++ b/spec/unit/application/client_spec.rb @@ -74,6 +74,8 @@ describe Chef::Application::Client, "reconfigure" do end before do + Chef::Config.reset + allow(Kernel).to receive(:trap).and_return(:ok) allow(::File).to receive(:read).and_call_original allow(::File).to receive(:read).with(Chef::Config.platform_specific_path("/etc/chef/client.rb")).and_return("") @@ -141,6 +143,39 @@ describe Chef::Application::Client, "reconfigure" do :daemonize => true end end + + describe "--config-option" do + context "with a single value" do + it_behaves_like "sets the configuration", "--config-option chef_server_url=http://example", + :chef_server_url => "http://example" + end + + context "with two values" do + it_behaves_like "sets the configuration", "--config-option chef_server_url=http://example --config-option policy_name=web", + :chef_server_url => "http://example", :policy_name => "web" + end + + context "with a boolean value" do + it_behaves_like "sets the configuration", "--config-option minimal_ohai=true", + :minimal_ohai => true + end + + context "with an empty value" do + it "should terminate with message" do + expect(Chef::Application).to receive(:fatal!).with('Unparsable config option ""').and_raise("so ded") + ARGV.replace(["--config-option", ""]) + expect { app.reconfigure }.to raise_error "so ded" + end + end + + context "with an invalid value" do + it "should terminate with message" do + expect(Chef::Application).to receive(:fatal!).with('Unparsable config option "asdf"').and_raise("so ded") + ARGV.replace(["--config-option", "asdf"]) + expect { app.reconfigure }.to raise_error "so ded" + end + end + end end describe "when configured to not fork the client process" do diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb index 8ab6e13204..867cd3f9c2 100644 --- a/spec/unit/application_spec.rb +++ b/spec/unit/application_spec.rb @@ -361,7 +361,7 @@ describe Chef::Application do end end - context 'when called with an Array-like argument (#size)' do + context "when called with an Array-like argument (#size)" do before do allow(app).to receive(:fork_chef_client).and_return(true) allow(app).to receive(:run_with_graceful_exit_option).and_return(true) diff --git a/spec/unit/audit/audit_event_proxy_spec.rb b/spec/unit/audit/audit_event_proxy_spec.rb index 2496aef3e7..820e670f1c 100644 --- a/spec/unit/audit/audit_event_proxy_spec.rb +++ b/spec/unit/audit/audit_event_proxy_spec.rb @@ -34,8 +34,9 @@ describe Chef::Audit::AuditEventProxy do describe "#example_group_started" do let(:description) { "poots" } - let(:group) { double("ExampleGroup", :parent_groups => parents, - :description => description) } + let(:group) do + double("ExampleGroup", :parent_groups => parents, + :description => description) end let(:notification) { double("Notification", :group => group) } context "when notified from a top-level example group" do @@ -120,35 +121,36 @@ describe Chef::Audit::AuditEventProxy do let(:examples) { [example] } - let(:example) { double("Example", :metadata => metadata, - :description => example_description, - :full_description => full_description, :exception => nil) } + let(:example) do + double("Example", :metadata => metadata, + :description => example_description, + :full_description => full_description, :exception => nil) end - let(:metadata) { + let(:metadata) do { :described_class => described_class, :example_group => example_group, :line_number => line, } - } + end - let(:example_group) { + let(:example_group) do { :description => group_description, :parent_example_group => parent_group, } - } + end - let(:parent_group) { + let(:parent_group) do { :description => control_group_name, :parent_example_group => nil, } - } + end let(:line) { 27 } - let(:control_data) { + let(:control_data) do { :name => example_description, :desc => full_description, @@ -157,7 +159,7 @@ describe Chef::Audit::AuditEventProxy do :context => context, :line_number => line, } - } + end shared_examples "built control" do @@ -218,12 +220,14 @@ describe Chef::Audit::AuditEventProxy do let(:control_group_name) { "application ports" } let(:group_description) { "#{resource_type} #{resource_name}" } let(:example_description) { "should not be listening" } - let(:full_description) { [control_group_name, group_description, - example_description].join(" ") } + let(:full_description) do + [control_group_name, group_description, + example_description].join(" ") end # Metadata fields - let(:described_class) { double("Serverspec::Type::Port", - :class => "Serverspec::Type::Port", :name => resource_name) } + let(:described_class) do + double("Serverspec::Type::Port", + :class => "Serverspec::Type::Port", :name => resource_name) end # Control data fields let(:resource_type) { "Port" } @@ -246,8 +250,9 @@ describe Chef::Audit::AuditEventProxy do let(:control_group_name) { "application ports" } let(:group_description) { "port 111" } let(:example_description) { "is not listening" } - let(:full_description) { [control_group_name, group_description, - example_description].join(" ") } + let(:full_description) do + [control_group_name, group_description, + example_description].join(" ") end # Metadata fields let(:described_class) { nil } @@ -276,27 +281,29 @@ describe Chef::Audit::AuditEventProxy do let(:outer_group_description) { "File \"tmp/audit\"" } let(:group_description) { "#{resource_type} #{resource_name}" } let(:example_description) { "is a file" } - let(:full_description) { [control_group_name, outer_group_description, - group_description, example_description].join(" ") } + let(:full_description) do + [control_group_name, outer_group_description, + group_description, example_description].join(" ") end # Metadata parts - let(:described_class) { double("Serverspec::Type::File", - :class => "Serverspec::Type::File", :name => resource_name) } + let(:described_class) do + double("Serverspec::Type::File", + :class => "Serverspec::Type::File", :name => resource_name) end # Example group parts - let(:parent_group) { + let(:parent_group) do { :description => outer_group_description, :parent_example_group => control_group, } - } + end - let(:control_group) { + let(:control_group) do { :description => control_group_name, :parent_example_group => nil, } - } + end # Control data parts let(:resource_type) { "File" } diff --git a/spec/unit/audit/audit_reporter_spec.rb b/spec/unit/audit/audit_reporter_spec.rb index 1db56a550e..cf916266d8 100644 --- a/spec/unit/audit/audit_reporter_spec.rb +++ b/spec/unit/audit/audit_reporter_spec.rb @@ -28,8 +28,9 @@ describe Chef::Audit::AuditReporter do let(:run_id) { 0 } let(:start_time) { Time.new(2014, 12, 3, 9, 31, 05, "-08:00") } let(:end_time) { Time.new(2014, 12, 3, 9, 36, 14, "-08:00") } - let(:run_status) { instance_double(Chef::RunStatus, :node => node, :run_id => run_id, - :start_time => start_time, :end_time => end_time) } + let(:run_status) do + instance_double(Chef::RunStatus, :node => node, :run_id => run_id, + :start_time => start_time, :end_time => end_time) end describe "#audit_phase_start" do @@ -85,9 +86,10 @@ describe Chef::Audit::AuditReporter do context "when audit phase failed" do - let(:audit_error) { double("AuditError", :class => "Chef::Exceptions::AuditError", - :message => "Audit phase failed with error message: derpderpderp", - :backtrace => ["/path/recipe.rb:57", "/path/library.rb:106"]) } + let(:audit_error) do + double("AuditError", :class => "Chef::Exceptions::AuditError", + :message => "Audit phase failed with error message: derpderpderp", + :backtrace => ["/path/recipe.rb:57", "/path/library.rb:106"]) end before do reporter.instance_variable_set(:@audit_phase_error, audit_error) @@ -233,13 +235,15 @@ EOM let(:audit_data) { Chef::Audit::AuditData.new(node.name, run_id) } let(:run_data) { audit_data.to_hash } - let(:audit_error) { double("AuditError", :class => "Chef::Exceptions::AuditError", - :message => "Audit phase failed with error message: derpderpderp", - :backtrace => ["/path/recipe.rb:57", "/path/library.rb:106"]) } + let(:audit_error) do + double("AuditError", :class => "Chef::Exceptions::AuditError", + :message => "Audit phase failed with error message: derpderpderp", + :backtrace => ["/path/recipe.rb:57", "/path/library.rb:106"]) end - let(:run_error) { double("RunError", :class => "Chef::Exceptions::RunError", - :message => "This error shouldn't be reported.", - :backtrace => ["fix it", "fix it", "fix it"]) } + let(:run_error) do + double("RunError", :class => "Chef::Exceptions::RunError", + :message => "This error shouldn't be reported.", + :backtrace => ["fix it", "fix it", "fix it"]) end before do allow(reporter).to receive(:auditing_enabled?).and_return(true) @@ -276,23 +280,27 @@ EOM shared_context "audit data" do - let(:control_group_foo) { instance_double(Chef::Audit::ControlGroupData, - :metadata => double("foo metadata")) } - let(:control_group_bar) { instance_double(Chef::Audit::ControlGroupData, - :metadata => double("bar metadata")) } + let(:control_group_foo) do + instance_double(Chef::Audit::ControlGroupData, + :metadata => double("foo metadata")) end + let(:control_group_bar) do + instance_double(Chef::Audit::ControlGroupData, + :metadata => double("bar metadata")) end - let(:ordered_control_groups) { + let(:ordered_control_groups) do { "foo" => control_group_foo, "bar" => control_group_bar, } - } + end - let(:audit_data) { instance_double(Chef::Audit::AuditData, - :add_control_group => true) } + let(:audit_data) do + instance_double(Chef::Audit::AuditData, + :add_control_group => true) end - let(:run_context) { instance_double(Chef::RunContext, - :audits => ordered_control_groups) } + let(:run_context) do + instance_double(Chef::RunContext, + :audits => ordered_control_groups) end before do allow(reporter).to receive(:ordered_control_groups).and_return(ordered_control_groups) @@ -340,8 +348,9 @@ EOM include_context "audit data" let(:name) { "bat" } - let(:control_group) { instance_double(Chef::Audit::ControlGroupData, - :metadata => double("metadata")) } + let(:control_group) do + instance_double(Chef::Audit::ControlGroupData, + :metadata => double("metadata")) end before do allow(Chef::Audit::ControlGroupData).to receive(:new). diff --git a/spec/unit/audit/control_group_data_spec.rb b/spec/unit/audit/control_group_data_spec.rb index a7c8850350..ea4ac260f9 100644 --- a/spec/unit/audit/control_group_data_spec.rb +++ b/spec/unit/audit/control_group_data_spec.rb @@ -122,9 +122,10 @@ describe Chef::Audit::ControlData do let(:context) { nil } let(:line_number) { 27 } - let(:control_data) { described_class.new(name: name, - resource_type: resource_type, resource_name: resource_name, - context: context, line_number: line_number) } + let(:control_data) do + described_class.new(name: name, + resource_type: resource_type, resource_name: resource_name, + context: context, line_number: line_number) end describe "#to_hash" do @@ -171,7 +172,7 @@ describe Chef::Audit::ControlGroupData do let(:context) { nil } let(:line_number) { 0 } - let(:control_data) { + let(:control_data) do { :name => name, :resource_type => resource_type, @@ -179,16 +180,17 @@ describe Chef::Audit::ControlGroupData do :context => context, :line_number => line_number, } - } + end end shared_context "control" do include_context "control data" - let(:control) { Chef::Audit::ControlData.new(name: name, - resource_type: resource_type, resource_name: resource_name, - context: context, line_number: line_number) } + let(:control) do + Chef::Audit::ControlData.new(name: name, + resource_type: resource_type, resource_name: resource_name, + context: context, line_number: line_number) end before do allow(Chef::Audit::ControlData).to receive(:new). @@ -436,15 +438,18 @@ describe Chef::Audit::ControlGroupData do let(:control_hash_2) { { :line_number => 13 } } let(:control_hash_3) { { :line_number => 35 } } - let(:control_1) { double("control 1", + let(:control_1) do + double("control 1", :line_number => control_hash_1[:line_number], - :to_hash => control_hash_1) } - let(:control_2) { double("control 2", + :to_hash => control_hash_1) end + let(:control_2) do + double("control 2", :line_number => control_hash_2[:line_number], - :to_hash => control_hash_2) } - let(:control_3) { double("control 3", + :to_hash => control_hash_2) end + let(:control_3) do + double("control 3", :line_number => control_hash_3[:line_number], - :to_hash => control_hash_3) } + :to_hash => control_hash_3) end let(:control_list) { [control_1, control_2, control_3] } let(:ordered_control_hashes) { [control_hash_2, control_hash_1, control_hash_3] } diff --git a/spec/unit/chef_class_spec.rb b/spec/unit/chef_class_spec.rb index 3c8411ef2a..21987c01ab 100644 --- a/spec/unit/chef_class_spec.rb +++ b/spec/unit/chef_class_spec.rb @@ -85,7 +85,7 @@ describe "Chef class" do end end - context '#event_handler' do + context "#event_handler" do it "adds a new handler" do x = 1 Chef.event_handler do diff --git a/spec/unit/chef_fs/data_handler/group_handler_spec.rb b/spec/unit/chef_fs/data_handler/group_handler_spec.rb index 849bc84f92..ac0252162f 100644 --- a/spec/unit/chef_fs/data_handler/group_handler_spec.rb +++ b/spec/unit/chef_fs/data_handler/group_handler_spec.rb @@ -29,7 +29,7 @@ class TestEntry < Mash end describe Chef::ChefFS::DataHandler::GroupDataHandler do - describe '#normalize_for_post' do + describe "#normalize_for_post" do let(:entry) do TestEntry.new("workers.json", "hive") end diff --git a/spec/unit/chef_fs/diff_spec.rb b/spec/unit/chef_fs/diff_spec.rb index c1c9050101..d946fcb9e7 100644 --- a/spec/unit/chef_fs/diff_spec.rb +++ b/spec/unit/chef_fs/diff_spec.rb @@ -32,7 +32,7 @@ describe "diff", :uses_diff => true do include FileSystemSupport context "with two filesystems with all types of difference" do - let(:a) { + let(:a) do memory_fs("a", { :both_dirs => { :sub_both_dirs => { :subsub => nil }, @@ -58,8 +58,8 @@ describe "diff", :uses_diff => true do :dir_in_a_file_in_b => {}, :file_in_a_dir_in_b => nil, }, /cannot_be_in_a/) - } - let(:b) { + end + let(:b) do memory_fs("b", { :both_dirs => { :sub_both_dirs => { :subsub => nil }, @@ -85,7 +85,7 @@ describe "diff", :uses_diff => true do :dir_in_a_file_in_b => nil, :file_in_a_dir_in_b => {}, }, /cannot_be_in_b/) - } + end it "Chef::ChefFS::CommandLine.diff_print(/)" do results = [] Chef::ChefFS::CommandLine.diff_print(pattern("/"), a, b, nil, nil) do |diff| diff --git a/spec/unit/chef_fs/file_system/operation_failed_error_spec.rb b/spec/unit/chef_fs/file_system/operation_failed_error_spec.rb index b0b5a547cd..7f3eb6efe2 100644 --- a/spec/unit/chef_fs/file_system/operation_failed_error_spec.rb +++ b/spec/unit/chef_fs/file_system/operation_failed_error_spec.rb @@ -30,17 +30,17 @@ describe Chef::ChefFS::FileSystem::OperationFailedError do allow(@response).to receive(:code).and_return("400") allow(@response).to receive(:body).and_return(response_body) exception = Net::HTTPServerException.new("(exception) unauthorized", @response) - expect { + expect do raise Chef::ChefFS::FileSystem::OperationFailedError.new(:write, self, exception), error_message - }.to raise_error(Chef::ChefFS::FileSystem::OperationFailedError, "#{error_message} cause: #{response_body}") + end.to raise_error(Chef::ChefFS::FileSystem::OperationFailedError, "#{error_message} cause: #{response_body}") end end context "does not have a cause attribute" do it "does not include error cause" do - expect { + expect do raise Chef::ChefFS::FileSystem::OperationFailedError.new(:write, self), error_message - }.to raise_error(Chef::ChefFS::FileSystem::OperationFailedError, error_message) + end.to raise_error(Chef::ChefFS::FileSystem::OperationFailedError, error_message) end end end diff --git a/spec/unit/chef_fs/file_system/repository/directory_spec.rb b/spec/unit/chef_fs/file_system/repository/directory_spec.rb index e050181be9..6e53e52966 100644 --- a/spec/unit/chef_fs/file_system/repository/directory_spec.rb +++ b/spec/unit/chef_fs/file_system/repository/directory_spec.rb @@ -76,6 +76,7 @@ describe Chef::ChefFS::FileSystem::Repository::Directory do context "#create_child" do it "creates a new TestFile" do expect(TestFile).to receive(:new).with("test_child", test_directory).and_return(file_double) + allow(file_double).to receive(:file_path).and_return("#{test_directory}/test_child") expect(file_double).to receive(:write).with("test") test_directory.create_child("test_child", "test") end diff --git a/spec/unit/chef_fs/file_system_spec.rb b/spec/unit/chef_fs/file_system_spec.rb index 429e039dda..5c74729557 100644 --- a/spec/unit/chef_fs/file_system_spec.rb +++ b/spec/unit/chef_fs/file_system_spec.rb @@ -55,7 +55,7 @@ describe Chef::ChefFS::FileSystem do end context "with a populated filesystem" do - let(:fs) { + let(:fs) do memory_fs("", { :a => { :aa => { @@ -69,7 +69,7 @@ describe Chef::ChefFS::FileSystem do :x => "", :y => {}, }) - } + end context "list" do it "/**" do list_should_yield_paths(fs, "/**", "/", "/a", "/x", "/y", "/a/aa", "/a/aa/c", "/a/aa/zz", "/a/ab", "/a/ab/c") diff --git a/spec/unit/chef_fs/parallelizer.rb b/spec/unit/chef_fs/parallelizer.rb index 9de8077677..84637f7283 100644 --- a/spec/unit/chef_fs/parallelizer.rb +++ b/spec/unit/chef_fs/parallelizer.rb @@ -35,9 +35,9 @@ describe Chef::ChefFS::Parallelizer do context "With :ordered => false (unordered output)" do it "An empty input produces an empty output" do - parallelize([], :ordered => false) do + expect(parallelize([], :ordered => false) do sleep 10 - end.to_a == [] + end.to_a).to eql([]) expect(elapsed_time).to be < 0.1 end @@ -107,9 +107,9 @@ describe Chef::ChefFS::Parallelizer do context "With :ordered => true (ordered output)" do it "An empty input produces an empty output" do - parallelize([]) do + expect(parallelize([]) do sleep 10 - end.to_a == [] + end.to_a).to eql([]) expect(elapsed_time).to be < 0.1 end @@ -211,9 +211,7 @@ describe Chef::ChefFS::Parallelizer do occupying_job_finished[0] = true end.wait end - until started - sleep(0.01) - end + sleep(0.01) until started end after :each do diff --git a/spec/unit/cookbook/metadata_spec.rb b/spec/unit/cookbook/metadata_spec.rb index c6d7e41283..27666eb338 100644 --- a/spec/unit/cookbook/metadata_spec.rb +++ b/spec/unit/cookbook/metadata_spec.rb @@ -461,21 +461,21 @@ describe Chef::Cookbook::Metadata do expect(metadata.grouping("/db/mysql/databases/tuning", group)).to eq(group) end it "should not accept anything but a string for display_name" do - expect { + expect do metadata.grouping("db/mysql/databases", :title => "foo") - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.grouping("db/mysql/databases", :title => Hash.new) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should not accept anything but a string for the description" do - expect { + expect do metadata.grouping("db/mysql/databases", :description => "foo") - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.grouping("db/mysql/databases", :description => Hash.new) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end end @@ -498,63 +498,63 @@ describe Chef::Cookbook::Metadata do end it "should not accept anything but a string for display_name" do - expect { + expect do metadata.attribute("db/mysql/databases", :display_name => "foo") - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :display_name => Hash.new) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should not accept anything but a string for the description" do - expect { + expect do metadata.attribute("db/mysql/databases", :description => "foo") - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :description => Hash.new) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should not accept anything but a string for the source_url" do - expect { + expect do metadata.attribute("db/mysql/databases", :source_url => "foo") - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :source_url => Hash.new) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should not accept anything but a string for the issues_url" do - expect { + expect do metadata.attribute("db/mysql/databases", :issues_url => "foo") - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :issues_url => Hash.new) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should not accept anything but true or false for the privacy flag" do - expect { + expect do metadata.attribute("db/mysql/databases", :privacy => true) - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :privacy => false) - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :privacy => "true") - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should not accept anything but an array of strings for choice" do - expect { + expect do metadata.attribute("db/mysql/databases", :choice => %w{dedicated shared}) - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :choice => [10, "shared"]) - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do metadata.attribute("db/mysql/databases", :choice => Hash.new) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should set choice to empty array by default" do @@ -563,15 +563,15 @@ describe Chef::Cookbook::Metadata do end it "should let calculated be true or false" do - expect { + expect do metadata.attribute("db/mysql/databases", :calculated => true) - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :calculated => false) - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :calculated => Hash.new) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should set calculated to false by default" do @@ -580,55 +580,55 @@ describe Chef::Cookbook::Metadata do end it "accepts String for the attribute type" do - expect { + expect do metadata.attribute("db/mysql/databases", :type => "string") - }.not_to raise_error + end.not_to raise_error end it "accepts Array for the attribute type" do - expect { + expect do metadata.attribute("db/mysql/databases", :type => "array") - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :type => Array.new) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "accepts symbol for the attribute type" do - expect { + expect do metadata.attribute("db/mysql/databases", :type => "symbol") - }.not_to raise_error + end.not_to raise_error end it "should let type be hash (backwards compatibility only)" do - expect { + expect do metadata.attribute("db/mysql/databases", :type => "hash") - }.not_to raise_error + end.not_to raise_error end it "should let required be required, recommended or optional" do - expect { + expect do metadata.attribute("db/mysql/databases", :required => "required") - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :required => "recommended") - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :required => "optional") - }.not_to raise_error + end.not_to raise_error end it "should convert required true to required" do - expect { + expect do metadata.attribute("db/mysql/databases", :required => true) - }.not_to raise_error + end.not_to raise_error #attrib = metadata.attributes["db/mysql/databases"][:required].should == "required" end it "should convert required false to optional" do - expect { + expect do metadata.attribute("db/mysql/databases", :required => false) - }.not_to raise_error + end.not_to raise_error #attrib = metadata.attributes["db/mysql/databases"][:required].should == "optional" end @@ -638,12 +638,12 @@ describe Chef::Cookbook::Metadata do end it "should make sure recipes is an array" do - expect { + expect do metadata.attribute("db/mysql/databases", :recipes => []) - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :required => Hash.new) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should set recipes to an empty array by default" do @@ -652,24 +652,24 @@ describe Chef::Cookbook::Metadata do end it "should allow the default value to be a string, array, hash, boolean or numeric" do - expect { + expect do metadata.attribute("db/mysql/databases", :default => []) - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :default => {}) - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :default => "alice in chains") - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :default => 1337) - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :default => true) - }.not_to raise_error - expect { + end.not_to raise_error + expect do metadata.attribute("db/mysql/databases", :required => :not_gonna_do_it) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should limit the types allowed in the choice array" do @@ -678,87 +678,87 @@ describe Chef::Cookbook::Metadata do :choice => %w{test1 test2}, :default => "test1", } - expect { + expect do metadata.attribute("test_cookbook/test", options) - }.not_to raise_error + end.not_to raise_error options = { :type => "boolean", :choice => [ true, false ], :default => true, } - expect { + expect do metadata.attribute("test_cookbook/test", options) - }.not_to raise_error + end.not_to raise_error options = { :type => "numeric", :choice => [ 1337, 420 ], :default => 1337, } - expect { + expect do metadata.attribute("test_cookbook/test", options) - }.not_to raise_error + end.not_to raise_error options = { :type => "numeric", :choice => [ true, "false" ], :default => false, } - expect { + expect do metadata.attribute("test_cookbook/test", options) - }.to raise_error(Chef::Exceptions::ValidationFailed) + end.to raise_error(Chef::Exceptions::ValidationFailed) end it "should error if default used with calculated" do - expect { + expect do attrs = { :calculated => true, :default => [ "I thought you said calculated" ], } metadata.attribute("db/mysql/databases", attrs) - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do attrs = { :calculated => true, :default => "I thought you said calculated", } metadata.attribute("db/mysql/databases", attrs) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should allow a default that is a choice" do - expect { + expect do attrs = { :choice => %w{a b c}, :default => "b", } metadata.attribute("db/mysql/databases", attrs) - }.not_to raise_error - expect { + end.not_to raise_error + expect do attrs = { :choice => %w{a b c d e}, :default => %w{b d}, } metadata.attribute("db/mysql/databases", attrs) - }.not_to raise_error + end.not_to raise_error end it "should error if default is not a choice" do - expect { + expect do attrs = { :choice => %w{a b c}, :default => "d", } metadata.attribute("db/mysql/databases", attrs) - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do attrs = { :choice => %w{a b c d e}, :default => %w{b z}, } metadata.attribute("db/mysql/databases", attrs) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end end diff --git a/spec/unit/cookbook/synchronizer_spec.rb b/spec/unit/cookbook/synchronizer_spec.rb index 3f5624f3b0..82876273e7 100644 --- a/spec/unit/cookbook/synchronizer_spec.rb +++ b/spec/unit/cookbook/synchronizer_spec.rb @@ -414,6 +414,13 @@ describe Chef::CookbookSynchronizer do and_return("/file-cache/cookbooks/cookbook_a/templates/default/apache2.conf.erb") end + describe "#server_api" do + it "sets keepalive to true" do + expect(Chef::ServerAPI).to receive(:new).with(Chef::Config[:chef_server_url], keepalives: true) + synchronizer.server_api + end + end + describe "when syncing cookbooks with the server" do let(:server_api) { double("Chef::ServerAPI (mock)") } diff --git a/spec/unit/cookbook_loader_spec.rb b/spec/unit/cookbook_loader_spec.rb index db10a4eb4f..eef5d2afd5 100644 --- a/spec/unit/cookbook_loader_spec.rb +++ b/spec/unit/cookbook_loader_spec.rb @@ -112,63 +112,63 @@ describe Chef::CookbookLoader do end it "should allow you to override an attribute file via cookbook_path" do - expect(cookbook_loader[:openldap].attribute_filenames.detect { |f| + expect(cookbook_loader[:openldap].attribute_filenames.detect do |f| f =~ /cookbooks\/openldap\/attributes\/default.rb/ - }).not_to eql(nil) - expect(cookbook_loader[:openldap].attribute_filenames.detect { |f| + end).not_to eql(nil) + expect(cookbook_loader[:openldap].attribute_filenames.detect do |f| f =~ /kitchen\/openldap\/attributes\/default.rb/ - }).to eql(nil) + end).to eql(nil) end it "should load different attribute files from deeper paths" do - expect(cookbook_loader[:openldap].attribute_filenames.detect { |f| + expect(cookbook_loader[:openldap].attribute_filenames.detect do |f| f =~ /kitchen\/openldap\/attributes\/robinson.rb/ - }).not_to eql(nil) + end).not_to eql(nil) end it "should allow you to override a definition file via cookbook_path" do - expect(cookbook_loader[:openldap].definition_filenames.detect { |f| + expect(cookbook_loader[:openldap].definition_filenames.detect do |f| f =~ /cookbooks\/openldap\/definitions\/client.rb/ - }).not_to eql(nil) - expect(cookbook_loader[:openldap].definition_filenames.detect { |f| + end).not_to eql(nil) + expect(cookbook_loader[:openldap].definition_filenames.detect do |f| f =~ /kitchen\/openldap\/definitions\/client.rb/ - }).to eql(nil) + end).to eql(nil) end it "should load definition files from deeper paths" do - expect(cookbook_loader[:openldap].definition_filenames.detect { |f| + expect(cookbook_loader[:openldap].definition_filenames.detect do |f| f =~ /kitchen\/openldap\/definitions\/drewbarrymore.rb/ - }).not_to eql(nil) + end).not_to eql(nil) end it "should allow you to override a recipe file via cookbook_path" do - expect(cookbook_loader[:openldap].recipe_filenames.detect { |f| + expect(cookbook_loader[:openldap].recipe_filenames.detect do |f| f =~ /cookbooks\/openldap\/recipes\/gigantor.rb/ - }).not_to eql(nil) - expect(cookbook_loader[:openldap].recipe_filenames.detect { |f| + end).not_to eql(nil) + expect(cookbook_loader[:openldap].recipe_filenames.detect do |f| f =~ /kitchen\/openldap\/recipes\/gigantor.rb/ - }).to eql(nil) + end).to eql(nil) end it "should load recipe files from deeper paths" do - expect(cookbook_loader[:openldap].recipe_filenames.detect { |f| + expect(cookbook_loader[:openldap].recipe_filenames.detect do |f| f =~ /kitchen\/openldap\/recipes\/woot.rb/ - }).not_to eql(nil) + end).not_to eql(nil) end it "should allow you to have an 'ignore' file, which skips loading files in later cookbooks" do - expect(cookbook_loader[:openldap].recipe_filenames.detect { |f| + expect(cookbook_loader[:openldap].recipe_filenames.detect do |f| f =~ /kitchen\/openldap\/recipes\/ignoreme.rb/ - }).to eql(nil) + end).to eql(nil) end it "should find files that start with a ." do - expect(cookbook_loader[:openldap].file_filenames.detect { |f| + expect(cookbook_loader[:openldap].file_filenames.detect do |f| f =~ /\.dotfile$/ - }).to match(/\.dotfile$/) - expect(cookbook_loader[:openldap].file_filenames.detect { |f| + end).to match(/\.dotfile$/) + expect(cookbook_loader[:openldap].file_filenames.detect do |f| f =~ /\.ssh\/id_rsa$/ - }).to match(/\.ssh\/id_rsa$/) + end).to match(/\.ssh\/id_rsa$/) end it "should load the metadata for the cookbook" do diff --git a/spec/unit/cookbook_version_file_specificity_spec.rb b/spec/unit/cookbook_version_file_specificity_spec.rb index df9e6571d8..3b5450cb2d 100644 --- a/spec/unit/cookbook_version_file_specificity_spec.rb +++ b/spec/unit/cookbook_version_file_specificity_spec.rb @@ -304,24 +304,24 @@ describe Chef::CookbookVersion, "file specificity" do it "should raise a FileNotFound exception without match" do node = Chef::Node.new - expect { + expect do @cookbook.preferred_manifest_record(node, :files, "doesn't_exist.rb") - }.to raise_error(Chef::Exceptions::FileNotFound) + end.to raise_error(Chef::Exceptions::FileNotFound) end it "should raise a FileNotFound exception consistently without match" do node = Chef::Node.new - expect { + expect do @cookbook.preferred_manifest_record(node, :files, "doesn't_exist.rb") - }.to raise_error(Chef::Exceptions::FileNotFound) + end.to raise_error(Chef::Exceptions::FileNotFound) - expect { + expect do @cookbook.preferred_manifest_record(node, :files, "doesn't_exist.rb") - }.to raise_error(Chef::Exceptions::FileNotFound) + end.to raise_error(Chef::Exceptions::FileNotFound) - expect { + expect do @cookbook.preferred_manifest_record(node, :files, "doesn't_exist.rb") - }.to raise_error(Chef::Exceptions::FileNotFound) + end.to raise_error(Chef::Exceptions::FileNotFound) end describe "when fetching the contents of a directory by file specificity" do diff --git a/spec/unit/daemon_spec.rb b/spec/unit/daemon_spec.rb index e31ce7d151..ae3d626113 100644 --- a/spec/unit/daemon_spec.rb +++ b/spec/unit/daemon_spec.rb @@ -22,7 +22,7 @@ describe Chef::Daemon do before do if windows? mock_struct = #Struct::Passwd.new(nil, nil, 111, 111) - mock_struct = OpenStruct.new(:uid => 2342, :gid => 2342) + mock_struct = OpenStruct.new(:uid => 2342, :gid => 2342) allow(Etc).to receive(:getpwnam).and_return mock_struct allow(Etc).to receive(:getgrnam).and_return mock_struct # mock unimplemented methods diff --git a/spec/unit/data_bag_item_spec.rb b/spec/unit/data_bag_item_spec.rb index 2711fcae03..e83f0ca0ec 100644 --- a/spec/unit/data_bag_item_spec.rb +++ b/spec/unit/data_bag_item_spec.rb @@ -91,12 +91,12 @@ describe Chef::DataBagItem do end describe "object_name" do - let(:data_bag_item) { + let(:data_bag_item) do data_bag_item = Chef::DataBagItem.new data_bag_item.data_bag("dreams") data_bag_item.raw_data = { "id" => "the_beatdown" } data_bag_item - } + end it "should return an object name based on the bag name and the raw_data id" do expect(data_bag_item.object_name).to eq("data_bag_item_dreams_the_beatdown") @@ -110,12 +110,12 @@ describe Chef::DataBagItem do end describe "class method name" do - let(:data_bag_item) { + let(:data_bag_item) do data_bag_item = Chef::DataBagItem.new data_bag_item.data_bag("dreams") data_bag_item.raw_data = { "id" => "the_beatdown", "name" => "Bruce" } data_bag_item - } + end it "should return the object name" do expect(data_bag_item.name).to eq(data_bag_item.object_name) @@ -128,11 +128,11 @@ describe Chef::DataBagItem do end describe "when used like a Hash" do - let(:data_bag_item) { + let(:data_bag_item) do data_bag_item = Chef::DataBagItem.new data_bag_item.raw_data = { "id" => "journey", "trials" => "been through" } data_bag_item - } + end it "responds to keys" do expect(data_bag_item.keys).to include("id") @@ -158,9 +158,9 @@ describe Chef::DataBagItem do describe "from_hash" do context "when hash contains raw_data" do - let(:data_bag_item) { + let(:data_bag_item) do Chef::DataBagItem.from_hash({ "raw_data" => { "id" => "whoa", "name" => "Bruce", "i_know" => "kung_fu" } }) - } + end it "should have the id key set" do expect(data_bag_item["id"]).to eq("whoa") @@ -172,9 +172,9 @@ describe Chef::DataBagItem do end context "when hash does not contain raw_data" do - let(:data_bag_item) { + let(:data_bag_item) do Chef::DataBagItem.from_hash({ "id" => "whoa", "name" => "Bruce", "i_know" => "kung_fu" }) - } + end it "should have the id key set" do expect(data_bag_item["id"]).to eq("whoa") @@ -187,12 +187,12 @@ describe Chef::DataBagItem do end describe "to_hash" do - let(:data_bag_item) { + let(:data_bag_item) do data_bag_item = Chef::DataBagItem.new data_bag_item.data_bag("still_lost") data_bag_item.raw_data = { "id" => "whoa", "name" => "Bruce", "i_know" => "kung_fu" } data_bag_item - } + end let!(:original_data_bag_keys) { data_bag_item.keys } @@ -223,12 +223,12 @@ describe Chef::DataBagItem do end describe "when deserializing from JSON" do - let(:data_bag_item) { + let(:data_bag_item) do data_bag_item = Chef::DataBagItem.new data_bag_item.data_bag("mars_volta") data_bag_item.raw_data = { "id" => "octahedron", "name" => "Bruce", "snooze" => { "finally" => :world_will } } data_bag_item - } + end let(:deserial) { Chef::DataBagItem.from_hash(Chef::JSONCompat.parse(Chef::JSONCompat.to_json(data_bag_item))) } @@ -275,13 +275,13 @@ describe Chef::DataBagItem do describe "save" do let(:server) { instance_double(Chef::ServerAPI) } - let(:data_bag_item) { + let(:data_bag_item) do data_bag_item = Chef::DataBagItem.new data_bag_item["id"] = "heart of darkness" data_bag_item.raw_data = { "id" => "heart_of_darkness", "author" => "Conrad" } data_bag_item.data_bag("books") data_bag_item - } + end before do expect(Chef::ServerAPI).to receive(:new).and_return(server) @@ -320,12 +320,12 @@ describe Chef::DataBagItem do describe "destroy" do let(:server) { instance_double(Chef::ServerAPI) } - let(:data_bag_item) { + let(:data_bag_item) do data_bag_item = Chef::DataBagItem.new data_bag_item.data_bag("a_baggy_bag") data_bag_item.raw_data = { "id" => "some_id" } data_bag_item - } + end it "should set default parameters" do expect(Chef::ServerAPI).to receive(:new).and_return(server) diff --git a/spec/unit/data_bag_spec.rb b/spec/unit/data_bag_spec.rb index 84aa724927..cadd60936e 100644 --- a/spec/unit/data_bag_spec.rb +++ b/spec/unit/data_bag_spec.rb @@ -241,9 +241,9 @@ describe Chef::DataBag do it "should raise an error if the configured data_bag_path is invalid" do file_dir_stub(@paths.first, false) - expect { + expect do Chef::DataBag.load("foo") - }.to raise_error Chef::Exceptions::InvalidDataBagPath, "Data bag path '/var/chef/data_bags' is invalid" + end.to raise_error Chef::Exceptions::InvalidDataBagPath, "Data bag path '/var/chef/data_bags' is invalid" end end diff --git a/spec/unit/data_collector/messages/helpers_spec.rb b/spec/unit/data_collector/messages/helpers_spec.rb index 26f7dbacfa..b0d9f4d09d 100644 --- a/spec/unit/data_collector/messages/helpers_spec.rb +++ b/spec/unit/data_collector/messages/helpers_spec.rb @@ -25,7 +25,7 @@ class TestMessage end describe Chef::DataCollector::Messages::Helpers do - describe '#organization' do + describe "#organization" do context "when the run is a solo run" do it "returns the data collector organization" do allow(TestMessage).to receive(:solo_run?).and_return(true) @@ -43,7 +43,7 @@ describe Chef::DataCollector::Messages::Helpers do end end - describe '#data_collector_organization' do + describe "#data_collector_organization" do context "when the org is specified in the config" do it "returns the org from the config" do Chef::Config[:data_collector][:organization] = "org1" @@ -58,7 +58,7 @@ describe Chef::DataCollector::Messages::Helpers do end end - describe '#chef_server_organization' do + describe "#chef_server_organization" do context "when the URL is properly formatted" do it "returns the org from the parsed URL" do Chef::Config[:chef_server_url] = "http://mycompany.com/organizations/myorg" @@ -74,7 +74,7 @@ describe Chef::DataCollector::Messages::Helpers do end end - describe '#collector_source' do + describe "#collector_source" do context "when the run is a solo run" do it "returns chef_solo" do allow(TestMessage).to receive(:solo_run?).and_return(true) @@ -90,7 +90,7 @@ describe Chef::DataCollector::Messages::Helpers do end end - describe '#solo_run?' do + describe "#solo_run?" do context "when :solo is set in Chef::Config" do it "returns true" do Chef::Config[:solo] = true @@ -116,7 +116,7 @@ describe Chef::DataCollector::Messages::Helpers do end end - describe '#node_uuid' do + describe "#node_uuid" do context "when the node UUID can be read" do it "returns the read-in node UUID" do allow(TestMessage).to receive(:read_node_uuid).and_return("read_uuid") @@ -133,7 +133,7 @@ describe Chef::DataCollector::Messages::Helpers do end end - describe '#generate_node_uuid' do + describe "#generate_node_uuid" do it "generates a new UUID, stores it, and returns it" do expect(SecureRandom).to receive(:uuid).and_return("generated_uuid") expect(TestMessage).to receive(:update_metadata).with("node_uuid", "generated_uuid") @@ -141,7 +141,7 @@ describe Chef::DataCollector::Messages::Helpers do end end - describe '#read_node_uuid' do + describe "#read_node_uuid" do it "reads the node UUID from metadata" do expect(TestMessage).to receive(:metadata).and_return({ "node_uuid" => "read_uuid" }) expect(TestMessage.read_node_uuid).to eq("read_uuid") @@ -170,7 +170,7 @@ describe Chef::DataCollector::Messages::Helpers do end end - describe '#update_metadata' do + describe "#update_metadata" do it "updates the file" do allow(TestMessage).to receive(:metadata_filename).and_return("fake_metadata_file.json") allow(TestMessage).to receive(:metadata).and_return({ "key" => "current_value" }) diff --git a/spec/unit/data_collector/messages_spec.rb b/spec/unit/data_collector/messages_spec.rb index b0c7e692d2..394f18dce0 100644 --- a/spec/unit/data_collector/messages_spec.rb +++ b/spec/unit/data_collector/messages_spec.rb @@ -22,7 +22,7 @@ require "ffi_yajl" require "chef/data_collector/messages/helpers" describe Chef::DataCollector::Messages do - describe '#run_start_message' do + describe "#run_start_message" do let(:run_status) { Chef::RunStatus.new(Chef::Node.new, Chef::EventDispatch::Dispatcher.new) } let(:required_fields) do %w{ @@ -61,7 +61,7 @@ describe Chef::DataCollector::Messages do end end - describe '#run_end_message' do + describe "#run_end_message" do let(:node) { Chef::Node.new } let(:run_status) { Chef::RunStatus.new(node, Chef::EventDispatch::Dispatcher.new) } let(:report1) { double("report1", report_data: { "status" => "updated" }) } diff --git a/spec/unit/data_collector_spec.rb b/spec/unit/data_collector_spec.rb index 131d6b8df9..37df758ff2 100644 --- a/spec/unit/data_collector_spec.rb +++ b/spec/unit/data_collector_spec.rb @@ -160,7 +160,7 @@ describe Chef::DataCollector::Reporter do Chef::Config[:data_collector][:server_url] = "http://my-data-collector-server.mycompany.com" end - describe '#run_started' do + describe "#run_started" do before do allow(reporter).to receive(:update_run_status) allow(reporter).to receive(:send_to_data_collector) @@ -182,7 +182,7 @@ describe Chef::DataCollector::Reporter do end end - describe '#run_completed' do + describe "#run_completed" do it "sends the run completion" do node = Chef::Node.new @@ -191,35 +191,35 @@ describe Chef::DataCollector::Reporter do end end - describe '#run_failed' do + describe "#run_failed" do it "updates the exception and sends the run completion" do expect(reporter).to receive(:send_run_completion).with(status: "failure") reporter.run_failed("test_exception") end end - describe '#converge_start' do + describe "#converge_start" do it "stashes the run_context for later use" do reporter.converge_start("test_context") expect(reporter.run_context).to eq("test_context") end end - describe '#converge_complete' do + describe "#converge_complete" do it "detects and processes any unprocessed resources" do expect(reporter).to receive(:detect_unprocessed_resources) reporter.converge_complete end end - describe '#converge_failed' do + describe "#converge_failed" do it "detects and processes any unprocessed resources" do expect(reporter).to receive(:detect_unprocessed_resources) reporter.converge_failed("exception") end end - describe '#resource_current_state_loaded' do + describe "#resource_current_state_loaded" do let(:new_resource) { double("new_resource") } let(:action) { double("action") } let(:current_resource) { double("current_resource") } @@ -245,7 +245,7 @@ describe Chef::DataCollector::Reporter do end end - describe '#resource_up_to_date' do + describe "#resource_up_to_date" do let(:new_resource) { double("new_resource") } let(:action) { double("action") } let(:resource_report) { double("resource_report") } @@ -273,7 +273,7 @@ describe Chef::DataCollector::Reporter do end end - describe '#resource_skipped' do + describe "#resource_skipped" do let(:new_resource) { double("new_resource") } let(:action) { double("action") } let(:conditional) { double("conditional") } @@ -311,7 +311,7 @@ describe Chef::DataCollector::Reporter do end end - describe '#resource_updated' do + describe "#resource_updated" do let(:resource_report) { double("resource_report") } before do @@ -325,7 +325,7 @@ describe Chef::DataCollector::Reporter do end end - describe '#resource_failed' do + describe "#resource_failed" do let(:new_resource) { double("new_resource") } let(:action) { double("action") } let(:exception) { double("exception") } @@ -368,7 +368,7 @@ describe Chef::DataCollector::Reporter do end end - describe '#resource_completed' do + describe "#resource_completed" do let(:new_resource) { double("new_resource") } let(:resource_report) { double("resource_report") } @@ -418,14 +418,14 @@ describe Chef::DataCollector::Reporter do end end - describe '#run_list_expanded' do + describe "#run_list_expanded" do it "sets the expanded run list" do reporter.run_list_expanded("test_run_list") expect(reporter.expanded_run_list).to eq("test_run_list") end end - describe '#run_list_expand_failed' do + describe "#run_list_expand_failed" do let(:node) { double("node") } let(:error_mapper) { double("error_mapper") } let(:exception) { double("exception") } @@ -441,7 +441,7 @@ describe Chef::DataCollector::Reporter do end end - describe '#cookbook_resolution_failed' do + describe "#cookbook_resolution_failed" do let(:error_mapper) { double("error_mapper") } let(:exception) { double("exception") } let(:expanded_run_list) { double("expanded_run_list") } @@ -458,7 +458,7 @@ describe Chef::DataCollector::Reporter do end - describe '#cookbook_sync_failed' do + describe "#cookbook_sync_failed" do let(:cookbooks) { double("cookbooks") } let(:error_mapper) { double("error_mapper") } let(:exception) { double("exception") } @@ -474,7 +474,7 @@ describe Chef::DataCollector::Reporter do end end - describe '#disable_reporter_on_error' do + describe "#disable_reporter_on_error" do context "when no exception is raise by the block" do it "does not disable the reporter" do expect(reporter).not_to receive(:disable_data_collector_reporter) @@ -488,7 +488,7 @@ describe Chef::DataCollector::Reporter do context "when an unexpected exception is raised by the block" do it "re-raises the exception" do - expect { reporter.send(:disable_reporter_on_error) { raise RuntimeError, "bummer" } }.to raise_error(RuntimeError) + expect { reporter.send(:disable_reporter_on_error) { raise "bummer" } }.to raise_error(RuntimeError) end end @@ -521,7 +521,7 @@ describe Chef::DataCollector::Reporter do end end - describe '#validate_data_collector_server_url!' do + describe "#validate_data_collector_server_url!" do context "when server_url is empty" do it "raises an exception" do Chef::Config[:data_collector][:server_url] = "" diff --git a/spec/unit/dsl/audit_spec.rb b/spec/unit/dsl/audit_spec.rb index a8227f6c99..42e543fdb2 100644 --- a/spec/unit/dsl/audit_spec.rb +++ b/spec/unit/dsl/audit_spec.rb @@ -21,14 +21,14 @@ describe Chef::DSL::Audit do end it "raises an error when no audit name is given" do - expect { auditor.control_group do end }.to raise_error(Chef::Exceptions::AuditNameMissing) + expect { auditor.control_group {} }.to raise_error(Chef::Exceptions::AuditNameMissing) end context "audits already populated" do let(:audits) { { "unique" => {} } } it "raises an error if the audit name is a duplicate" do - expect { auditor.control_group "unique" do end }.to raise_error(Chef::Exceptions::AuditControlGroupDuplicate) + expect { auditor.control_group("unique") {} }.to raise_error(Chef::Exceptions::AuditControlGroupDuplicate) end end @@ -36,7 +36,7 @@ describe Chef::DSL::Audit do let(:auditor) { BadAuditDSLTester.new } it "fails because it relies on the recipe DSL existing" do - expect { auditor.control_group "unique" do end }.to raise_error(NoMethodError, /undefined method `cookbook_name'/) + expect { auditor.control_group("unique") {} }.to raise_error(NoMethodError, /undefined method `cookbook_name'/) end end diff --git a/spec/unit/dsl/data_query_spec.rb b/spec/unit/dsl/data_query_spec.rb index 55c6e5f578..f93f07bc52 100644 --- a/spec/unit/dsl/data_query_spec.rb +++ b/spec/unit/dsl/data_query_spec.rb @@ -60,14 +60,15 @@ describe Chef::DSL::DataQuery do let(:item_name) { "item_name" } - let(:raw_data) {{ + let(:raw_data) do + { "id" => item_name, "greeting" => "hello", "nested" => { "a1" => [1, 2, 3], "a2" => { "b1" => true }, }, - }} + } end let(:item) do item = Chef::DataBagItem.new diff --git a/spec/unit/dsl/declare_resource_spec.rb b/spec/unit/dsl/declare_resource_spec.rb index 6dd9317c21..57a7fd7f18 100644 --- a/spec/unit/dsl/declare_resource_spec.rb +++ b/spec/unit/dsl/declare_resource_spec.rb @@ -50,17 +50,17 @@ describe Chef::ResourceCollection do describe "#edit_resource!" do it "raises if nothing is found" do - expect { + expect do recipe.edit_resource!(:zen_master, "monkey") do something true end - }.to raise_error(Chef::Exceptions::ResourceNotFound) + end.to raise_error(Chef::Exceptions::ResourceNotFound) end it "raises if nothing is found and no block is given" do - expect { + expect do recipe.edit_resource!(:zen_master, "monkey") - }.to raise_error(Chef::Exceptions::ResourceNotFound) + end.to raise_error(Chef::Exceptions::ResourceNotFound) end it "edits the resource if it finds one" do @@ -131,20 +131,20 @@ describe Chef::ResourceCollection do describe "#find_resource!" do it "raises if nothing is found" do - expect { + expect do recipe.find_resource!(:zen_master, "monkey") - }.to raise_error(Chef::Exceptions::ResourceNotFound) + end.to raise_error(Chef::Exceptions::ResourceNotFound) end it "raises if given a block" do resource = recipe.declare_resource(:zen_master, "monkey") do something false end - expect { + expect do recipe.find_resource!(:zen_master, "monkey") do something false end - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "returns the resource if it finds one" do @@ -221,9 +221,9 @@ describe Chef::ResourceCollection do describe "#delete_resource!" do it "raises if nothing is found" do - expect { + expect do recipe.delete_resource!(:zen_master, "monkey") - }.to raise_error(Chef::Exceptions::ResourceNotFound) + end.to raise_error(Chef::Exceptions::ResourceNotFound) end it "deletes and returns the resource if it finds one" do @@ -235,6 +235,36 @@ describe Chef::ResourceCollection do ).to eql(resource) expect(run_context.resource_collection.all_resources.size).to eql(0) end + + it "removes pending delayed notifications" do + recipe.declare_resource(:zen_master, "one") + recipe.declare_resource(:zen_master, "two") do + notifies :win, "zen_master[one]" + end + recipe.delete_resource(:zen_master, "two") + resource = recipe.declare_resource(:zen_master, "two") + expect(resource.delayed_notifications).to eql([]) + end + + it "removes pending immediate notifications" do + recipe.declare_resource(:zen_master, "one") + recipe.declare_resource(:zen_master, "two") do + notifies :win, "zen_master[one]", :immediate + end + recipe.delete_resource(:zen_master, "two") + resource = recipe.declare_resource(:zen_master, "two") + expect(resource.immediate_notifications).to eql([]) + end + + it "removes pending before notifications" do + recipe.declare_resource(:zen_master, "one") + recipe.declare_resource(:zen_master, "two") do + notifies :win, "zen_master[one]", :before + end + recipe.delete_resource(:zen_master, "two") + resource = recipe.declare_resource(:zen_master, "two") + expect(resource.before_notifications).to eql([]) + end end describe "run_context helpers" do diff --git a/spec/unit/encrypted_data_bag_item/check_encrypted_spec.rb b/spec/unit/encrypted_data_bag_item/check_encrypted_spec.rb index c2cb275f9d..7e885f8818 100644 --- a/spec/unit/encrypted_data_bag_item/check_encrypted_spec.rb +++ b/spec/unit/encrypted_data_bag_item/check_encrypted_spec.rb @@ -39,14 +39,15 @@ describe Chef::EncryptedDataBagItem::CheckEncrypted do let(:default_secret) { "abc123SECRET" } let(:item_name) { "item_name" } - let(:raw_data) {{ + let(:raw_data) do + { "id" => item_name, "greeting" => "hello", "nested" => { "a1" => [1, 2, 3], "a2" => { "b1" => true }, }, - }} + } end let(:version) { 1 } let(:encoded_data) do diff --git a/spec/unit/encrypted_data_bag_item_spec.rb b/spec/unit/encrypted_data_bag_item_spec.rb index e17f7a2331..a8fb144bf7 100644 --- a/spec/unit/encrypted_data_bag_item_spec.rb +++ b/spec/unit/encrypted_data_bag_item_spec.rb @@ -320,11 +320,12 @@ end describe Chef::EncryptedDataBagItem do subject { described_class } let(:encrypted_data_bag_item) { subject.new(encoded_data, secret) } - let(:plaintext_data) {{ + let(:plaintext_data) do + { "id" => "item_name", "greeting" => "hello", "nested" => { "a1" => [1, 2, 3], "a2" => { "b1" => true } }, - }} + } end let(:secret) { "abc123SECRET" } let(:encoded_data) { subject.encrypt_data_bag_item(plaintext_data, secret) } diff --git a/spec/unit/environment_spec.rb b/spec/unit/environment_spec.rb index 5557b5dc11..63c96ad93e 100644 --- a/spec/unit/environment_spec.rb +++ b/spec/unit/environment_spec.rb @@ -296,9 +296,9 @@ describe Chef::Environment do end it "should raise and exception" do - expect { + expect do Chef::Environment.validate_cookbook_version("= 1.2.3.4") - }.to raise_error Chef::Exceptions::IllegalVersionConstraint, + end.to raise_error Chef::Exceptions::IllegalVersionConstraint, "Environment cookbook version constraints not allowed in chef-solo" end end @@ -450,9 +450,9 @@ describe Chef::Environment do it "should raise an error if the configured environment_path is invalid" do expect(File).to receive(:directory?).with(Chef::Config[:environment_path]).and_return(false) - expect { + expect do Chef::Environment.load("foo") - }.to raise_error Chef::Exceptions::InvalidEnvironmentPath, "Environment path '/var/chef/environments' is invalid" + end.to raise_error Chef::Exceptions::InvalidEnvironmentPath, "Environment path '/var/chef/environments' is invalid" end it "should raise an error if the file does not exist" do @@ -460,9 +460,9 @@ describe Chef::Environment do expect(File).to receive(:exists?).with(File.join(Chef::Config[:environment_path], "foo.json")).and_return(false) expect(File).to receive(:exists?).with(File.join(Chef::Config[:environment_path], "foo.rb")).and_return(false) - expect { + expect do Chef::Environment.load("foo") - }.to raise_error Chef::Exceptions::EnvironmentNotFound, "Environment 'foo' could not be loaded from disk" + end.to raise_error Chef::Exceptions::EnvironmentNotFound, "Environment 'foo' could not be loaded from disk" end end end diff --git a/spec/unit/file_access_control_spec.rb b/spec/unit/file_access_control_spec.rb index 4357a91148..ee806b5c3a 100644 --- a/spec/unit/file_access_control_spec.rb +++ b/spec/unit/file_access_control_spec.rb @@ -43,7 +43,7 @@ describe Chef::FileAccessControl do end describe "class methods" do - it 'responds to #writable?' do + it "responds to #writable?" do expect(Chef::FileAccessControl).to respond_to(:writable?) end end @@ -67,7 +67,7 @@ describe Chef::FileAccessControl do it "raises a Chef::Exceptions::UserIDNotFound error when Etc can't find the user's name" do expect(Etc).to receive(:getpwnam).with("toor").and_raise(ArgumentError) - expect { @fac.target_uid ; @provider_requirements.run(:create) }.to raise_error(Chef::Exceptions::UserIDNotFound, "cannot determine user id for 'toor', does the user exist on this system?") + expect { @fac.target_uid; @provider_requirements.run(:create) }.to raise_error(Chef::Exceptions::UserIDNotFound, "cannot determine user id for 'toor', does the user exist on this system?") end it "does not attempt to resolve the uid if the user is not specified" do @@ -84,7 +84,7 @@ describe Chef::FileAccessControl do it "raises an ArgumentError if the resource's owner is set to something wack" do @resource.instance_variable_set(:@owner, :diaf) - expect { @fac.target_uid ; @provider_requirements.run(:create) }.to raise_error(ArgumentError) + expect { @fac.target_uid; @provider_requirements.run(:create) }.to raise_error(ArgumentError) end it "uses the resource's uid for the target uid when the resource's owner is specified by an integer" do diff --git a/spec/unit/file_content_management/tempfile_spec.rb b/spec/unit/file_content_management/tempfile_spec.rb index a833e21fac..4b27fc8cc9 100644 --- a/spec/unit/file_content_management/tempfile_spec.rb +++ b/spec/unit/file_content_management/tempfile_spec.rb @@ -19,11 +19,11 @@ require "spec_helper" describe Chef::FileContentManagement::Tempfile do - let(:resource) { + let(:resource) do r = Chef::Resource::File.new("new_file") r.path "/foo/bar/new_file" r - } + end subject { described_class.new(resource) } diff --git a/spec/unit/formatters/error_inspectors/api_error_formatting_spec.rb b/spec/unit/formatters/error_inspectors/api_error_formatting_spec.rb index 97fa92ca52..0e5104a0db 100644 --- a/spec/unit/formatters/error_inspectors/api_error_formatting_spec.rb +++ b/spec/unit/formatters/error_inspectors/api_error_formatting_spec.rb @@ -32,13 +32,13 @@ describe Chef::Formatters::APIErrorFormatting do let(:min_version) { "2" } let(:max_version) { "5" } let(:request_version) { "30" } - let(:return_hash) { + let(:return_hash) do { "min_version" => min_version, "max_version" => max_version, "request_version" => request_version, } - } + end before do # mock out the header diff --git a/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb b/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb index e76e69d2cd..746b343e9c 100644 --- a/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb +++ b/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb @@ -105,9 +105,9 @@ describe Chef::GuardInterpreter::ResourceGuardInterpreter do parent_resource end - let(:shell_out) { + let(:shell_out) do instance_double(Mixlib::ShellOut, :live_stream => true, :run_command => true, :error! => nil) - } + end before do # TODO for some reason Windows is failing on executing a ruby script diff --git a/spec/unit/http/basic_client_spec.rb b/spec/unit/http/basic_client_spec.rb index 8cf63d4441..0def00a220 100644 --- a/spec/unit/http/basic_client_spec.rb +++ b/spec/unit/http/basic_client_spec.rb @@ -29,6 +29,26 @@ describe "HTTP Connection" do end end + describe "#initialize" do + it "calls .start when doing keepalives" do + basic_client = Chef::HTTP::BasicClient.new(uri, keepalives: true) + expect(basic_client).to receive(:configure_ssl) + net_http_mock = instance_double(Net::HTTP, proxy_address: nil, "proxy_port=" => nil, "read_timeout=" => nil, "open_timeout=" => nil) + expect(net_http_mock).to receive(:start).and_return(net_http_mock) + expect(Net::HTTP).to receive(:new).and_return(net_http_mock) + expect(basic_client.http_client).to eql(net_http_mock) + end + + it "does not call .start when not doing keepalives" do + basic_client = Chef::HTTP::BasicClient.new(uri) + expect(basic_client).to receive(:configure_ssl) + net_http_mock = instance_double(Net::HTTP, proxy_address: nil, "proxy_port=" => nil, "read_timeout=" => nil, "open_timeout=" => nil) + expect(net_http_mock).not_to receive(:start) + expect(Net::HTTP).to receive(:new).and_return(net_http_mock) + expect(basic_client.http_client).to eql(net_http_mock) + end + end + describe "#build_http_client" do it "should build an http client" do subject.build_http_client diff --git a/spec/unit/http/validate_content_length_spec.rb b/spec/unit/http/validate_content_length_spec.rb index 85f8d92f78..5067d36d38 100644 --- a/spec/unit/http/validate_content_length_spec.rb +++ b/spec/unit/http/validate_content_length_spec.rb @@ -37,25 +37,25 @@ describe Chef::HTTP::ValidateContentLength do let(:content_length_value) { 23 } let(:streaming_length) { 23 } let(:response_body) { "Thanks for checking in." } - let(:response_headers) { + let(:response_headers) do { "content-length" => content_length_value, } - } + end - let(:response) { + let(:response) do m = double("HttpResponse", :body => response_body) allow(m).to receive(:[]) do |key| response_headers[key] end m - } + end - let(:middleware) { + let(:middleware) do client = TestClient.new(url) client.middlewares[0] - } + end def run_content_length_validation stream_handler = middleware.stream_response_handler(response) @@ -169,12 +169,12 @@ describe Chef::HTTP::ValidateContentLength do end describe "when Transfer-Encoding & Content-Length is set" do - let(:response_headers) { + let(:response_headers) do { "content-length" => content_length_value, "transfer-encoding" => "chunked", } - } + end %w{direct streaming}.each do |req_type| describe "when running #{req_type} request" do diff --git a/spec/unit/http_spec.rb b/spec/unit/http_spec.rb index 69e59ecaf8..d99f03aac9 100644 --- a/spec/unit/http_spec.rb +++ b/spec/unit/http_spec.rb @@ -43,6 +43,20 @@ describe Chef::HTTP do end + describe "#intialize" do + it "accepts a keepalive option and passes it to the http_client" do + http = Chef::HTTP.new(uri, keepalives: true) + expect(Chef::HTTP::BasicClient).to receive(:new).with(uri, ssl_policy: Chef::HTTP::APISSLPolicy, keepalives: true).and_call_original + expect(http.http_client).to be_a_kind_of(Chef::HTTP::BasicClient) + end + + it "the default is not to use keepalives" do + http = Chef::HTTP.new(uri) + expect(Chef::HTTP::BasicClient).to receive(:new).with(uri, ssl_policy: Chef::HTTP::APISSLPolicy, keepalives: false).and_call_original + expect(http.http_client).to be_a_kind_of(Chef::HTTP::BasicClient) + end + end + describe "create_url" do it "should return a correctly formatted url 1/3 CHEF-5261" do diff --git a/spec/unit/knife/bootstrap/chef_vault_handler_spec.rb b/spec/unit/knife/bootstrap/chef_vault_handler_spec.rb index 734b27216d..d822fe8f98 100644 --- a/spec/unit/knife/bootstrap/chef_vault_handler_spec.rb +++ b/spec/unit/knife/bootstrap/chef_vault_handler_spec.rb @@ -29,10 +29,10 @@ describe Chef::Knife::Bootstrap::ChefVaultHandler do let(:client) { Chef::ApiClient.new } - let(:chef_vault_handler) { + let(:chef_vault_handler) do chef_vault_handler = Chef::Knife::Bootstrap::ChefVaultHandler.new(knife_config: knife_config, ui: ui) chef_vault_handler - } + end context "when there's no vault option" do it "should report its not doing anything" do diff --git a/spec/unit/knife/bootstrap/client_builder_spec.rb b/spec/unit/knife/bootstrap/client_builder_spec.rb index 491d0ca754..97ba0fc48e 100644 --- a/spec/unit/knife/bootstrap/client_builder_spec.rb +++ b/spec/unit/knife/bootstrap/client_builder_spec.rb @@ -33,12 +33,12 @@ describe Chef::Knife::Bootstrap::ClientBuilder do let(:rest) { double("Chef::ServerAPI") } - let(:client_builder) { + let(:client_builder) do client_builder = Chef::Knife::Bootstrap::ClientBuilder.new(knife_config: knife_config, chef_config: chef_config, ui: ui) allow(client_builder).to receive(:rest).and_return(rest) allow(client_builder).to receive(:node_name).and_return(node_name) client_builder - } + end context "#sanity_check!" do let(:response_404) { OpenStruct.new(:code => "404") } diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb index 5f1ba9f781..9f944b82d9 100644 --- a/spec/unit/knife/bootstrap_spec.rb +++ b/spec/unit/knife/bootstrap_spec.rb @@ -236,11 +236,11 @@ describe Chef::Knife::Bootstrap do end context "with bootstrap_attribute options" do - let(:jsonfile) { + let(:jsonfile) do file = Tempfile.new (["node", ".json"]) File.open(file.path, "w") { |f| f.puts '{"foo":{"bar":"baz"}}' } file - } + end it "should have foo => {bar => baz} in the first_boot from cli" do knife.parse_options(["-j", '{"foo":{"bar":"baz"}}']) @@ -478,8 +478,9 @@ describe Chef::Knife::Bootstrap do end context "when client_d_dir is set" do - let(:client_d_dir) { Chef::Util::PathHelper.cleanpath( - File.join(File.dirname(__FILE__), "../../data/client.d_00")) } + let(:client_d_dir) do + Chef::Util::PathHelper.cleanpath( + File.join(File.dirname(__FILE__), "../../data/client.d_00")) end it "creates /etc/chef/client.d" do expect(rendered_template).to match("mkdir -p /etc/chef/client\.d") @@ -497,8 +498,9 @@ describe Chef::Knife::Bootstrap do end context "a nested directory structure" do - let(:client_d_dir) { Chef::Util::PathHelper.cleanpath( - File.join(File.dirname(__FILE__), "../../data/client.d_01")) } + let(:client_d_dir) do + Chef::Util::PathHelper.cleanpath( + File.join(File.dirname(__FILE__), "../../data/client.d_01")) end it "creates a file foo/bar.rb" do expect(rendered_template).to match("cat > /etc/chef/client.d/foo/bar.rb <<'EOP'") expect(rendered_template).to match("1 / 0") diff --git a/spec/unit/knife/client_bulk_delete_spec.rb b/spec/unit/knife/client_bulk_delete_spec.rb index a9b18c9086..994f4d33a4 100644 --- a/spec/unit/knife/client_bulk_delete_spec.rb +++ b/spec/unit/knife/client_bulk_delete_spec.rb @@ -24,7 +24,7 @@ describe Chef::Knife::ClientBulkDelete do let(:stderr_io) { StringIO.new } let(:stderr) { stderr_io.string } - let(:knife) { + let(:knife) do k = Chef::Knife::ClientBulkDelete.new k.name_args = name_args k.config = option_args @@ -33,7 +33,7 @@ describe Chef::Knife::ClientBulkDelete do allow(k.ui).to receive(:confirm).and_return(knife_confirm) allow(k.ui).to receive(:confirm_without_exit).and_return(knife_confirm) k - } + end let(:name_args) { [ "." ] } let(:option_args) { {} } @@ -41,7 +41,7 @@ describe Chef::Knife::ClientBulkDelete do let(:knife_confirm) { true } let(:nonvalidator_client_names) { %w{tim dan stephen} } - let(:nonvalidator_clients) { + let(:nonvalidator_clients) do clients = Hash.new nonvalidator_client_names.each do |client_name| @@ -52,10 +52,10 @@ describe Chef::Knife::ClientBulkDelete do end clients - } + end let(:validator_client_names) { %w{myorg-validator} } - let(:validator_clients) { + let(:validator_clients) do clients = Hash.new validator_client_names.each do |validator_client_name| @@ -67,12 +67,12 @@ describe Chef::Knife::ClientBulkDelete do end clients - } + end let(:client_names) { nonvalidator_client_names + validator_client_names } - let(:clients) { + let(:clients) do nonvalidator_clients.merge(validator_clients) - } + end before(:each) do allow(Chef::ApiClientV1).to receive(:list).and_return(clients) diff --git a/spec/unit/knife/client_edit_spec.rb b/spec/unit/knife/client_edit_spec.rb index 584a94014c..e7c9030883 100644 --- a/spec/unit/knife/client_edit_spec.rb +++ b/spec/unit/knife/client_edit_spec.rb @@ -27,7 +27,7 @@ describe Chef::Knife::ClientEdit do end describe "run" do - let(:data) { + let(:data) do { "name" => "adam", "validator" => false, @@ -35,7 +35,7 @@ describe Chef::Knife::ClientEdit do "chef_type" => "client", "create_key" => true, } - } + end it "should edit the client" do allow(Chef::ApiClientV1).to receive(:load).with("adam").and_return(data) diff --git a/spec/unit/knife/configure_client_spec.rb b/spec/unit/knife/configure_client_spec.rb index 192da862d7..3ecb89f827 100644 --- a/spec/unit/knife/configure_client_spec.rb +++ b/spec/unit/knife/configure_client_spec.rb @@ -33,9 +33,9 @@ describe Chef::Knife::ConfigureClient do it "should print usage and exit when a directory is not provided" do expect(@knife).to receive(:show_usage) expect(@knife.ui).to receive(:fatal).with(/must provide the directory/) - expect { + expect do @knife.run - }.to raise_error SystemExit + end.to raise_error SystemExit end describe "when specifing a directory" do diff --git a/spec/unit/knife/cookbook_metadata_spec.rb b/spec/unit/knife/cookbook_metadata_spec.rb index 0e3fccfa7e..4b405d0842 100644 --- a/spec/unit/knife/cookbook_metadata_spec.rb +++ b/spec/unit/knife/cookbook_metadata_spec.rb @@ -128,9 +128,9 @@ describe Chef::Knife::CookbookMetadata do it "should print an error and exit when an #{description} syntax exception is encountered" do exception = klass.new("#{description} blah") allow(Chef::Cookbook::Metadata).to receive(:new).and_raise(exception) - expect { + expect do @knife.generate_metadata_from_file("foobar", "#{@cookbook_dir}/foobar/metadata.rb") - }.to raise_error(SystemExit) + end.to raise_error(SystemExit) expect(@stderr.string).to match /error: the cookbook 'foobar' contains invalid or obsolete metadata syntax/im expect(@stderr.string).to match /in #{@cookbook_dir}\/foobar\/metadata\.rb/im expect(@stderr.string).to match /#{description} blah/im @@ -166,9 +166,9 @@ describe Chef::Knife::CookbookMetadata do and_return(@json_data) exception = klass.new("#{description} blah") allow(Chef::Cookbook::Metadata).to receive(:validate_json).and_raise(exception) - expect { + expect do @knife.validate_metadata_json(@cookbook_dir, "foobar") - }.to raise_error(SystemExit) + end.to raise_error(SystemExit) expect(@stderr.string).to match /error: the cookbook 'foobar' contains invalid or obsolete metadata syntax/im expect(@stderr.string).to match /in #{@cookbook_dir}\/foobar\/metadata\.json/im expect(@stderr.string).to match /#{description} blah/im diff --git a/spec/unit/knife/cookbook_site_install_spec.rb b/spec/unit/knife/cookbook_site_install_spec.rb index 1549245ea3..d93af10761 100644 --- a/spec/unit/knife/cookbook_site_install_spec.rb +++ b/spec/unit/knife/cookbook_site_install_spec.rb @@ -24,16 +24,17 @@ describe Chef::Knife::CookbookSiteInstall do let(:stderr) { StringIO.new } let(:downloader) { Hash.new } let(:archive) { double(Mixlib::Archive, extract: true) } - let(:repo) { double(:sanity_check => true, :reset_to_default_state => true, - :prepare_to_import => true, :finalize_updates_to => true, - :merge_updates_from => true) } - let(:install_path) { + let(:repo) do + double(:sanity_check => true, :reset_to_default_state => true, + :prepare_to_import => true, :finalize_updates_to => true, + :merge_updates_from => true) end + let(:install_path) do if Chef::Platform.windows? "C:/tmp/chef" else "/var/tmp/chef" end - } + end before(:each) do require "chef/knife/core/cookbook_scm_repo" diff --git a/spec/unit/knife/cookbook_site_share_spec.rb b/spec/unit/knife/cookbook_site_share_spec.rb index 9339114d2a..823eff8b04 100644 --- a/spec/unit/knife/cookbook_site_share_spec.rb +++ b/spec/unit/knife/cookbook_site_share_spec.rb @@ -83,11 +83,11 @@ describe Chef::Knife::CookbookSiteShare do @knife.run end - it "should print error and exit when given only 1 argument and cannot determine category" do + it "should use a default category when given only 1 argument and cannot determine category" do @knife.name_args = ["cookbook_name"] - expect(@noauth_rest).to receive(:get).with("https://supermarket.chef.io/api/v1/cookbooks/cookbook_name").and_return(@bad_category_response) - expect(@knife.ui).to receive(:fatal) - expect { @knife.run }.to raise_error(SystemExit) + expect(@noauth_rest).to receive(:get).with("https://supermarket.chef.io/api/v1/cookbooks/cookbook_name") { raise Net::HTTPServerException.new("404 Not Found", OpenStruct.new(code: "404")) } + expect(@knife).to receive(:do_upload) + expect { @knife.run }.to_not raise_error end it "should print error and exit when given only 1 argument and Chef::ServerAPI throws an exception" do @@ -199,8 +199,8 @@ describe Chef::Knife::CookbookSiteShare do response_text = Chef::JSONCompat.to_json({ :system_error => "Your call was dropped", :reason => "There's a map for that" }) allow(@upload_response).to receive(:body).and_return(response_text) allow(@upload_response).to receive(:code).and_return(500) - expect(@knife.ui).to receive(:error).with(/#{Regexp.escape(response_text)}/)#.ordered - expect(@knife.ui).to receive(:error).with(/Unknown error/)#.ordered + expect(@knife.ui).to receive(:error).with(/#{Regexp.escape(response_text)}/) #.ordered + expect(@knife.ui).to receive(:error).with(/Unknown error/) #.ordered expect { @knife.run }.to raise_error(SystemExit) end diff --git a/spec/unit/knife/core/hashed_command_loader_spec.rb b/spec/unit/knife/core/hashed_command_loader_spec.rb index 081f9deae5..53bd81f4f7 100644 --- a/spec/unit/knife/core/hashed_command_loader_spec.rb +++ b/spec/unit/knife/core/hashed_command_loader_spec.rb @@ -22,7 +22,7 @@ describe Chef::Knife::SubcommandLoader::HashedCommandLoader do allow(ChefConfig).to receive(:windows?) { false } end - let(:plugin_manifest) { + let(:plugin_manifest) do { "_autogenerated_command_paths" => { "plugins_paths" => { @@ -39,11 +39,12 @@ describe Chef::Knife::SubcommandLoader::HashedCommandLoader do }, }, } - } + end - let(:loader) { Chef::Knife::SubcommandLoader::HashedCommandLoader.new( + let(:loader) do + Chef::Knife::SubcommandLoader::HashedCommandLoader.new( File.join(CHEF_SPEC_DATA, "knife-site-subcommands"), - plugin_manifest)} + plugin_manifest) end describe "#list_commands" do before do diff --git a/spec/unit/knife/core/node_editor_spec.rb b/spec/unit/knife/core/node_editor_spec.rb index 19af419632..ce169a77dd 100644 --- a/spec/unit/knife/core/node_editor_spec.rb +++ b/spec/unit/knife/core/node_editor_spec.rb @@ -41,7 +41,7 @@ describe Chef::Knife::NodeEditor do subject { described_class.new(node, ui, config) } - describe '#view' do + describe "#view" do it "returns a Hash with only the name, chef_environment, normal, " + "policy_name, policy_group, and run_list properties" do expected = node_data.select do |key,| @@ -61,7 +61,7 @@ describe Chef::Knife::NodeEditor do end end - describe '#apply_updates' do + describe "#apply_updates" do context "when the node name is changed" do before(:each) do allow(ui).to receive(:warn) @@ -143,7 +143,7 @@ describe Chef::Knife::NodeEditor do end end - describe '#updated?' do + describe "#updated?" do context "before the node has been edited" do it "returns false" do expect(subject.updated?).to be false diff --git a/spec/unit/knife/core/ui_spec.rb b/spec/unit/knife/core/ui_spec.rb index 0b9547fc1f..9f525f22f0 100644 --- a/spec/unit/knife/core/ui_spec.rb +++ b/spec/unit/knife/core/ui_spec.rb @@ -500,9 +500,9 @@ EOM shared_examples_for "confirm with negative answer" do it "confirm should exit 3" do - expect { + expect do run_confirm - }.to raise_error(SystemExit) { |e| expect(e.status).to eq(3) } + end.to raise_error(SystemExit) { |e| expect(e.status).to eq(3) } end it "confirm_without_exit should return false" do diff --git a/spec/unit/knife/data_bag_from_file_spec.rb b/spec/unit/knife/data_bag_from_file_spec.rb index 0b6f389e87..3bea392ae2 100644 --- a/spec/unit/knife/data_bag_from_file_spec.rb +++ b/spec/unit/knife/data_bag_from_file_spec.rb @@ -52,7 +52,7 @@ describe Chef::Knife::DataBagFromFile do k end - let(:tmp_dir) { Dir.mktmpdir } + let(:tmp_dir) { make_canonical_temp_directory } let(:db_folder) { File.join(tmp_dir, data_bags_path, bag_name) } let(:db_file) { Tempfile.new(["data_bag_from_file_test", ".json"], db_folder) } let(:db_file2) { Tempfile.new(["data_bag_from_file_test2", ".json"], db_folder) } @@ -72,11 +72,12 @@ describe Chef::Knife::DataBagFromFile do let(:loader) { double("Knife::Core::ObjectLoader") } let(:data_bags_path) { "data_bags" } - let(:plain_data) { { + let(:plain_data) do + { "id" => "item_name", "greeting" => "hello", "nested" => { "a1" => [1, 2, 3], "a2" => { "b1" => true } }, - } } + } end let(:enc_data) { Chef::EncryptedDataBagItem.encrypt_data_bag_item(plain_data, secret) } let(:rest) { double("Chef::ServerAPI") } diff --git a/spec/unit/knife/data_bag_show_spec.rb b/spec/unit/knife/data_bag_show_spec.rb index 0672b8bb33..ece7f5bf78 100644 --- a/spec/unit/knife/data_bag_show_spec.rb +++ b/spec/unit/knife/data_bag_show_spec.rb @@ -45,8 +45,9 @@ describe Chef::Knife::DataBagShow do let(:bag_name) { "sudoing_admins" } let(:item_name) { "ME" } - let(:data_bag_contents) { { "id" => "id", "baz" => "http://localhost:4000/data/bag_o_data/baz", - "qux" => "http://localhost:4000/data/bag_o_data/qux" } } + let(:data_bag_contents) do + { "id" => "id", "baz" => "http://localhost:4000/data/bag_o_data/baz", + "qux" => "http://localhost:4000/data/bag_o_data/qux" } end let(:enc_hash) { Chef::EncryptedDataBagItem.encrypt_data_bag_item(data_bag_contents, secret) } let(:data_bag) { Chef::DataBagItem.from_hash(data_bag_contents) } let(:data_bag_with_encoded_hash) { Chef::DataBagItem.from_hash(enc_hash) } diff --git a/spec/unit/knife/key_create_spec.rb b/spec/unit/knife/key_create_spec.rb index 146b6a904b..5b00c6ea31 100644 --- a/spec/unit/knife/key_create_spec.rb +++ b/spec/unit/knife/key_create_spec.rb @@ -73,7 +73,7 @@ describe "key create commands that inherit knife" do end describe Chef::Knife::KeyCreate do - let(:public_key) { + let(:public_key) do "-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvPo+oNPB7uuNkws0fC02 KxSwdyqPLu0fhI1pOweNKAZeEIiEz2PkybathHWy8snSXGNxsITkf3eyvIIKa8OZ @@ -83,15 +83,15 @@ IjSmiN/ihHtlhV/VSnBJ5PzT/lRknlrJ4kACoz7Pq9jv+aAx5ft/xE9yDa2DYs0q Tfuc9dUYsFjptWYrV6pfEQ+bgo1OGBXORBFcFL+2D7u9JYquKrMgosznHoEkQNLo 0wIDAQAB -----END PUBLIC KEY-----" - } + end let(:config) { Hash.new } let(:actor) { "charmander" } let(:ui) { instance_double("Chef::Knife::UI") } shared_examples_for "key create run command" do - let(:key_create_object) { + let(:key_create_object) do described_class.new(actor, actor_field_name, ui, config) - } + end context "when public_key and key_name weren't passed" do it "raises a Chef::Exceptions::KeyCommandInputError with the proper error message" do @@ -100,11 +100,11 @@ Tfuc9dUYsFjptWYrV6pfEQ+bgo1OGBXORBFcFL+2D7u9JYquKrMgosznHoEkQNLo end context "when the command is run" do - let(:expected_hash) { + let(:expected_hash) do { actor_field_name => "charmander", } - } + end before do allow(File).to receive(:read).and_return(public_key) @@ -120,14 +120,14 @@ Tfuc9dUYsFjptWYrV6pfEQ+bgo1OGBXORBFcFL+2D7u9JYquKrMgosznHoEkQNLo context "when a valid hash is passed" do let(:key_name) { "charmander-key" } let(:valid_expiration_date) { "2020-12-24T21:00:00Z" } - let(:expected_hash) { + let(:expected_hash) do { actor_field_name => "charmander", "public_key" => public_key, "expiration_date" => valid_expiration_date, "key_name" => key_name, } - } + end before do key_create_object.config[:public_key] = "public_key_path" key_create_object.config[:expiration_Date] = valid_expiration_date, @@ -141,12 +141,12 @@ Tfuc9dUYsFjptWYrV6pfEQ+bgo1OGBXORBFcFL+2D7u9JYquKrMgosznHoEkQNLo end context "when public_key is passed" do - let(:expected_hash) { + let(:expected_hash) do { actor_field_name => "charmander", "public_key" => public_key, } - } + end before do key_create_object.config[:public_key] = "public_key_path" end @@ -158,13 +158,13 @@ Tfuc9dUYsFjptWYrV6pfEQ+bgo1OGBXORBFcFL+2D7u9JYquKrMgosznHoEkQNLo end # when public_key is passed context "when public_key isn't passed and key_name is" do - let(:expected_hash) { + let(:expected_hash) do { actor_field_name => "charmander", "name" => "charmander-key", "create_key" => true, } - } + end before do key_create_object.config[:key_name] = "charmander-key" end @@ -176,13 +176,13 @@ Tfuc9dUYsFjptWYrV6pfEQ+bgo1OGBXORBFcFL+2D7u9JYquKrMgosznHoEkQNLo end context "when the server returns a private key" do - let(:expected_hash) { + let(:expected_hash) do { actor_field_name => "charmander", "public_key" => public_key, "private_key" => "super_private", } - } + end before do key_create_object.config[:public_key] = "public_key_path" diff --git a/spec/unit/knife/key_delete_spec.rb b/spec/unit/knife/key_delete_spec.rb index 3da5a9762a..0176f3c71e 100644 --- a/spec/unit/knife/key_delete_spec.rb +++ b/spec/unit/knife/key_delete_spec.rb @@ -80,9 +80,9 @@ describe Chef::Knife::KeyDelete do let(:ui) { instance_double("Chef::Knife::UI") } shared_examples_for "key delete run command" do - let(:key_delete_object) { + let(:key_delete_object) do described_class.new(keyname, actor, actor_field_name, ui) - } + end before do allow_any_instance_of(Chef::Key).to receive(:destroy) diff --git a/spec/unit/knife/key_edit_spec.rb b/spec/unit/knife/key_edit_spec.rb index 9195e97135..244d8bdcc7 100644 --- a/spec/unit/knife/key_edit_spec.rb +++ b/spec/unit/knife/key_edit_spec.rb @@ -75,7 +75,7 @@ describe "key edit commands that inherit knife" do end describe Chef::Knife::KeyEdit do - let(:public_key) { + let(:public_key) do "-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvPo+oNPB7uuNkws0fC02 KxSwdyqPLu0fhI1pOweNKAZeEIiEz2PkybathHWy8snSXGNxsITkf3eyvIIKa8OZ @@ -85,23 +85,23 @@ IjSmiN/ihHtlhV/VSnBJ5PzT/lRknlrJ4kACoz7Pq9jv+aAx5ft/xE9yDa2DYs0q Tfuc9dUYsFjptWYrV6pfEQ+bgo1OGBXORBFcFL+2D7u9JYquKrMgosznHoEkQNLo 0wIDAQAB -----END PUBLIC KEY-----" - } + end let(:config) { Hash.new } let(:actor) { "charmander" } let(:keyname) { "charmander-key" } let(:ui) { instance_double("Chef::Knife::UI") } shared_examples_for "key edit run command" do - let(:key_edit_object) { + let(:key_edit_object) do described_class.new(keyname, actor, actor_field_name, ui, config) - } + end context "when the command is run" do - let(:expected_hash) { + let(:expected_hash) do { actor_field_name => "charmander", } - } + end let(:new_keyname) { "charizard-key" } before do @@ -126,12 +126,12 @@ Tfuc9dUYsFjptWYrV6pfEQ+bgo1OGBXORBFcFL+2D7u9JYquKrMgosznHoEkQNLo end context "when key_name is passed" do - let(:expected_hash) { + let(:expected_hash) do { actor_field_name => "charmander", "name" => new_keyname, } - } + end before do key_edit_object.config[:key_name] = new_keyname allow_any_instance_of(Chef::Key).to receive(:update) @@ -155,14 +155,14 @@ Tfuc9dUYsFjptWYrV6pfEQ+bgo1OGBXORBFcFL+2D7u9JYquKrMgosznHoEkQNLo end context "when public_key, key_name, and expiration_date are passed" do - let(:expected_hash) { + let(:expected_hash) do { actor_field_name => "charmander", "public_key" => public_key, "name" => new_keyname, "expiration_date" => "infinity", } - } + end before do key_edit_object.config[:public_key] = "this-public-key" key_edit_object.config[:key_name] = new_keyname @@ -177,12 +177,12 @@ Tfuc9dUYsFjptWYrV6pfEQ+bgo1OGBXORBFcFL+2D7u9JYquKrMgosznHoEkQNLo end context "when create_key is passed" do - let(:expected_hash) { + let(:expected_hash) do { actor_field_name => "charmander", "create_key" => true, } - } + end before do key_edit_object.config[:create_key] = true @@ -196,12 +196,12 @@ Tfuc9dUYsFjptWYrV6pfEQ+bgo1OGBXORBFcFL+2D7u9JYquKrMgosznHoEkQNLo end context "when public_key is passed" do - let(:expected_hash) { + let(:expected_hash) do { actor_field_name => "charmander", "public_key" => public_key, } - } + end before do allow(key_edit_object).to receive(:update_key_from_hash).and_return(Chef::Key.from_hash(expected_hash)) key_edit_object.config[:public_key] = "public_key_path" @@ -214,13 +214,13 @@ Tfuc9dUYsFjptWYrV6pfEQ+bgo1OGBXORBFcFL+2D7u9JYquKrMgosznHoEkQNLo end # when public_key is passed context "when the server returns a private key" do - let(:expected_hash) { + let(:expected_hash) do { actor_field_name => "charmander", "public_key" => public_key, "private_key" => "super_private", } - } + end before do allow(key_edit_object).to receive(:update_key_from_hash).and_return(Chef::Key.from_hash(expected_hash)) diff --git a/spec/unit/knife/key_list_spec.rb b/spec/unit/knife/key_list_spec.rb index 2d4f0a07bb..82fd1e4a09 100644 --- a/spec/unit/knife/key_list_spec.rb +++ b/spec/unit/knife/key_list_spec.rb @@ -78,9 +78,9 @@ describe Chef::Knife::KeyList do let(:ui) { instance_double("Chef::Knife::UI") } shared_examples_for "key list run command" do - let(:key_list_object) { + let(:key_list_object) do described_class.new(actor, list_method, ui, config) - } + end before do allow(Chef::Key).to receive(list_method).and_return(http_response) @@ -191,26 +191,26 @@ describe Chef::Knife::KeyList do context "when list_method is :list_by_user" do it_should_behave_like "key list run command" do let(:list_method) { :list_by_user } - let(:http_response) { + let(:http_response) do [ { "uri" => "https://api.opscode.piab/users/charmander/keys/non-expired1", "name" => "non-expired1", "expired" => false }, { "uri" => "https://api.opscode.piab/users/charmander/keys/non-expired2", "name" => "non-expired2", "expired" => false }, { "uri" => "https://api.opscode.piab/users/mary/keys/out-of-date", "name" => "out-of-date", "expired" => true }, ] - } + end end end context "when list_method is :list_by_client" do it_should_behave_like "key list run command" do let(:list_method) { :list_by_client } - let(:http_response) { + let(:http_response) do [ { "uri" => "https://api.opscode.piab/organizations/pokemon/clients/charmander/keys/non-expired1", "name" => "non-expired1", "expired" => false }, { "uri" => "https://api.opscode.piab/organizations/pokemon/clients/charmander/keys/non-expired2", "name" => "non-expired2", "expired" => false }, { "uri" => "https://api.opscode.piab/organizations/pokemon/clients/mary/keys/out-of-date", "name" => "out-of-date", "expired" => true }, ] - } + end end end end diff --git a/spec/unit/knife/key_show_spec.rb b/spec/unit/knife/key_show_spec.rb index c161efbe0d..139d4f91a2 100644 --- a/spec/unit/knife/key_show_spec.rb +++ b/spec/unit/knife/key_show_spec.rb @@ -78,19 +78,19 @@ describe Chef::Knife::KeyShow do let(:actor) { "charmander" } let(:keyname) { "charmander" } let(:ui) { instance_double("Chef::Knife::UI") } - let(:expected_hash) { + let(:expected_hash) do { actor_field_name => "charmander", "name" => "charmander-key", "public_key" => "some-public-key", "expiration_date" => "infinity", } - } + end shared_examples_for "key show run command" do - let(:key_show_object) { + let(:key_show_object) do described_class.new(keyname, actor, load_method, ui) - } + end before do allow(key_show_object).to receive(:display_output) diff --git a/spec/unit/knife/status_spec.rb b/spec/unit/knife/status_spec.rb index 473598fd85..c87ea3ad17 100644 --- a/spec/unit/knife/status_spec.rb +++ b/spec/unit/knife/status_spec.rb @@ -34,10 +34,11 @@ describe Chef::Knife::Status do end describe "run" do - let(:opts) {{ filter_result: + let(:opts) do + { filter_result: { name: ["name"], ipaddress: ["ipaddress"], ohai_time: ["ohai_time"], ec2: ["ec2"], run_list: ["run_list"], platform: ["platform"], - platform_version: ["platform_version"], chef_environment: ["chef_environment"] } }} + platform_version: ["platform_version"], chef_environment: ["chef_environment"] } } end it "should default to searching for everything" do expect(@query).to receive(:search).with(:node, "*:*", opts) diff --git a/spec/unit/knife/user_create_spec.rb b/spec/unit/knife/user_create_spec.rb index e708d2d1ad..07d72fd05a 100644 --- a/spec/unit/knife/user_create_spec.rb +++ b/spec/unit/knife/user_create_spec.rb @@ -24,13 +24,13 @@ Chef::Knife::UserCreate.load_deps describe Chef::Knife::UserCreate do let(:knife) { Chef::Knife::UserCreate.new } - let(:stderr) { + let(:stderr) do StringIO.new - } + end - let(:stdout) { + let(:stdout) do StringIO.new - } + end before(:each) do allow(knife.ui).to receive(:stdout).and_return(stdout) diff --git a/spec/unit/knife_spec.rb b/spec/unit/knife_spec.rb index ec1e59d863..f0ec45d59a 100644 --- a/spec/unit/knife_spec.rb +++ b/spec/unit/knife_spec.rb @@ -159,12 +159,13 @@ describe Chef::Knife do describe "the headers include X-Remote-Request-Id" do - let(:headers) {{ "Accept" => "application/json", - "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3", - "X-Chef-Version" => Chef::VERSION, - "Host" => "api.opscode.piab", - "X-REMOTE-REQUEST-ID" => request_id, - }} + let(:headers) do + { "Accept" => "application/json", + "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3", + "X-Chef-Version" => Chef::VERSION, + "Host" => "api.opscode.piab", + "X-REMOTE-REQUEST-ID" => request_id, + } end let(:request_id) { "1234" } diff --git a/spec/unit/lwrp_spec.rb b/spec/unit/lwrp_spec.rb index 6574a91f13..0689d99647 100644 --- a/spec/unit/lwrp_spec.rb +++ b/spec/unit/lwrp_spec.rb @@ -28,13 +28,13 @@ describe "LWRP" do include Chef::Mixin::ConvertToClassName before do - @original_VERBOSE = $VERBOSE + @original_verbose = $VERBOSE $VERBOSE = nil Chef::Resource::LWRPBase.class_eval { @loaded_lwrps = {} } end after do - $VERBOSE = @original_VERBOSE + $VERBOSE = @original_verbose end def get_lwrp(name) @@ -232,9 +232,9 @@ describe "LWRP" do end it "allows to user to user the resource_name" do - expect { + expect do klass.resource_name(:foo) - }.to_not raise_error + end.to_not raise_error end it "returns the set value for the resource" do @@ -741,7 +741,7 @@ describe "LWRP" do end end - let(:recipe) { + let(:recipe) do cookbook_repo = File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "cookbooks")) cookbook_loader = Chef::CookbookLoader.new(cookbook_repo) cookbook_loader.load_cookbooks @@ -750,7 +750,7 @@ describe "LWRP" do events = Chef::EventDispatch::Dispatcher.new run_context = Chef::RunContext.new(node, cookbook_collection, events) Chef::Recipe.new("hjk", "test", run_context) - } + end it "lets you extend the recipe DSL" do expect(Chef::Recipe).to receive(:include).with(MyAwesomeDSLExensionClass) diff --git a/spec/unit/mixin/api_version_request_handling_spec.rb b/spec/unit/mixin/api_version_request_handling_spec.rb index 13b729538c..191dee643b 100644 --- a/spec/unit/mixin/api_version_request_handling_spec.rb +++ b/spec/unit/mixin/api_version_request_handling_spec.rb @@ -50,12 +50,12 @@ describe Chef::Mixin::ApiVersionRequestHandling do context "when x-ops-server-api-version header exists" do let(:min_server_version) { 2 } let(:max_server_version) { 4 } - let(:return_hash) { + let(:return_hash) do { "min_version" => min_server_version, "max_version" => max_server_version, } - } + end before(:each) do allow(response).to receive(:[]).with("x-ops-server-api-version").and_return(Chef::JSONCompat.to_json(return_hash)) diff --git a/spec/unit/mixin/command_spec.rb b/spec/unit/mixin/command_spec.rb index 0c2f6da188..e9f0dacad6 100644 --- a/spec/unit/mixin/command_spec.rb +++ b/spec/unit/mixin/command_spec.rb @@ -49,22 +49,24 @@ describe Chef::Mixin::Command, :volatile do end it "should end when the child process reads from STDIN and a block is given" do - expect {Timeout.timeout(10) do - popen4("ruby -e 'while gets; end'", :waitlast => true) do |pid, stdin, stdout, stderr| - (1..5).each { |i| stdin.puts "#{i}" } + expect do + Timeout.timeout(10) do + popen4("ruby -e 'while gets; end'", :waitlast => true) do |pid, stdin, stdout, stderr| + (1..5).each { |i| stdin.puts "#{i}" } + end end - end - }.not_to raise_error + end.not_to raise_error end describe "when a process detaches but doesn't close STDOUT and STDERR [CHEF-584]" do it "returns immediately after the first child process exits" do - expect {Timeout.timeout(10) do - evil_forker = "exit if fork; 10.times { sleep 1}" - popen4("ruby -e '#{evil_forker}'") do |pid, stdin, stdout, stderr| - end - end}.not_to raise_error + expect do + Timeout.timeout(10) do + evil_forker = "exit if fork; 10.times { sleep 1}" + popen4("ruby -e '#{evil_forker}'") do |pid, stdin, stdout, stderr| + end + end end.not_to raise_error end end @@ -92,10 +94,11 @@ describe Chef::Mixin::Command, :volatile do # btm # Serdar - During Solaris tests, we've seen that processes # are taking a long time to exit. Bumping timeout now to 10. - expect {Timeout.timeout(10) do - evil_forker = "exit if fork; 10.times { sleep 1}" - run_command(:command => "ruby -e '#{evil_forker}'") - end}.not_to raise_error + expect do + Timeout.timeout(10) do + evil_forker = "exit if fork; 10.times { sleep 1}" + run_command(:command => "ruby -e '#{evil_forker}'") + end end.not_to raise_error end end diff --git a/spec/unit/mixin/deprecation_spec.rb b/spec/unit/mixin/deprecation_spec.rb index 8f22b09295..8707c6476e 100644 --- a/spec/unit/mixin/deprecation_spec.rb +++ b/spec/unit/mixin/deprecation_spec.rb @@ -36,7 +36,7 @@ describe Chef::Mixin do end it "warns when accessing the deprecated constant" do - Chef::Mixin::DeprecatedClass + Chef::Mixin::DeprecatedClass # rubocop:disable Lint/Void expect(@log_io.string).to include("This is a test deprecation") end end diff --git a/spec/unit/mixin/homebrew_user_spec.rb b/spec/unit/mixin/homebrew_user_spec.rb index de72f6b935..c9a6e6e909 100644 --- a/spec/unit/mixin/homebrew_user_spec.rb +++ b/spec/unit/mixin/homebrew_user_spec.rb @@ -51,11 +51,11 @@ describe Chef::Mixin::HomebrewUser do let(:user) { nil } let(:brew_owner) { 2001 } let(:default_brew_path) { "/usr/local/bin/brew" } - let(:stat_double) { + let(:stat_double) do d = double() expect(d).to receive(:uid).and_return(brew_owner) d - } + end context "debug statement prints owner name" do diff --git a/spec/unit/mixin/params_validate_spec.rb b/spec/unit/mixin/params_validate_spec.rb index dcee123982..0cafb925c8 100644 --- a/spec/unit/mixin/params_validate_spec.rb +++ b/spec/unit/mixin/params_validate_spec.rb @@ -56,7 +56,7 @@ describe Chef::Mixin::ParamsValidate do end it "should allow you to check what kind_of? thing an argument is with kind_of" do - expect { + expect do @vo.validate( { :one => "string" }, { @@ -65,9 +65,9 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.not_to raise_error + end.not_to raise_error - expect { + expect do @vo.validate( { :one => "string" }, { @@ -76,11 +76,11 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should allow you to specify an argument is required with required" do - expect { + expect do @vo.validate( { :one => "string" }, { @@ -89,9 +89,9 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.not_to raise_error + end.not_to raise_error - expect { + expect do @vo.validate( { :two => "string" }, { @@ -100,9 +100,9 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) - expect { + expect do @vo.validate( { :two => "string" }, { @@ -111,11 +111,11 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.not_to raise_error + end.not_to raise_error end it "should allow you to specify whether an object has a method with respond_to" do - expect { + expect do @vo.validate( { :one => @vo }, { @@ -124,9 +124,9 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.not_to raise_error + end.not_to raise_error - expect { + expect do @vo.validate( { :one => @vo }, { @@ -135,11 +135,11 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should allow you to specify whether an object has all the given methods with respond_to and an array" do - expect { + expect do @vo.validate( { :one => @vo }, { @@ -148,9 +148,9 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.not_to raise_error + end.not_to raise_error - expect { + expect do @vo.validate( { :one => @vo }, { @@ -159,7 +159,7 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should let you set a default value with default => value" do @@ -173,7 +173,7 @@ describe Chef::Mixin::ParamsValidate do end it "should let you check regular expressions" do - expect { + expect do @vo.validate( { :one => "is good" }, { @@ -182,9 +182,9 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.not_to raise_error + end.not_to raise_error - expect { + expect do @vo.validate( { :one => "is good" }, { @@ -193,44 +193,44 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should let you specify your own callbacks" do - expect { + expect do @vo.validate( { :one => "is good" }, { :one => { :callbacks => { - "should be equal to is good" => lambda { |a| + "should be equal to is good" => lambda do |a| a == "is good" - }, + end, }, }, } ) - }.not_to raise_error + end.not_to raise_error - expect { + expect do @vo.validate( { :one => "is bad" }, { :one => { :callbacks => { - "should be equal to 'is good'" => lambda { |a| + "should be equal to 'is good'" => lambda do |a| a == "is good" - }, + end, }, }, } ) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should let you combine checks" do args = { :one => "is good", :two => "is bad" } - expect { + expect do @vo.validate( args, { @@ -239,9 +239,9 @@ describe Chef::Mixin::ParamsValidate do :respond_to => [ :to_s, :upcase ], :regex => /^is good/, :callbacks => { - "should be your friend" => lambda { |a| + "should be your friend" => lambda do |a| a == "is good" - }, + end, }, :required => true, }, @@ -252,9 +252,9 @@ describe Chef::Mixin::ParamsValidate do :three => { :default => "neato mosquito" }, } ) - }.not_to raise_error + end.not_to raise_error expect(args[:three]).to eq("neato mosquito") - expect { + expect do @vo.validate( args, { @@ -263,9 +263,9 @@ describe Chef::Mixin::ParamsValidate do :respond_to => [ :to_s, :upcase ], :regex => /^is good/, :callbacks => { - "should be your friend" => lambda { |a| + "should be your friend" => lambda do |a| a == "is good" - }, + end, }, :required => true, }, @@ -276,11 +276,12 @@ describe Chef::Mixin::ParamsValidate do :three => { :default => "neato mosquito" }, } ) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should raise an ArgumentError if the validation map has an unknown check" do - expect { @vo.validate( + expect do + @vo.validate( { :one => "two" }, { :one => { @@ -288,17 +289,17 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should accept keys that are strings in the options" do - expect { + expect do @vo.validate({ "one" => "two" }, { :one => { :regex => /^two$/ } }) - }.not_to raise_error + end.not_to raise_error end it "should allow an array to kind_of" do - expect { + expect do @vo.validate( { :one => "string" }, { @@ -307,8 +308,8 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.not_to raise_error - expect { + end.not_to raise_error + expect do @vo.validate( { :one => ["string"] }, { @@ -317,8 +318,8 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.not_to raise_error - expect { + end.not_to raise_error + expect do @vo.validate( { :one => Hash.new }, { @@ -327,7 +328,7 @@ describe Chef::Mixin::ParamsValidate do }, } ) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "asserts that a value returns false from a predicate method" do @@ -354,15 +355,15 @@ describe Chef::Mixin::ParamsValidate do end it "should raise an ArgumentError when argument is nil and required is true" do - expect { + expect do @vo.set_or_return(:test, nil, { :required => true }) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should not raise an error when argument is nil and required is false" do - expect { + expect do @vo.set_or_return(:test, nil, { :required => false }) - }.not_to raise_error + end.not_to raise_error end it "should set and return @name, then return @name for foo when argument is nil" do diff --git a/spec/unit/mixin/powershell_out_spec.rb b/spec/unit/mixin/powershell_out_spec.rb index eae5b033f1..8e5f3588ce 100644 --- a/spec/unit/mixin/powershell_out_spec.rb +++ b/spec/unit/mixin/powershell_out_spec.rb @@ -22,9 +22,9 @@ describe Chef::Mixin::PowershellOut do let(:shell_out_class) { Class.new { include Chef::Mixin::PowershellOut } } subject(:object) { shell_out_class.new } let(:architecture) { "something" } - let(:flags) { + let(:flags) do "-NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrestricted -InputFormat None" - } + end describe "#powershell_out" do it "runs a command and returns the shell_out object" do diff --git a/spec/unit/mixin/powershell_type_coercions_spec.rb b/spec/unit/mixin/powershell_type_coercions_spec.rb index 7f2ecb94e2..6f52abccfb 100644 --- a/spec/unit/mixin/powershell_type_coercions_spec.rb +++ b/spec/unit/mixin/powershell_type_coercions_spec.rb @@ -27,12 +27,12 @@ end describe Chef::Mixin::PowershellTypeCoercions do let (:test_class) { Chef::PSTypeTester.new } - describe '#translate_type' do + describe "#translate_type" do it "single quotes a string" do expect(test_class.translate_type("foo")).to eq("'foo'") end - ["'", '"', '#', "`"].each do |c| + ["'", '"', "#", "`"].each do |c| it "base64 encodes a string that contains #{c}" do expect(test_class.translate_type("#{c}")).to match(Base64.strict_encode64(c)) end diff --git a/spec/unit/mixin/shell_out_spec.rb b/spec/unit/mixin/shell_out_spec.rb index 191ea920c0..bf74ff410e 100644 --- a/spec/unit/mixin/shell_out_spec.rb +++ b/spec/unit/mixin/shell_out_spec.rb @@ -25,7 +25,7 @@ require "spec_helper" describe Chef::Mixin::ShellOut do let(:shell_out_class) { Class.new { include Chef::Mixin::ShellOut } } subject(:shell_out_obj) { shell_out_class.new } - describe '#run_command_compatible_options' do + describe "#run_command_compatible_options" do subject { shell_out_obj.run_command_compatible_options(command_args) } let(:command_args) { [ cmd, options ] } let(:cmd) { "echo '#{rand(1000)}'" } diff --git a/spec/unit/mixin/xml_escape_spec.rb b/spec/unit/mixin/xml_escape_spec.rb index 903c91164e..495ad0662c 100644 --- a/spec/unit/mixin/xml_escape_spec.rb +++ b/spec/unit/mixin/xml_escape_spec.rb @@ -37,7 +37,7 @@ describe Chef::Mixin::XMLEscape do end it "does not modify ASCII strings" do - expect(@escaper.xml_escape('foobarbaz!@#$%^*()')).to eq('foobarbaz!@#$%^*()') + expect(@escaper.xml_escape("foobarbaz!@\#$%^*()")).to eq("foobarbaz!@\#$%^*()") end it "converts invalid bytes to asterisks" do @@ -45,10 +45,10 @@ describe Chef::Mixin::XMLEscape do end it "converts UTF-8 correctly" do - expect(@escaper.xml_escape("\xC2\xA9")).to eq('©') + expect(@escaper.xml_escape("\xC2\xA9")).to eq("©") end it "converts win 1252 characters correctly" do - expect(@escaper.xml_escape("#{0x80.chr}")).to eq('€') + expect(@escaper.xml_escape("#{0x80.chr}")).to eq("€") end end diff --git a/spec/unit/node_spec.rb b/spec/unit/node_spec.rb index 72731c927f..2c8fc4408b 100644 --- a/spec/unit/node_spec.rb +++ b/spec/unit/node_spec.rb @@ -1359,10 +1359,10 @@ describe Chef::Node do end include_examples "to_json equivalent to Chef::JSONCompat.to_json" do - let(:jsonable) { + let(:jsonable) do node.from_file(File.expand_path("nodes/test.example.com.rb", CHEF_SPEC_DATA)) node - } + end end end diff --git a/spec/unit/platform/query_helpers_spec.rb b/spec/unit/platform/query_helpers_spec.rb index 49da6a95f0..aa2b3c1f11 100644 --- a/spec/unit/platform/query_helpers_spec.rb +++ b/spec/unit/platform/query_helpers_spec.rb @@ -151,7 +151,7 @@ describe "Chef::Platform#supports_msi?" do end end -describe 'Chef::Platform#supports_dsc?' do +describe "Chef::Platform#supports_dsc?" do it "returns false if powershell is not present" do node = Chef::Node.new expect(Chef::Platform.supports_dsc?(node)).to be_falsey @@ -174,7 +174,7 @@ describe 'Chef::Platform#supports_dsc?' do end end -describe 'Chef::Platform#supports_dsc_invoke_resource?' do +describe "Chef::Platform#supports_dsc_invoke_resource?" do it "returns false if powershell is not present" do node = Chef::Node.new expect(Chef::Platform.supports_dsc_invoke_resource?(node)).to be_falsey @@ -195,7 +195,7 @@ describe 'Chef::Platform#supports_dsc_invoke_resource?' do end end -describe 'Chef::Platform#dsc_refresh_mode_disabled?' do +describe "Chef::Platform#dsc_refresh_mode_disabled?" do let(:node) { instance_double("Chef::Node") } let(:cmdlet) { instance_double("Chef::Util::Powershell::Cmdlet") } let(:cmdlet_result) { instance_double("Chef::Util::Powershell::CmdletResult") } diff --git a/spec/unit/property_spec.rb b/spec/unit/property_spec.rb index f5eb361426..50ff3434f6 100644 --- a/spec/unit/property_spec.rb +++ b/spec/unit/property_spec.rb @@ -1103,18 +1103,18 @@ describe "Chef::Resource.property" do context "property_type" do it "property_types validate their defaults" do - expect { + expect do module ::PropertySpecPropertyTypes include Chef::Mixin::Properties property_type(is: [:a, :b], default: :c) end - }.to raise_error(Chef::Exceptions::DeprecatedFeatureError, /Default value :c is invalid for property <property type>./) - expect { + end.to raise_error(Chef::Exceptions::DeprecatedFeatureError, /Default value :c is invalid for property <property type>./) + expect do module ::PropertySpecPropertyTypes include Chef::Mixin::Properties property_type(is: [:a, :b], default: :b) end - }.not_to raise_error + end.not_to raise_error end context "With property_type ABType (is: [:a, :b]) and CDType (is: [:c, :d])" do diff --git a/spec/unit/provider/cookbook_file_spec.rb b/spec/unit/provider/cookbook_file_spec.rb index b375784d00..f49cc7d3da 100644 --- a/spec/unit/provider/cookbook_file_spec.rb +++ b/spec/unit/provider/cookbook_file_spec.rb @@ -26,12 +26,12 @@ describe Chef::Provider::CookbookFile do let(:node) { double("Chef::Node") } let(:events) { double("Chef::Events").as_null_object } # mock all the methods let(:run_context) { double("Chef::RunContext", :node => node, :events => events) } - let(:enclosing_directory) { + let(:enclosing_directory) do canonicalize_path(File.expand_path(File.join(CHEF_SPEC_DATA, "templates"))) - } - let(:resource_path) { + end + let(:resource_path) do canonicalize_path(File.expand_path(File.join(enclosing_directory, "seattle.txt"))) - } + end # Subject diff --git a/spec/unit/provider/cron/unix_spec.rb b/spec/unit/provider/cron/unix_spec.rb index 83e0f431bf..5e1fcb35ab 100644 --- a/spec/unit/provider/cron/unix_spec.rb +++ b/spec/unit/provider/cron/unix_spec.rb @@ -91,9 +91,9 @@ describe Chef::Provider::Cron::Unix do let (:exitstatus) { 2 } it "should raise an exception if another error occurs" do - expect { + expect do provider.send(:read_crontab) - }.to raise_error(Chef::Exceptions::Cron, "Error determining state of #{new_resource.name}, exit: 2") + end.to raise_error(Chef::Exceptions::Cron, "Error determining state of #{new_resource.name}, exit: 2") end it "logs the crontab output to debug" do @@ -130,9 +130,9 @@ describe Chef::Provider::Cron::Unix do context "when writing the crontab fails" do let(:exitstatus) { 1 } it "should raise an exception if the command returns non-zero" do - expect { + expect do provider.send(:write_crontab, "Foo") - }.to raise_error(Chef::Exceptions::Cron, /Error updating state of #{new_resource.name}, exit: 1/) + end.to raise_error(Chef::Exceptions::Cron, /Error updating state of #{new_resource.name}, exit: 1/) end end end diff --git a/spec/unit/provider/cron_spec.rb b/spec/unit/provider/cron_spec.rb index 010b1b09f3..64916ef454 100644 --- a/spec/unit/provider/cron_spec.rb +++ b/spec/unit/provider/cron_spec.rb @@ -199,9 +199,9 @@ CRONTAB # Chef Name: foo[bar] (baz) 21 */4 * * * some_prog 1234567 CRONTAB - expect { + expect do @provider.load_current_resource - }.not_to raise_error + end.not_to raise_error end end @@ -462,10 +462,10 @@ CRONTAB @new_resource.environment "TEST" => "LOL" expect(@provider).to receive(:write_crontab).with(<<-ENDCRON) # Chef Name: cronhole some stuff -MAILTO=foo@example.com -PATH=/usr/bin:/my/custom/path -SHELL=/bin/foosh -HOME=/home/foo +MAILTO="foo@example.com" +PATH="/usr/bin:/my/custom/path" +SHELL="/bin/foosh" +HOME="/home/foo" TEST=LOL 30 * * * * /bin/true ENDCRON @@ -524,10 +524,10 @@ TEST=LOL # Another comment # Chef Name: cronhole some stuff -MAILTO=foo@example.com -PATH=/usr/bin:/my/custom/path -SHELL=/bin/foosh -HOME=/home/foo +MAILTO="foo@example.com" +PATH="/usr/bin:/my/custom/path" +SHELL="/bin/foosh" +HOME="/home/foo" TEST=LOL 30 * * * * /bin/true ENDCRON @@ -585,10 +585,10 @@ TEST=LOL 0 2 * * * /some/other/command # Chef Name: cronhole some stuff -MAILTO=foo@example.com -PATH=/usr/bin:/my/custom/path -SHELL=/bin/foosh -HOME=/home/foo +MAILTO="foo@example.com" +PATH="/usr/bin:/my/custom/path" +SHELL="/bin/foosh" +HOME="/home/foo" TEST=LOL 30 * * * * /bin/true # Chef Name: something else @@ -679,10 +679,10 @@ HOME=/home/foo 0 2 * * * /some/other/command # Chef Name: cronhole some stuff -MAILTO=foo@example.com -PATH=/usr/bin:/my/custom/path -SHELL=/bin/foosh -HOME=/home/foo +MAILTO="foo@example.com" +PATH="/usr/bin:/my/custom/path" +SHELL="/bin/foosh" +HOME="/home/foo" 30 * * * * /bin/true # Chef Name: something else diff --git a/spec/unit/provider/deploy_spec.rb b/spec/unit/provider/deploy_spec.rb index 62d9123e7b..e69714280c 100644 --- a/spec/unit/provider/deploy_spec.rb +++ b/spec/unit/provider/deploy_spec.rb @@ -167,9 +167,9 @@ describe Chef::Provider::Deploy do allow(@provider).to receive(:deploy) { raise "Unexpected error" } allow(@provider).to receive(:previous_release_path).and_return("previous_release") expect(@provider).not_to receive(:rollback) - expect { + expect do @provider.run_action(:deploy) - }.to raise_exception(RuntimeError, "Unexpected error") + end.to raise_exception(RuntimeError, "Unexpected error") end it "rollbacks to previous release if error happens on deploy" do @@ -178,9 +178,9 @@ describe Chef::Provider::Deploy do allow(@provider).to receive(:deploy) { raise "Unexpected error" } allow(@provider).to receive(:previous_release_path).and_return("previous_release") expect(@provider).to receive(:rollback) - expect { + expect do @provider.run_action(:deploy) - }.to raise_exception(RuntimeError, "Unexpected error") + end.to raise_exception(RuntimeError, "Unexpected error") end describe "on systems without broken Dir.glob results" do @@ -232,17 +232,17 @@ describe Chef::Provider::Deploy do #FileUtils.should_receive(:rm_rf).with("/my/deploy/dir/releases/20040815162342") #@provider.run_action(:rollback) #@provider.release_path.should eql(NIL) -- no check needed since assertions will fail - expect { + expect do @provider.run_action(:rollback) - }.to raise_exception(RuntimeError, "There is no release to rollback to!") + end.to raise_exception(RuntimeError, "There is no release to rollback to!") end it "an exception is raised when there are no releases" do all_releases = [] allow(Dir).to receive(:glob).with("/my/deploy/dir/releases/*").and_return(all_releases) - expect { + expect do @provider.run_action(:rollback) - }.to raise_exception(RuntimeError, "There is no release to rollback to!") + end.to raise_exception(RuntimeError, "There is no release to rollback to!") end end end diff --git a/spec/unit/provider/dsc_resource_spec.rb b/spec/unit/provider/dsc_resource_spec.rb index 2a00c2ed7f..34eb9727f8 100644 --- a/spec/unit/provider/dsc_resource_spec.rb +++ b/spec/unit/provider/dsc_resource_spec.rb @@ -28,11 +28,11 @@ describe Chef::Provider::DscResource do end context "when Powershell does not support Invoke-DscResource" do - let (:node) { + let (:node) do node = Chef::Node.new node.automatic[:languages][:powershell][:version] = "4.0" node - } + end it "raises a ProviderNotFound exception" do expect(provider).not_to receive(:meta_configuration) expect { provider.run_action(:run) }.to raise_error( @@ -44,11 +44,11 @@ describe Chef::Provider::DscResource do context "when RefreshMode is not set to Disabled" do context "and the WMF 5 is a preview release" do - let (:node) { + let (:node) do node = Chef::Node.new node.automatic[:languages][:powershell][:version] = "5.0.10018.0" node - } + end it "raises an exception" do expect(provider).to receive(:dsc_refresh_mode_disabled?).and_return(false) expect { provider.run_action(:run) }.to raise_error( @@ -56,11 +56,11 @@ describe Chef::Provider::DscResource do end end context "and the WMF is 5 RTM or newer" do - let (:node) { + let (:node) do node = Chef::Node.new node.automatic[:languages][:powershell][:version] = "5.0.10586.0" node - } + end it "does not raises an exception" do expect(provider).to receive(:test_resource) expect(provider).to receive(:set_resource) @@ -72,11 +72,11 @@ describe Chef::Provider::DscResource do end context "when the LCM supports Invoke-DscResource" do - let (:node) { + let (:node) do node = Chef::Node.new node.automatic[:languages][:powershell][:version] = "5.0.10018.0" node - } + end let (:resource_result) { double("CmdletResult", return_value: { "InDesiredState" => true }, stream: "description") } let (:invoke_dsc_resource) { double("cmdlet", run!: resource_result) } let (:store) { double("ResourceStore", find: resource_records) } @@ -153,10 +153,11 @@ describe Chef::Provider::DscResource do end context "multiple resource are found" do - let (:resource_records) { [ + let (:resource_records) do + [ { "Module" => { "Name" => "ModuleName1" } }, { "Module" => { "Name" => "ModuleName2" } }, - ] } + ] end it "raises MultipleDscResourcesFound" do expect { provider.run_action(:run) }.to raise_error(Chef::Exceptions::MultipleDscResourcesFound) diff --git a/spec/unit/provider/dsc_script_spec.rb b/spec/unit/provider/dsc_script_spec.rb index 3877a37e61..5f091b8813 100644 --- a/spec/unit/provider/dsc_script_spec.rb +++ b/spec/unit/provider/dsc_script_spec.rb @@ -23,11 +23,11 @@ require "spec_helper" describe Chef::Provider::DscScript do context "when DSC is available" do - let (:node) { + let (:node) do node = Chef::Node.new node.automatic[:languages][:powershell][:version] = "4.0" node - } + end let (:events) { Chef::EventDispatch::Dispatcher.new } let (:run_context) { Chef::RunContext.new(node, {}, events) } let (:resource) { Chef::Resource::DscScript.new("script", run_context) } @@ -35,7 +35,7 @@ describe Chef::Provider::DscScript do Chef::Provider::DscScript.new(resource, run_context) end - describe '#load_current_resource' do + describe "#load_current_resource" do it "describes the resource as converged if there were 0 DSC resources" do allow(provider).to receive(:run_configuration).with(:test).and_return([]) provider.load_current_resource @@ -75,7 +75,7 @@ describe Chef::Provider::DscScript do end end - describe '#generate_configuration_document' do + describe "#generate_configuration_document" do # I think integration tests should cover these cases it "uses configuration_document_from_script_path when a dsc script file is given" do @@ -123,7 +123,7 @@ describe Chef::Provider::DscScript do end end - describe '#generate_description' do + describe "#generate_description" do it "removes the resource name from the beginning of any log line from the LCM" do dsc_resource_info = Chef::Util::DSC::ResourceInfo.new("resourcename", true, ["resourcename doing something", "lastline"]) provider.instance_variable_set("@dsc_resources_info", [dsc_resource_info]) @@ -156,16 +156,16 @@ describe Chef::Provider::DscScript do it "raises an exception for powershell version '#{version}'" do node.automatic[:languages][:powershell][:version] = version - expect { + expect do provider.run_action(:run) - }.to raise_error(Chef::Exceptions::ProviderNotFound) + end.to raise_error(Chef::Exceptions::ProviderNotFound) end end it "raises an exception if Powershell is not present" do - expect { + expect do provider.run_action(:run) - }.to raise_error(Chef::Exceptions::ProviderNotFound) + end.to raise_error(Chef::Exceptions::ProviderNotFound) end end diff --git a/spec/unit/provider/env/windows_spec.rb b/spec/unit/provider/env/windows_spec.rb index abe2344443..5ddc1d6f91 100644 --- a/spec/unit/provider/env/windows_spec.rb +++ b/spec/unit/provider/env/windows_spec.rb @@ -24,16 +24,16 @@ describe Chef::Provider::Env::Windows, :windows_only do let(:run_context) { Chef::RunContext.new(node, {}, events) } context "when environment variable is not PATH" do - let(:new_resource) { + let(:new_resource) do new_resource = Chef::Resource::Env.new("CHEF_WINDOWS_ENV_TEST") new_resource.value("foo") new_resource - } - let(:provider) { + end + let(:provider) do provider = Chef::Provider::Env::Windows.new(new_resource, run_context) allow(provider).to receive(:env_obj).and_return(double("null object").as_null_object) provider - } + end describe "action_create" do before do @@ -76,16 +76,16 @@ describe Chef::Provider::Env::Windows, :windows_only do describe "for PATH" do let(:system_root) { "%SystemRoot%" } let(:system_root_value) { 'D:\Windows' } - let(:new_resource) { + let(:new_resource) do new_resource = Chef::Resource::Env.new("PATH") new_resource.value(system_root) new_resource - } - let(:provider) { + end + let(:provider) do provider = Chef::Provider::Env::Windows.new(new_resource, run_context) allow(provider).to receive(:env_obj).and_return(double("null object").as_null_object) provider - } + end before do stub_const("ENV", { "PATH" => "" }) diff --git a/spec/unit/provider/file/content_spec.rb b/spec/unit/provider/file/content_spec.rb index a31c75baf4..f840d92dbb 100644 --- a/spec/unit/provider/file/content_spec.rb +++ b/spec/unit/provider/file/content_spec.rb @@ -28,12 +28,12 @@ describe Chef::Provider::File::Content do double("Chef::Provider::File::Resource (current)") end - let(:enclosing_directory) { + let(:enclosing_directory) do canonicalize_path(File.expand_path(File.join(CHEF_SPEC_DATA, "templates"))) - } - let(:resource_path) { + end + let(:resource_path) do canonicalize_path(File.expand_path(File.join(enclosing_directory, "seattle.txt"))) - } + end let(:new_resource) do double("Chef::Provider::File::Resource (new)", :name => "seattle.txt", :path => resource_path) @@ -77,9 +77,9 @@ describe Chef::Provider::File::Content do end context "when creating a tempfiles in destdir fails" do - let(:enclosing_directory) { + let(:enclosing_directory) do canonicalize_path("/nonexisting/path") - } + end it "returns a tempfile in the tempdir when :file_deployment_uses_destdir is set to :auto" do Chef::Config[:file_staging_uses_destdir] = :auto diff --git a/spec/unit/provider/file_spec.rb b/spec/unit/provider/file_spec.rb index 11bef8a44d..d8d4ed2286 100644 --- a/spec/unit/provider/file_spec.rb +++ b/spec/unit/provider/file_spec.rb @@ -35,12 +35,12 @@ describe Chef::Provider::File do let(:node) { double("Chef::Node") } let(:events) { double("Chef::Events").as_null_object } # mock all the methods let(:run_context) { double("Chef::RunContext", :node => node, :events => events) } - let(:enclosing_directory) { + let(:enclosing_directory) do canonicalize_path(File.expand_path(File.join(CHEF_SPEC_DATA, "templates"))) - } - let(:resource_path) { + end + let(:resource_path) do canonicalize_path(File.expand_path(File.join(enclosing_directory, "seattle.txt"))) - } + end # Subject diff --git a/spec/unit/provider/launchd_spec.rb b/spec/unit/provider/launchd_spec.rb index 4286405ef5..2893044833 100644 --- a/spec/unit/provider/launchd_spec.rb +++ b/spec/unit/provider/launchd_spec.rb @@ -51,7 +51,8 @@ describe Chef::Provider::Launchd do </plist> XML - let(:test_hash) do { + let(:test_hash) do + { "Label" => "call.mom.weekly", "Program" => "/Library/scripts/call_mom.sh", "StartCalendarInterval" => { diff --git a/spec/unit/provider/mount/mount_spec.rb b/spec/unit/provider/mount/mount_spec.rb index 42585d9e3e..0b956d9bb9 100644 --- a/spec/unit/provider/mount/mount_spec.rb +++ b/spec/unit/provider/mount/mount_spec.rb @@ -82,7 +82,7 @@ describe Chef::Provider::Mount::Mount do it "should raise an error if the mount device does not exist" do allow(::File).to receive(:exists?).with("/dev/sdz1").and_return false - expect { @provider.load_current_resource();@provider.mountable? }.to raise_error(Chef::Exceptions::Mount) + expect { @provider.load_current_resource(); @provider.mountable? }.to raise_error(Chef::Exceptions::Mount) end it "should not call mountable? with load_current_resource - CHEF-1565" do @@ -99,25 +99,25 @@ describe Chef::Provider::Mount::Mount do @new_resource.device "d21afe51-a0fe-4dc6-9152-ac733763ae0a" expect(@provider).to receive(:shell_out).with("/sbin/findfs UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_return(status) expect(::File).to receive(:exists?).with("").and_return(false) - expect { @provider.load_current_resource();@provider.mountable? }.to raise_error(Chef::Exceptions::Mount) + expect { @provider.load_current_resource(); @provider.mountable? }.to raise_error(Chef::Exceptions::Mount) end it "should raise an error if the mount point does not exist" do allow(::File).to receive(:exists?).with("/tmp/foo").and_return false - expect { @provider.load_current_resource();@provider.mountable? }.to raise_error(Chef::Exceptions::Mount) + expect { @provider.load_current_resource(); @provider.mountable? }.to raise_error(Chef::Exceptions::Mount) end %w{tmpfs fuse cgroup}.each do |fstype| it "does not expect the device to exist for #{fstype}" do @new_resource.fstype(fstype) @new_resource.device("whatever") - expect { @provider.load_current_resource();@provider.mountable? }.not_to raise_error + expect { @provider.load_current_resource(); @provider.mountable? }.not_to raise_error end end it "does not expect the device to exist if it's none" do @new_resource.device("none") - expect { @provider.load_current_resource();@provider.mountable? }.not_to raise_error + expect { @provider.load_current_resource(); @provider.mountable? }.not_to raise_error end it "should set mounted true if the mount point is found in the mounts list" do diff --git a/spec/unit/provider/mount/solaris_spec.rb b/spec/unit/provider/mount/solaris_spec.rb index 51ace83470..264c8b9b36 100644 --- a/spec/unit/provider/mount/solaris_spec.rb +++ b/spec/unit/provider/mount/solaris_spec.rb @@ -41,7 +41,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do let(:options) { nil } - let(:new_resource) { + let(:new_resource) do new_resource = Chef::Resource::Mount.new(mountpoint) new_resource.device device new_resource.device_type device_type @@ -50,13 +50,13 @@ describe Chef::Provider::Mount::Solaris, :unix_only do new_resource.options options new_resource.supports :remount => false new_resource - } + end - let(:provider) { + let(:provider) do Chef::Provider::Mount::Solaris.new(new_resource, run_context) - } + end - let(:vfstab_file_contents) { + let(:vfstab_file_contents) do <<-EOF.gsub /^\s*/, "" #device device mount FS fsck mount mount #to mount to fsck point type pass at boot options @@ -74,21 +74,21 @@ describe Chef::Provider::Mount::Solaris, :unix_only do # ufs /dev/dsk/c0t2d0s7 /dev/rdsk/c0t2d0s7 /mnt/foo ufs 2 yes - EOF - } + end - let(:vfstab_file) { + let(:vfstab_file) do t = Tempfile.new("rspec-vfstab") t.write(vfstab_file_contents) t.close t - } + end - let(:mount_output) { + let(:mount_output) do <<-EOF.gsub /^\s*/, "" /dev/dsk/c0t0d0s0 on / type ufs read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200000 on Tue Jul 31 22:34:46 2012 /dev/dsk/c0t2d0s7 on /mnt/foo type ufs read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Tue Jul 31 22:34:46 2012 EOF - } + end before do stub_const("Chef::Provider::Mount::Solaris::VFSTAB", vfstab_file.path ) @@ -214,7 +214,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do describe "#load_current_resource" do context "when loading a normal UFS filesystem with noauto, don't mount at boot" do - let(:vfstab_file_contents) { + let(:vfstab_file_contents) do <<-EOF.gsub /^\s*/, "" #device device mount FS fsck mount mount #to mount to fsck point type pass at boot options @@ -232,7 +232,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do # ufs /dev/dsk/c0t2d0s7 /dev/rdsk/c0t2d0s7 /mnt/foo ufs 2 no - EOF - } + end before do provider.load_current_resource @@ -244,16 +244,16 @@ describe Chef::Provider::Mount::Solaris, :unix_only do end context "when the device is an smbfs mount" do - let(:mount_output) { + let(:mount_output) do <<-EOF.gsub /^\s*/, "" //solarsystem/tmp on /mnt type smbfs read/write/setuid/devices/dev=5080000 on Tue Mar 29 11:40:18 2011 EOF - } - let(:vfstab_file_contents) { + end + let(:vfstab_file_contents) do <<-EOF.gsub /^\s*/, "" //WORKGROUP;username:password@host/share - /mountpoint smbfs - no fileperms=0777,dirperms=0777 EOF - } + end let(:fsck_device) { "-" } @@ -263,17 +263,17 @@ describe Chef::Provider::Mount::Solaris, :unix_only do end context "when the device is an NFS mount" do - let(:mount_output) { + let(:mount_output) do <<-EOF.gsub /^\s*/, "" cartman:/share2 on /cartman type nfs rsize=32768,wsize=32768,NFSv4,dev=4000004 on Tue Mar 29 11:40:18 2011 EOF - } + end - let(:vfstab_file_contents) { + let(:vfstab_file_contents) do <<-EOF.gsub /^\s*/, "" cartman:/share2 - /cartman nfs - yes rw,soft EOF - } + end let(:fsck_device) { "-" } @@ -334,17 +334,17 @@ describe Chef::Provider::Mount::Solaris, :unix_only do let(:target) { "/dev/mapper/target" } - let(:mount_output) { + let(:mount_output) do <<-EOF.gsub /^\s*/, "" #{target} on /mnt/foo type ufs read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Tue Jul 31 22:34:46 2012 EOF - } + end - let(:vfstab_file_contents) { + let(:vfstab_file_contents) do <<-EOF.gsub /^\s*/, "" #{target} /dev/rdsk/c0t2d0s7 /mnt/foo ufs 2 yes - EOF - } + end before do expect(File).to receive(:symlink?).with(device).at_least(:once).and_return(true) @@ -371,17 +371,17 @@ describe Chef::Provider::Mount::Solaris, :unix_only do let(:absolute_target) { File.expand_path(target, File.dirname(device)) } - let(:mount_output) { + let(:mount_output) do <<-EOF.gsub /^\s*/, "" #{absolute_target} on /mnt/foo type ufs read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Tue Jul 31 22:34:46 2012 EOF - } + end - let(:vfstab_file_contents) { + let(:vfstab_file_contents) do <<-EOF.gsub /^\s*/, "" #{absolute_target} /dev/rdsk/c0t2d0s7 /mnt/foo ufs 2 yes - EOF - } + end before do expect(File).to receive(:symlink?).with(device).at_least(:once).and_return(true) @@ -404,12 +404,12 @@ describe Chef::Provider::Mount::Solaris, :unix_only do end context "when the matching mount point is last in the mounts list" do - let(:mount_output) { + let(:mount_output) do <<-EOF.gsub /^\s*/, "" /dev/dsk/c0t0d0s0 on /mnt/foo type ufs read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200000 on Tue Jul 31 22:34:46 2012 /dev/dsk/c0t2d0s7 on /mnt/foo type ufs read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Tue Jul 31 22:34:46 2012 EOF - } + end it "should set mounted true" do provider.load_current_resource() expect(provider.current_resource.mounted).to be_truthy @@ -417,12 +417,12 @@ describe Chef::Provider::Mount::Solaris, :unix_only do end context "when the matching mount point is not last in the mounts list" do - let(:mount_output) { + let(:mount_output) do <<-EOF.gsub /^\s*/, "" /dev/dsk/c0t2d0s7 on /mnt/foo type ufs read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Tue Jul 31 22:34:46 2012 /dev/dsk/c0t0d0s0 on /mnt/foo type ufs read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200000 on Tue Jul 31 22:34:46 2012 EOF - } + end it "should set mounted false" do provider.load_current_resource() expect(provider.current_resource.mounted).to be_falsey @@ -430,11 +430,11 @@ describe Chef::Provider::Mount::Solaris, :unix_only do end context "when the matching mount point is not in the mounts list (mountpoint wrong)" do - let(:mount_output) { + let(:mount_output) do <<-EOF.gsub /^\s*/, "" /dev/dsk/c0t2d0s7 on /mnt/foob type ufs read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Tue Jul 31 22:34:46 2012 EOF - } + end it "should set mounted false" do provider.load_current_resource() expect(provider.current_resource.mounted).to be_falsey @@ -442,11 +442,11 @@ describe Chef::Provider::Mount::Solaris, :unix_only do end context "when the matching mount point is not in the mounts list (raw device wrong)" do - let(:mount_output) { + let(:mount_output) do <<-EOF.gsub /^\s*/, "" /dev/dsk/c0t2d0s72 on /mnt/foo type ufs read/write/setuid/intr/largefiles/xattr/onerror=panic/dev=2200007 on Tue Jul 31 22:34:46 2012 EOF - } + end it "should set mounted false" do provider.load_current_resource() expect(provider.current_resource.mounted).to be_falsey @@ -454,12 +454,12 @@ describe Chef::Provider::Mount::Solaris, :unix_only do end context "when the mount point is last in fstab" do - let(:vfstab_file_contents) { + let(:vfstab_file_contents) do <<-EOF.gsub /^\s*/, "" /dev/dsk/c0t2d0s72 /dev/rdsk/c0t2d0s7 /mnt/foo ufs 2 yes - /dev/dsk/c0t2d0s7 /dev/rdsk/c0t2d0s7 /mnt/foo ufs 2 yes - EOF - } + end it "should set enabled to true" do provider.load_current_resource @@ -468,12 +468,12 @@ describe Chef::Provider::Mount::Solaris, :unix_only do end context "when the mount point is not last in fstab and is a substring of another mount" do - let(:vfstab_file_contents) { + let(:vfstab_file_contents) do <<-EOF.gsub /^\s*/, "" /dev/dsk/c0t2d0s7 /dev/rdsk/c0t2d0s7 /mnt/foo ufs 2 yes - /dev/dsk/c0t2d0s72 /dev/rdsk/c0t2d0s7 /mnt/foo/bar ufs 2 yes - EOF - } + end it "should set enabled to true" do provider.load_current_resource @@ -482,12 +482,12 @@ describe Chef::Provider::Mount::Solaris, :unix_only do end context "when the mount point is not last in fstab" do - let(:vfstab_file_contents) { + let(:vfstab_file_contents) do <<-EOF.gsub /^\s*/, "" /dev/dsk/c0t2d0s7 /dev/rdsk/c0t2d0s7 /mnt/foo ufs 2 yes - /dev/dsk/c0t2d0s72 /dev/rdsk/c0t2d0s72 /mnt/foo ufs 2 yes - EOF - } + end it "should set enabled to false" do provider.load_current_resource @@ -496,11 +496,11 @@ describe Chef::Provider::Mount::Solaris, :unix_only do end context "when the mount point is not in fstab, but the mountpoint is a substring of one that is" do - let(:vfstab_file_contents) { + let(:vfstab_file_contents) do <<-EOF.gsub /^\s*/, "" /dev/dsk/c0t2d0s7 /dev/rdsk/c0t2d0s7 /mnt/foob ufs 2 yes - EOF - } + end it "should set enabled to false" do provider.load_current_resource @@ -509,11 +509,11 @@ describe Chef::Provider::Mount::Solaris, :unix_only do end context "when the mount point is not in fstab, but the device is a substring of one that is" do - let(:vfstab_file_contents) { + let(:vfstab_file_contents) do <<-EOF.gsub /^\s*/, "" /dev/dsk/c0t2d0s72 /dev/rdsk/c0t2d0s7 /mnt/foo ufs 2 yes - EOF - } + end it "should set enabled to false" do provider.load_current_resource @@ -522,11 +522,11 @@ describe Chef::Provider::Mount::Solaris, :unix_only do end context "when the mountpoint line is commented out" do - let(:vfstab_file_contents) { + let(:vfstab_file_contents) do <<-EOF.gsub /^\s*/, "" #/dev/dsk/c0t2d0s7 /dev/rdsk/c0t2d0s7 /mnt/foo ufs 2 yes - EOF - } + end it "should set enabled to false" do provider.load_current_resource diff --git a/spec/unit/provider/package/chocolatey_spec.rb b/spec/unit/provider/package/chocolatey_spec.rb index 8344c3d0ec..704ef1aef2 100644 --- a/spec/unit/provider/package/chocolatey_spec.rb +++ b/spec/unit/provider/package/chocolatey_spec.rb @@ -462,18 +462,18 @@ describe "behavior when Chocolatey is not installed" do Chef::Provider::Package::Chocolatey.new(new_resource, run_context) end - before { + before do # the shellout sometimes returns "", but test nil to be safe. allow(provider).to receive(:choco_install_path).and_return(nil) provider.instance_variable_set("@choco_install_path", nil) # we don't care what this returns, but we have to let it be called. allow(provider).to receive(:shell_out!).and_return(double(:stdout => "")) - } + end - let(:error_regex) { + let(:error_regex) do /Could not locate.*install.*cookbook.*PowerShell.*GetEnvironmentVariable/m - } + end context "#choco_exe" do it "triggers a MissingLibrary exception when Chocolatey is not installed" do diff --git a/spec/unit/provider/package/freebsd/port_spec.rb b/spec/unit/provider/package/freebsd/port_spec.rb index b593da4ff1..4ae8d960a2 100644 --- a/spec/unit/provider/package/freebsd/port_spec.rb +++ b/spec/unit/provider/package/freebsd/port_spec.rb @@ -74,8 +74,8 @@ describe Chef::Provider::Package::Freebsd::Port do it "should check 'pkg info' if make supports WITH_PKGNG if freebsd version is < 1000017" do pkg_enabled = OpenStruct.new(:stdout => "yes\n") - [1000016, 1000000, 901503, 902506, 802511].each do |__freebsd_version| - @node.automatic_attrs[:os_version] = __freebsd_version + [1000016, 1000000, 901503, 902506, 802511].each do |freebsd_version| + @node.automatic_attrs[:os_version] = freebsd_version expect(@new_resource).to receive(:shell_out!).with("make -V WITH_PKGNG", env: nil).and_return(pkg_enabled) expect(@provider).to receive(:shell_out!).with('pkg info "zsh"', env: nil, returns: [0, 70], timeout: 900).and_return(@pkg_info) expect(@provider.current_installed_version).to eq("3.1.7") @@ -83,8 +83,8 @@ describe Chef::Provider::Package::Freebsd::Port do end it "should check 'pkg info' if the freebsd version is greater than or equal to 1000017" do - __freebsd_version = 1000017 - @node.automatic_attrs[:os_version] = __freebsd_version + freebsd_version = 1000017 + @node.automatic_attrs[:os_version] = freebsd_version expect(@provider).to receive(:shell_out!).with('pkg info "zsh"', env: nil, returns: [0, 70], timeout: 900).and_return(@pkg_info) expect(@provider.current_installed_version).to eq("3.1.7") end diff --git a/spec/unit/provider/package/rubygems_spec.rb b/spec/unit/provider/package/rubygems_spec.rb index f87c261ec0..b1ebde2b7d 100644 --- a/spec/unit/provider/package/rubygems_spec.rb +++ b/spec/unit/provider/package/rubygems_spec.rb @@ -16,7 +16,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # -require "pp" module GemspecBackcompatCreator def gemspec(name, version) @@ -64,7 +63,7 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do begin @gem_env.with_gem_sources("http://gems.example.org") do sources_in_block = Gem.sources - raise RuntimeError, "sources should be reset even in case of an error" + raise "sources should be reset even in case of an error" end rescue RuntimeError end @@ -78,7 +77,7 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do begin @gem_env.with_gem_sources(nil) do sources_in_block = Gem.sources - raise RuntimeError, "sources should be reset even in case of an error" + raise "sources should be reset even in case of an error" end rescue RuntimeError end @@ -86,34 +85,55 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do expect(Gem.sources).to eq(normal_sources) end - it "finds a matching gem candidate version" do - dep = Gem::Dependency.new("rspec", ">= 0") - dep_installer = Gem::DependencyInstaller.new - allow(@gem_env).to receive(:dependency_installer).and_return(dep_installer) - latest = [[gemspec("rspec", Gem::Version.new("1.3.0")), "https://rubygems.org/"]] - expect(dep_installer).to receive(:find_gems_with_sources).with(dep).and_return(latest) - expect(@gem_env.candidate_version_from_remote(Gem::Dependency.new("rspec", ">= 0"))).to eq(Gem::Version.new("1.3.0")) - end + context "new default rubygems behavior" do + before do + Chef::Config[:rubygems_cache_enabled] = false + end - it "finds a matching gem candidate version on rubygems 2.0.0+" do - dep = Gem::Dependency.new("rspec", ">= 0") - dep_installer = Gem::DependencyInstaller.new - allow(@gem_env).to receive(:dependency_installer).and_return(dep_installer) - best_gem = double("best gem match", :spec => gemspec("rspec", Gem::Version.new("1.3.0")), :source => "https://rubygems.org") - available_set = double("Gem::AvailableSet test double") - expect(available_set).to receive(:pick_best!) - expect(available_set).to receive(:set).and_return([best_gem]) - expect(dep_installer).to receive(:find_gems_with_sources).with(dep).and_return(available_set) - expect(@gem_env.candidate_version_from_remote(Gem::Dependency.new("rspec", ">= 0"))).to eq(Gem::Version.new("1.3.0")) + it "finds a matching gem candidate version on rubygems 2.0.0+" do + dep = Gem::Dependency.new("rspec", ">= 0") + dep_installer = Gem::DependencyInstaller.new + allow(@gem_env).to receive(:dependency_installer).and_return(dep_installer) + expect(dep_installer).not_to receive(:find_gems_with_sources).with(dep).and_call_original + expect(@gem_env.candidate_version_from_remote(dep)).to be_kind_of(Gem::Version) + end + + it "gives the candidate version as nil if none is found" do + dep = Gem::Dependency.new("lksdjflksdjflsdkfj", ">= 0") + dep_installer = Gem::DependencyInstaller.new + allow(@gem_env).to receive(:dependency_installer).and_return(dep_installer) + expect(dep_installer).not_to receive(:find_gems_with_sources).with(dep).and_call_original + expect(@gem_env.candidate_version_from_remote(dep)).to be_nil + end + + it "finds a matching gem from a specific gemserver when explicit sources are given (to a server that doesn't respond to api requests)" do + dep = Gem::Dependency.new("rspec", ">= 0") + dep_installer = Gem::DependencyInstaller.new + allow(@gem_env).to receive(:dependency_installer).and_return(dep_installer) + expect(dep_installer).not_to receive(:find_gems_with_sources).with(dep).and_call_original + expect(@gem_env.candidate_version_from_remote(dep, "http://production.cf.rubygems.org")).to be_kind_of(Gem::Version) + end end - it "gives the candidate version as nil if none is found" do - dep = Gem::Dependency.new("rspec", ">= 0") - latest = [] - dep_installer = Gem::DependencyInstaller.new - allow(@gem_env).to receive(:dependency_installer).and_return(dep_installer) - expect(dep_installer).to receive(:find_gems_with_sources).with(dep).and_return(latest) - expect(@gem_env.candidate_version_from_remote(Gem::Dependency.new("rspec", ">= 0"))).to be_nil + context "old rubygems caching behavior" do + before do + Chef::Config[:rubygems_cache_enabled] = true + end + + it "finds a matching gem candidate version on rubygems 2.0.0+" do + dep = Gem::Dependency.new("rspec", ">= 0") + expect(@gem_env.candidate_version_from_remote(dep)).to be_kind_of(Gem::Version) + end + + it "gives the candidate version as nil if none is found" do + dep = Gem::Dependency.new("lksdjflksdjflsdkfj", ">= 0") + expect(@gem_env.candidate_version_from_remote(dep)).to be_nil + end + + it "finds a matching gem from a specific gemserver when explicit sources are given" do + dep = Gem::Dependency.new("rspec", ">= 0") + expect(@gem_env.candidate_version_from_remote(dep, "http://production.cf.rubygems.org")).to be_kind_of(Gem::Version) + end end it "finds a matching candidate version from a .gem file when the path to the gem is supplied" do @@ -122,17 +142,6 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do expect(@gem_env.candidate_version_from_file(Gem::Dependency.new("chef-integration-test", ">= 0.2.0"), location)).to be_nil end - it "finds a matching gem from a specific gemserver when explicit sources are given" do - dep = Gem::Dependency.new("rspec", ">= 0") - latest = [[gemspec("rspec", Gem::Version.new("1.3.0")), "https://rubygems.org/"]] - - expect(@gem_env).to receive(:with_gem_sources).with("http://gems.example.com").and_yield - dep_installer = Gem::DependencyInstaller.new - allow(@gem_env).to receive(:dependency_installer).and_return(dep_installer) - expect(dep_installer).to receive(:find_gems_with_sources).with(dep).and_return(latest) - expect(@gem_env.candidate_version_from_remote(Gem::Dependency.new("rspec", ">=0"), "http://gems.example.com")).to eq(Gem::Version.new("1.3.0")) - end - it "installs a gem with a hash of options for the dependency installer" do dep_installer = Gem::DependencyInstaller.new expect(@gem_env).to receive(:dependency_installer).with(:install_dir => "/foo/bar").and_return(dep_installer) @@ -545,7 +554,6 @@ describe Chef::Provider::Package::Rubygems do expect(provider.candidate_version).to eq("0.1.0") end end - end describe "when installing a gem" do diff --git a/spec/unit/provider/package/yum_spec.rb b/spec/unit/provider/package/yum_spec.rb index ab726134e9..e9aec933e2 100644 --- a/spec/unit/provider/package/yum_spec.rb +++ b/spec/unit/provider/package/yum_spec.rb @@ -312,7 +312,8 @@ describe Chef::Provider::Package::Yum do end context "when the package name isn't found" do - let(:yum_cache) { double( + let(:yum_cache) do + double( "Chef::Provider::Yum::YumCache", :reload_installed => true, :reset => true, @@ -322,7 +323,7 @@ describe Chef::Provider::Package::Yum do :version_available? => true, :disable_extra_repo_control => true ) - } + end before do allow(Chef::Provider::Package::Yum::YumCache).to receive(:instance).and_return(yum_cache) @@ -1063,21 +1064,21 @@ describe Chef::Provider::Package::Yum::RPMVersion do end it "should raise an error unless passed 1 or 3 args" do - expect { + expect do Chef::Provider::Package::Yum::RPMVersion.new() - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do Chef::Provider::Package::Yum::RPMVersion.new("1:1.6.5-9.36.el5") - }.not_to raise_error - expect { + end.not_to raise_error + expect do Chef::Provider::Package::Yum::RPMVersion.new("1:1.6.5-9.36.el5", "extra") - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do Chef::Provider::Package::Yum::RPMVersion.new("1", "1.6.5", "9.36.el5") - }.not_to raise_error - expect { + end.not_to raise_error + expect do Chef::Provider::Package::Yum::RPMVersion.new("1", "1.6.5", "9.36.el5", "extra") - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end # thanks version_class_spec.rb! @@ -1229,9 +1230,9 @@ describe Chef::Provider::Package::Yum::RPMPackage do it "should always have at least one provide, itself" do expect(@rpm.provides.size).to eq(1) - @rpm.provides[0].name == "testing" - @rpm.provides[0].version.evr == "1:1.6.5-9.36.el5" - @rpm.provides[0].flag == :== + expect(@rpm.provides[0].name).to eql("testing") + expect(@rpm.provides[0].version.evr).to eql("1:1.6.5-9.36.el5") + expect(@rpm.provides[0].flag).to eql(:==) end end @@ -1253,37 +1254,37 @@ describe Chef::Provider::Package::Yum::RPMPackage do it "should always have at least one provide, itself" do expect(@rpm.provides.size).to eq(1) - @rpm.provides[0].name == "testing" - @rpm.provides[0].version.evr == "1:1.6.5-9.36.el5" - @rpm.provides[0].flag == :== + expect(@rpm.provides[0].name).to eql("testing") + expect(@rpm.provides[0].version.evr).to eql("1:1.6.5-9.36.el5") + expect(@rpm.provides[0].flag).to eql(:==) end end it "should raise an error unless passed 4 or 6 args" do - expect { + expect do Chef::Provider::Package::Yum::RPMPackage.new() - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do Chef::Provider::Package::Yum::RPMPackage.new("testing") - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do Chef::Provider::Package::Yum::RPMPackage.new("testing", "1:1.6.5-9.36.el5") - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do Chef::Provider::Package::Yum::RPMPackage.new("testing", "1:1.6.5-9.36.el5", "x86_64") - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do Chef::Provider::Package::Yum::RPMPackage.new("testing", "1:1.6.5-9.36.el5", "x86_64", []) - }.not_to raise_error - expect { + end.not_to raise_error + expect do Chef::Provider::Package::Yum::RPMPackage.new("testing", "1", "1.6.5", "9.36.el5", "x86_64") - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do Chef::Provider::Package::Yum::RPMPackage.new("testing", "1", "1.6.5", "9.36.el5", "x86_64", []) - }.not_to raise_error - expect { + end.not_to raise_error + expect do Chef::Provider::Package::Yum::RPMPackage.new("testing", "1", "1.6.5", "9.36.el5", "x86_64", [], "extra") - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end describe "<=>" do @@ -1397,27 +1398,27 @@ describe Chef::Provider::Package::Yum::RPMDependency do end it "should raise an error unless passed 3 or 5 args" do - expect { + expect do Chef::Provider::Package::Yum::RPMDependency.new() - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do Chef::Provider::Package::Yum::RPMDependency.new("testing") - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5") - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :==) - }.not_to raise_error - expect { + end.not_to raise_error + expect do Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :==, "extra") - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do Chef::Provider::Package::Yum::RPMDependency.new("testing", "1", "1.6.5", "9.36.el5", :==) - }.not_to raise_error - expect { + end.not_to raise_error + expect do Chef::Provider::Package::Yum::RPMDependency.new("testing", "1", "1.6.5", "9.36.el5", :==, "extra") - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end describe "parse" do @@ -1485,12 +1486,12 @@ describe Chef::Provider::Package::Yum::RPMDependency do it "should raise an error unless a RPMDependency is passed" do @rpmprovide = Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :==) @rpmrequire = Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :>=) - expect { + expect do @rpmprovide.satisfy?("hi") - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do @rpmprovide.satisfy?(@rpmrequire) - }.not_to raise_error + end.not_to raise_error end it "should validate dependency satisfaction logic for standard examples" do @@ -1712,12 +1713,12 @@ describe Chef::Provider::Package::Yum::RPMDb do it "should raise an error unless a RPMDependency is passed" do @rpmprovide = Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :==) @rpmrequire = Chef::Provider::Package::Yum::RPMDependency.new("testing", "1:1.6.5-9.36.el5", :>=) - expect { + expect do @rpmdb.whatprovides("hi") - }.to raise_error(ArgumentError) - expect { + end.to raise_error(ArgumentError) + expect do @rpmdb.whatprovides(@rpmrequire) - }.not_to raise_error + end.not_to raise_error end it "should return an Array of packages statisfying a RPMDependency" do @@ -1748,13 +1749,13 @@ describe Chef::Provider::Package::Yum::YumCache do end end - let(:yum_exe) { + let(:yum_exe) do StringIO.new("#!/usr/bin/python\n\naldsjfa\ldsajflkdsjf\lajsdfj") - } + end - let(:bin_exe) { + let(:bin_exe) do StringIO.new(SecureRandom.random_bytes) - } + end before(:each) do @stdin = double("STDIN", :nil_object => true) diff --git a/spec/unit/provider/package/zypper_spec.rb b/spec/unit/provider/package/zypper_spec.rb index df0a1da9a2..8838c26b71 100644 --- a/spec/unit/provider/package/zypper_spec.rb +++ b/spec/unit/provider/package/zypper_spec.rb @@ -72,7 +72,7 @@ describe Chef::Provider::Package::Zypper do provider.load_current_resource end - it "should set the installed version if zypper info has one" do + it "should set the installed version if zypper info has one (zypper version < 1.13.0)" do status = double(:stdout => "Version: 1.0\nInstalled: Yes\n", :exitstatus => 0) allow(provider).to receive(:shell_out!).and_return(status) @@ -80,7 +80,15 @@ describe Chef::Provider::Package::Zypper do provider.load_current_resource end - it "should set the candidate version if zypper info has one" do + it "should set the installed version if zypper info has one (zypper version >= 1.13.0)" do + status = double(:stdout => "Version : 1.0 \nInstalled : Yes \n", :exitstatus => 0) + + allow(provider).to receive(:shell_out!).and_return(status) + expect(current_resource).to receive(:version).with(["1.0"]).and_return(true) + provider.load_current_resource + end + + it "should set the candidate version if zypper info has one (zypper version < 1.13.0)" do status = double(:stdout => "Version: 1.0\nInstalled: No\nStatus: out-of-date (version 0.9 installed)", :exitstatus => 0) allow(provider).to receive(:shell_out!).and_return(status) @@ -88,6 +96,14 @@ describe Chef::Provider::Package::Zypper do expect(provider.candidate_version).to eql(["1.0"]) end + it "should set the candidate version if zypper info has one (zypper version >= 1.13.0)" do + status = double(:stdout => "Version : 1.0 \nInstalled : No \nStatus : out-of-date (version 0.9 installed)", :exitstatus => 0) + + allow(provider).to receive(:shell_out!).and_return(status) + provider.load_current_resource + expect(provider.candidate_version).to eql(["1.0"]) + end + it "should return the current resouce" do expect(provider.load_current_resource).to eql(current_resource) end diff --git a/spec/unit/provider/package_spec.rb b/spec/unit/provider/package_spec.rb index 2ef58db9f3..40b7516b5c 100644 --- a/spec/unit/provider/package_spec.rb +++ b/spec/unit/provider/package_spec.rb @@ -396,13 +396,13 @@ describe Chef::Provider::Package do describe "when installing the preseed file to the cache location" do let(:response_file_destination) { Dir.tmpdir + "/preseed--java--java-6.seed" } - let(:response_file_resource) { + let(:response_file_resource) do response_file_resource = Chef::Resource::CookbookFile.new(response_file_destination, run_context) response_file_resource.cookbook_name = "java" response_file_resource.backup(false) response_file_resource.source("java.response") response_file_resource - } + end before do expect(provider).to receive(:preseed_resource).with("java", "6").and_return(response_file_resource) diff --git a/spec/unit/provider/powershell_script_spec.rb b/spec/unit/provider/powershell_script_spec.rb index 96869ff31c..4fd3f3534d 100644 --- a/spec/unit/provider/powershell_script_spec.rb +++ b/spec/unit/provider/powershell_script_spec.rb @@ -20,7 +20,7 @@ require "spec_helper" describe Chef::Provider::PowershellScript, "action_run" do let(:powershell_version) { nil } - let(:node) { + let(:node) do node = Chef::Node.new node.default["kernel"] = Hash.new node.default["kernel"][:machine] = :x86_64.to_s @@ -28,14 +28,14 @@ describe Chef::Provider::PowershellScript, "action_run" do node.default[:languages] = { :powershell => { :version => powershell_version } } end node - } + end - let(:provider) { + let(:provider) do empty_events = Chef::EventDispatch::Dispatcher.new run_context = Chef::RunContext.new(node, {}, empty_events) new_resource = Chef::Resource::PowershellScript.new("run some powershell code", run_context) Chef::Provider::PowershellScript.new(new_resource, run_context) - } + end context "when setting interpreter flags" do context "on nano" do diff --git a/spec/unit/provider/remote_directory_spec.rb b/spec/unit/provider/remote_directory_spec.rb index b6fd4cfc8e..cb1b6e3cd8 100644 --- a/spec/unit/provider/remote_directory_spec.rb +++ b/spec/unit/provider/remote_directory_spec.rb @@ -121,7 +121,7 @@ describe Chef::Provider::RemoteDirectory do @node.automatic_attrs[:platform] = :just_testing @node.automatic_attrs[:platform_version] = :just_testing - @destination_dir = Dir.mktmpdir << "/remote_directory_test" + @destination_dir = make_canonical_temp_directory << "/remote_directory_test" @resource.path(@destination_dir) end diff --git a/spec/unit/provider/remote_file/ftp_spec.rb b/spec/unit/provider/remote_file/ftp_spec.rb index 9963c401d2..b2fbb7300c 100644 --- a/spec/unit/provider/remote_file/ftp_spec.rb +++ b/spec/unit/provider/remote_file/ftp_spec.rb @@ -19,12 +19,12 @@ require "spec_helper" describe Chef::Provider::RemoteFile::FTP do - let(:enclosing_directory) { + let(:enclosing_directory) do canonicalize_path(File.expand_path(File.join(CHEF_SPEC_DATA, "templates"))) - } - let(:resource_path) { + end + let(:resource_path) do canonicalize_path(File.expand_path(File.join(enclosing_directory, "seattle.txt"))) - } + end let(:new_resource) do r = Chef::Resource::RemoteFile.new("remote file ftp backend test (new resource)") diff --git a/spec/unit/provider/remote_file/local_file_spec.rb b/spec/unit/provider/remote_file/local_file_spec.rb index 31f14fbe45..6f345cadd1 100644 --- a/spec/unit/provider/remote_file/local_file_spec.rb +++ b/spec/unit/provider/remote_file/local_file_spec.rb @@ -17,6 +17,8 @@ # require "spec_helper" +require "uri" +require "addressable/uri" describe Chef::Provider::RemoteFile::LocalFile do @@ -47,7 +49,7 @@ describe Chef::Provider::RemoteFile::LocalFile do end describe "when given local windows path with spaces" do - let(:uri) { URI.parse(URI.escape("file:///z:/windows/path/foo & bar.txt")) } + let(:uri) { URI.parse(Addressable::URI.encode("file:///z:/windows/path/foo & bar.txt")) } it "returns a valid windows local path" do expect(fetcher.source_path).to eq("z:/windows/path/foo & bar.txt") end @@ -61,7 +63,7 @@ describe Chef::Provider::RemoteFile::LocalFile do end describe "when given unc windows path with spaces" do - let(:uri) { URI.parse(URI.escape("file:////server/share/windows/path/foo & bar.txt")) } + let(:uri) { URI.parse(Addressable::URI.encode("file:////server/share/windows/path/foo & bar.txt")) } it "returns a valid windows unc path" do expect(fetcher.source_path).to eq("//server/share/windows/path/foo & bar.txt") end diff --git a/spec/unit/provider/remote_file/sftp_spec.rb b/spec/unit/provider/remote_file/sftp_spec.rb index 673ea015c0..7be507dc89 100644 --- a/spec/unit/provider/remote_file/sftp_spec.rb +++ b/spec/unit/provider/remote_file/sftp_spec.rb @@ -20,12 +20,12 @@ require "spec_helper" describe Chef::Provider::RemoteFile::SFTP do #built out dependencies - let(:enclosing_directory) { + let(:enclosing_directory) do canonicalize_path(File.expand_path(File.join(CHEF_SPEC_DATA, "templates"))) - } - let(:resource_path) { + end + let(:resource_path) do canonicalize_path(File.expand_path(File.join(enclosing_directory, "seattle.txt"))) - } + end let(:new_resource) do r = Chef::Resource::RemoteFile.new("remote file sftp backend test (new resource)") diff --git a/spec/unit/provider/remote_file_spec.rb b/spec/unit/provider/remote_file_spec.rb index 6107f93c41..6ceb1d450d 100644 --- a/spec/unit/provider/remote_file_spec.rb +++ b/spec/unit/provider/remote_file_spec.rb @@ -37,12 +37,12 @@ describe Chef::Provider::RemoteFile do let(:node) { double("Chef::Node") } let(:events) { double("Chef::Events").as_null_object } # mock all the methods let(:run_context) { double("Chef::RunContext", :node => node, :events => events) } - let(:enclosing_directory) { + let(:enclosing_directory) do canonicalize_path(File.expand_path(File.join(CHEF_SPEC_DATA, "templates"))) - } - let(:resource_path) { + end + let(:resource_path) do canonicalize_path(File.expand_path(File.join(enclosing_directory, "seattle.txt"))) - } + end subject(:provider) do provider = described_class.new(resource, run_context) diff --git a/spec/unit/provider/script_spec.rb b/spec/unit/provider/script_spec.rb index 4e8d8bdf59..7e34a8f083 100644 --- a/spec/unit/provider/script_spec.rb +++ b/spec/unit/provider/script_spec.rb @@ -25,12 +25,12 @@ describe Chef::Provider::Script, "action_run" do let(:run_context) { Chef::RunContext.new(node, {}, events) } - let(:new_resource) { + let(:new_resource) do new_resource = Chef::Resource::Script.new("run some perl code") new_resource.code "$| = 1; print 'i like beans'" new_resource.interpreter "perl" new_resource - } + end let(:provider) { Chef::Provider::Script.new(new_resource, run_context) } @@ -87,9 +87,9 @@ describe Chef::Provider::Script, "action_run" do end describe "when running the script" do - let (:default_opts) { + let (:default_opts) do { timeout: 3600, returns: 0, log_level: :info, log_tag: "script[run some perl code]" } - } + end before do allow(STDOUT).to receive(:tty?).and_return(false) diff --git a/spec/unit/provider/service/debian_service_spec.rb b/spec/unit/provider/service/debian_service_spec.rb index 2192671370..799ed991a3 100644 --- a/spec/unit/provider/service/debian_service_spec.rb +++ b/spec/unit/provider/service/debian_service_spec.rb @@ -39,9 +39,9 @@ describe Chef::Provider::Service::Debian do expect(File).to receive(:exists?).with("/usr/sbin/update-rc.d") .and_return(false) @provider.define_resource_requirements - expect { + expect do @provider.process_resource_requirements - }.to raise_error(Chef::Exceptions::Service) + end.to raise_error(Chef::Exceptions::Service) end context "when update-rc.d shows init linked to rc*.d/" do @@ -108,9 +108,9 @@ describe Chef::Provider::Service::Debian do it "raises an error" do @provider.define_resource_requirements - expect { + expect do @provider.process_resource_requirements - }.to raise_error(Chef::Exceptions::Service) + end.to raise_error(Chef::Exceptions::Service) end end diff --git a/spec/unit/provider/service/freebsd_service_spec.rb b/spec/unit/provider/service/freebsd_service_spec.rb index 68d4d63991..10eb3c1a14 100644 --- a/spec/unit/provider/service/freebsd_service_spec.rb +++ b/spec/unit/provider/service/freebsd_service_spec.rb @@ -257,10 +257,11 @@ PS_SAMPLE end context "when the enable variable partial matches (left) some other service and we are disabled" do - let(:lines) { [ + let(:lines) do + [ %Q{thing_#{new_resource.service_name}_enable="YES"}, %Q{#{new_resource.service_name}_enable="NO"}, - ] } + ] end it "sets enabled based on the exact match (false)" do provider.determine_enabled_status! expect(current_resource.enabled).to be false @@ -268,10 +269,11 @@ PS_SAMPLE end context "when the enable variable partial matches (right) some other service and we are disabled" do - let(:lines) { [ + let(:lines) do + [ %Q{#{new_resource.service_name}_thing_enable="YES"}, %Q{#{new_resource.service_name}_enable="NO"}, - ] } + ] end it "sets enabled based on the exact match (false)" do provider.determine_enabled_status! expect(current_resource.enabled).to be false @@ -279,10 +281,11 @@ PS_SAMPLE end context "when the enable variable partial matches (left) some other disabled service and we are enabled" do - let(:lines) { [ + let(:lines) do + [ %Q{thing_#{new_resource.service_name}_enable="NO"}, %Q{#{new_resource.service_name}_enable="YES"}, - ] } + ] end it "sets enabled based on the exact match (true)" do provider.determine_enabled_status! expect(current_resource.enabled).to be true @@ -290,10 +293,11 @@ PS_SAMPLE end context "when the enable variable partial matches (right) some other disabled service and we are enabled" do - let(:lines) { [ + let(:lines) do + [ %Q{#{new_resource.service_name}_thing_enable="NO"}, %Q{#{new_resource.service_name}_enable="YES"}, - ] } + ] end it "sets enabled based on the exact match (true)" do provider.determine_enabled_status! expect(current_resource.enabled).to be true diff --git a/spec/unit/provider/service/openbsd_service_spec.rb b/spec/unit/provider/service/openbsd_service_spec.rb index b11015a63a..872a3bc400 100644 --- a/spec/unit/provider/service/openbsd_service_spec.rb +++ b/spec/unit/provider/service/openbsd_service_spec.rb @@ -174,10 +174,11 @@ describe Chef::Provider::Service::Openbsd do end context "when the enable variable partial matches (left) some other service and we are disabled" do - let(:lines) { [ + let(:lines) do + [ %Q{thing_#{provider.builtin_service_enable_variable_name}="YES"}, %Q{#{provider.builtin_service_enable_variable_name}="NO"}, - ] } + ] end it "sets enabled based on the exact match (false)" do provider.determine_enabled_status! expect(current_resource.enabled).to be false @@ -185,10 +186,11 @@ describe Chef::Provider::Service::Openbsd do end context "when the enable variable partial matches (right) some other service and we are disabled" do - let(:lines) { [ + let(:lines) do + [ %Q{#{provider.builtin_service_enable_variable_name}_thing="YES"}, %Q{#{provider.builtin_service_enable_variable_name}}, - ] } + ] end it "sets enabled based on the exact match (false)" do provider.determine_enabled_status! expect(current_resource.enabled).to be false @@ -196,10 +198,11 @@ describe Chef::Provider::Service::Openbsd do end context "when the enable variable partial matches (left) some other disabled service and we are enabled" do - let(:lines) { [ + let(:lines) do + [ %Q{thing_#{provider.builtin_service_enable_variable_name}="NO"}, %Q{#{provider.builtin_service_enable_variable_name}="YES"}, - ] } + ] end it "sets enabled based on the exact match (true)" do provider.determine_enabled_status! expect(current_resource.enabled).to be true @@ -207,10 +210,11 @@ describe Chef::Provider::Service::Openbsd do end context "when the enable variable partial matches (right) some other disabled service and we are enabled" do - let(:lines) { [ + let(:lines) do + [ %Q{#{provider.builtin_service_enable_variable_name}_thing="NO"}, %Q{#{provider.builtin_service_enable_variable_name}="YES"}, - ] } + ] end it "sets enabled based on the exact match (true)" do provider.determine_enabled_status! expect(current_resource.enabled).to be true diff --git a/spec/unit/provider/service/systemd_service_spec.rb b/spec/unit/provider/service/systemd_service_spec.rb index e0a94127b7..8574cbf772 100644 --- a/spec/unit/provider/service/systemd_service_spec.rb +++ b/spec/unit/provider/service/systemd_service_spec.rb @@ -21,7 +21,7 @@ require "spec_helper" describe Chef::Provider::Service::Systemd do - let(:node) { + let(:node) do node = Chef::Node.new node.default["etc"] = Hash.new node.default["etc"]["passwd"] = { @@ -30,7 +30,7 @@ describe Chef::Provider::Service::Systemd do }, } node - } + end let(:events) { Chef::EventDispatch::Dispatcher.new } diff --git a/spec/unit/provider/service/windows_spec.rb b/spec/unit/provider/service/windows_spec.rb index f944d8f6c6..d4c451511d 100644 --- a/spec/unit/provider/service/windows_spec.rb +++ b/spec/unit/provider/service/windows_spec.rb @@ -151,15 +151,15 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do let(:old_run_as_user) { new_resource.run_as_user } let(:old_run_as_password) { new_resource.run_as_password } - before { + before do new_resource.run_as_user(".\\wallace") new_resource.run_as_password("Wensleydale") - } + end - after { + after do new_resource.run_as_user(old_run_as_user) new_resource.run_as_password(old_run_as_password) - } + end it "calls #grant_service_logon if the :run_as_user and :run_as_password attributes are present" do expect(Win32::Service).to receive(:start) @@ -409,17 +409,17 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do shared_context "testing private methods" do - let(:private_methods) { + let(:private_methods) do described_class.private_instance_methods - } + end - before { + before do described_class.send(:public, *private_methods) - } + end - after { + after do described_class.send(:private, *private_methods) - } + end end describe "grant_service_logon" do diff --git a/spec/unit/provider/template/content_spec.rb b/spec/unit/provider/template/content_spec.rb index 0f936c8f11..8f30d8f868 100644 --- a/spec/unit/provider/template/content_spec.rb +++ b/spec/unit/provider/template/content_spec.rb @@ -20,13 +20,13 @@ require "spec_helper" describe Chef::Provider::Template::Content do - let(:enclosing_directory) { + let(:enclosing_directory) do canonicalize_path(Dir.mktmpdir) - } + end - let(:resource_path) { + let(:resource_path) do canonicalize_path(File.expand_path(File.join(enclosing_directory, "openldap_stuff.conf"))) - } + end let(:new_resource) do double("Chef::Resource::Template (new)", @@ -46,10 +46,10 @@ describe Chef::Provider::Template::Content do :helper_modules => []) end - let(:rendered_file_locations) { + let(:rendered_file_locations) do [Dir.tmpdir + "/openldap_stuff.conf", enclosing_directory + "/openldap_stuff.conf"] - } + end let(:run_context) do cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks")) @@ -101,9 +101,9 @@ describe Chef::Provider::Template::Content do end context "when creating a tempfile in destdir fails" do - let(:enclosing_directory) { + let(:enclosing_directory) do canonicalize_path("/nonexisting/path") - } + end it "returns a tempfile in the tempdir when :file_deployment_uses_destdir is set to :auto" do Chef::Config[:file_staging_uses_destdir] = :auto diff --git a/spec/unit/provider/template_spec.rb b/spec/unit/provider/template_spec.rb index 488039ad18..306fd6ea71 100644 --- a/spec/unit/provider/template_spec.rb +++ b/spec/unit/provider/template_spec.rb @@ -27,12 +27,12 @@ describe Chef::Provider::Template do let(:node) { double("Chef::Node") } let(:events) { double("Chef::Events").as_null_object } # mock all the methods let(:run_context) { double("Chef::RunContext", :node => node, :events => events) } - let(:enclosing_directory) { + let(:enclosing_directory) do canonicalize_path(File.expand_path(File.join(CHEF_SPEC_DATA, "templates"))) - } - let(:resource_path) { + end + let(:resource_path) do canonicalize_path(File.expand_path(File.join(enclosing_directory, "seattle.txt"))) - } + end # Subject @@ -61,12 +61,12 @@ describe Chef::Provider::Template do let(:node) { double("Chef::Node") } let(:events) { double("Chef::Events").as_null_object } # mock all the methods let(:run_context) { double("Chef::RunContext", :node => node, :events => events) } - let(:enclosing_directory) { + let(:enclosing_directory) do canonicalize_path(File.expand_path(File.join(CHEF_SPEC_DATA, "templates"))) - } - let(:resource_path) { + end + let(:resource_path) do canonicalize_path(File.expand_path(File.join(enclosing_directory, "seattle.txt"))) - } + end # Subject diff --git a/spec/unit/provider/user/dscl_spec.rb b/spec/unit/provider/user/dscl_spec.rb index bf8b3169d7..dfaaa377d3 100644 --- a/spec/unit/provider/user/dscl_spec.rb +++ b/spec/unit/provider/user/dscl_spec.rb @@ -24,52 +24,52 @@ describe Chef::Provider::User::Dscl do before do allow(ChefConfig).to receive(:windows?) { false } end - let(:shellcmdresult) { + let(:shellcmdresult) do Struct.new(:stdout, :stderr, :exitstatus) - } - let(:node) { + end + let(:node) do node = Chef::Node.new allow(node).to receive(:[]).with(:platform_version).and_return(mac_version) allow(node).to receive(:[]).with(:platform).and_return("mac_os_x") node - } + end - let(:events) { + let(:events) do Chef::EventDispatch::Dispatcher.new - } + end - let(:run_context) { + let(:run_context) do Chef::RunContext.new(node, {}, events) - } + end - let(:new_resource) { - r = Chef::Resource::User.new("toor") + let(:new_resource) do + r = Chef::Resource::User::DsclUser.new("toor") r.password(password) r.salt(salt) r.iterations(iterations) r - } + end - let(:provider) { + let(:provider) do Chef::Provider::User::Dscl.new(new_resource, run_context) - } + end - let(:mac_version) { + let(:mac_version) do "10.9.1" - } + end let(:password) { nil } let(:salt) { nil } let(:iterations) { nil } - let(:salted_sha512_password) { + let(:salted_sha512_password) do "0f543f021c63255e64e121a3585601b8ecfedf6d2\ 705ddac69e682a33db5dbcdb9b56a2520bc8fff63a\ 2ba6b7984c0737ff0b7949455071581f7affcd536d\ 402b6cdb097" - } + end - let(:salted_sha512_pbkdf2_password) { + let(:salted_sha512_pbkdf2_password) do "c734b6e4787c3727bb35e29fdd92b97c\ 1de12df509577a045728255ec7c6c5f5\ c18efa05ed02b682ffa7ebc05119900e\ @@ -78,24 +78,24 @@ b1d4880833aa7a190afc13e2bf0936b8\ 9464a8c234f3919082400b4f939bb77b\ c5adbbac718b7eb99463a7b679571e0f\ 1c9fef2ef08d0b9e9c2bcf644eed2ffc" - } + end - let(:salted_sha512_pbkdf2_salt) { + let(:salted_sha512_pbkdf2_salt) do "2d942d8364a9ccf2b8e5cb7ed1ff58f78\ e29dbfee7f9db58859144d061fd0058" - } + end - let(:salted_sha512_pbkdf2_iterations) { + let(:salted_sha512_pbkdf2_iterations) do 25000 - } + end - let(:vagrant_sha_512) { + let(:vagrant_sha_512) do "6f75d7190441facc34291ebbea1fc756b242d4f\ e9bcff141bccb84f1979e27e539539aa31f9f7dcc92c0cea959\ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30" - } + end - let(:vagrant_sha_512_pbkdf2) { + let(:vagrant_sha_512_pbkdf2) do "12601a90db17cbf\ 8ba4808e6382fb0d3b9d8a6c1a190477bf680ab21afb\ 6065467136e55cc208a6f74156e3daf20fb13369ef4b\ @@ -103,15 +103,15 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30" 47cca84341a7f93a27147343f89fb843fb46c0017d2\ 64afa4976baacf941b915bd1ec1ca24c30b3e759e02\ 403e02f59fe7ff5938a7636c" - } + end - let(:vagrant_sha_512_pbkdf2_salt) { + let(:vagrant_sha_512_pbkdf2_salt) do "ee954be472fdc60ddf89484781433993625f006af6ec810c08f49a7e413946a1" - } + end - let(:vagrant_sha_512_pbkdf2_iterations) { + let(:vagrant_sha_512_pbkdf2_iterations) do 34482 - } + end describe "when shelling out to dscl" do it "should run dscl with the supplied cmd /Path args" do @@ -214,9 +214,9 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30" end describe "when modifying the home directory" do - let(:current_resource) { + let(:current_resource) do new_resource.dup - } + end before do new_resource.supports({ :manage_home => true }) @@ -307,9 +307,9 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30" end describe "when on Mac 10.6" do - let(:mac_version) { + let(:mac_version) do "10.6.5" - } + end it "should raise an error" do expect { run_requirements }.to raise_error(Chef::Exceptions::User) @@ -317,9 +317,9 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30" end describe "when on Mac 10.7" do - let(:mac_version) { + let(:mac_version) do "10.7.5" - } + end describe "when password is SALTED-SHA512" do let(:password) { salted_sha512_password } @@ -340,9 +340,9 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30" [ "10.9", "10.10"].each do |version| describe "when on Mac #{version}" do - let(:mac_version) { + let(:mac_version) do "#{version}.2" - } + end describe "when password is SALTED-SHA512" do let(:password) { salted_sha512_password } @@ -413,9 +413,9 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30" let(:password) { "something" } # Load password during load_current_resource describe "on 10.7" do - let(:mac_version) { + let(:mac_version) do "10.7.5" - } + end let(:user_plist_file) { "10.7" } @@ -478,9 +478,9 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30" end describe "on 10.8" do - let(:mac_version) { + let(:mac_version) do "10.8.3" - } + end let(:user_plist_file) { "10.8" } @@ -504,9 +504,9 @@ e68d1f9821b26689312366") describe "on 10.7 upgraded to 10.8" do # In this scenario user password is still in 10.7 format - let(:mac_version) { + let(:mac_version) do "10.8.3" - } + end let(:user_plist_file) { "10.7-8" } @@ -542,9 +542,9 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30") end describe "on 10.9" do - let(:mac_version) { + let(:mac_version) do "10.9.1" - } + end let(:user_plist_file) { "10.9" } @@ -646,9 +646,9 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30") describe "prepare_password_shadow_info" do describe "when on Mac 10.7" do - let(:mac_version) { + let(:mac_version) do "10.7.1" - } + end describe "when the password is plain text" do let(:password) { "vagrant" } @@ -676,9 +676,9 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30") ["10.8", "10.9", "10.10"].each do |version| describe "when on Mac #{version}" do - let(:mac_version) { + let(:mac_version) do "#{version}.1" - } + end describe "when the password is plain text" do let(:password) { "vagrant" } diff --git a/spec/unit/provider/user/useradd_spec.rb b/spec/unit/provider/user/linux_spec.rb index 7c67449a86..ef12cec234 100644 --- a/spec/unit/provider/user/useradd_spec.rb +++ b/spec/unit/provider/user/linux_spec.rb @@ -21,7 +21,7 @@ require "spec_helper" require "chef/provider/user/useradd" -describe Chef::Provider::User::Useradd do +describe Chef::Provider::User::Linux do subject(:provider) do p = described_class.new(@new_resource, @run_context) @@ -48,4 +48,34 @@ describe Chef::Provider::User::Useradd do provider.manage_user end end + + describe "manage_home behavior" do + before(:each) do + @new_resource = Chef::Resource::User::LinuxUser.new("adam", @run_context) + @current_resource = Chef::Resource::User::LinuxUser.new("adam", @run_context) + end + + it "sets supports manage_home to true" do + Chef::Config[:treat_deprecation_warnings_as_errors] = false + expect( @new_resource.supports[:manage_home] ).to be true + end + + it "sets supports non-unique to true" do + Chef::Config[:treat_deprecation_warnings_as_errors] = false + expect( @new_resource.supports[:non_unique] ).to be true + end + + it "defaults manage_home to true" do + expect( @new_resource.manage_home ).to be true + end + + it "by default manage_home is true and we do not -M" do + expect( provider.useradd_options ).to eql([]) + end + + it "setting manage_home to false includes -M" do + @new_resource.manage_home false + expect( provider.useradd_options ).to eql(["-M"]) + end + end end diff --git a/spec/unit/provider/user/pw_spec.rb b/spec/unit/provider/user/pw_spec.rb index 1e9fda9f7e..624bcfc67d 100644 --- a/spec/unit/provider/user/pw_spec.rb +++ b/spec/unit/provider/user/pw_spec.rb @@ -24,7 +24,7 @@ describe Chef::Provider::User::Pw do @events = Chef::EventDispatch::Dispatcher.new @run_context = Chef::RunContext.new(@node, {}, @events) - @new_resource = Chef::Resource::User.new("adam") + @new_resource = Chef::Resource::User::PwUser.new("adam") @new_resource.comment "Adam Jacob" @new_resource.uid 1000 @new_resource.gid 1000 @@ -34,7 +34,7 @@ describe Chef::Provider::User::Pw do @new_resource.supports :manage_home => true - @current_resource = Chef::Resource::User.new("adam") + @current_resource = Chef::Resource::User::PwUser.new("adam") @current_resource.comment "Adam Jacob" @current_resource.uid 1000 @current_resource.gid 1000 @@ -170,7 +170,6 @@ describe Chef::Provider::User::Pw do end it "logs an appropriate message" do - expect(Chef::Log).to receive(:debug).with("user[adam] no change needed to password") @provider.modify_password end end @@ -194,7 +193,6 @@ describe Chef::Provider::User::Pw do end it "logs an appropriate message" do - expect(Chef::Log).to receive(:debug).with("user[adam] no change needed to password") @provider.modify_password end end @@ -206,7 +204,6 @@ describe Chef::Provider::User::Pw do end it "should log an appropriate message" do - expect(Chef::Log).to receive(:debug).with("user[adam] updating password") @provider.modify_password end @@ -236,7 +233,7 @@ describe Chef::Provider::User::Pw do describe "when loading the current state" do before do - @provider.new_resource = Chef::Resource::User.new("adam") + @provider.new_resource = Chef::Resource::User::PwUser.new("adam") end it "should raise an error if the required binary /usr/sbin/pw doesn't exist" do diff --git a/spec/unit/provider/user/solaris_spec.rb b/spec/unit/provider/user/solaris_spec.rb index 07a39a1f0c..860c9e41dd 100644 --- a/spec/unit/provider/user/solaris_spec.rb +++ b/spec/unit/provider/user/solaris_spec.rb @@ -25,9 +25,9 @@ require "spec_helper" describe Chef::Provider::User::Solaris do - let(:shellcmdresult) { + let(:shellcmdresult) do Struct.new(:stdout, :stderr, :exitstatus) - } + end subject(:provider) do p = described_class.new(@new_resource, @run_context) @@ -44,8 +44,8 @@ describe Chef::Provider::User::Solaris do @events = Chef::EventDispatch::Dispatcher.new @run_context = Chef::RunContext.new(@node, {}, @events) - @new_resource = Chef::Resource::User.new("adam", @run_context) - @current_resource = Chef::Resource::User.new("adam", @run_context) + @new_resource = Chef::Resource::User::SolarisUser.new("adam", @run_context) + @current_resource = Chef::Resource::User::SolarisUser.new("adam", @run_context) @new_resource.password "hocus-pocus" @@ -81,7 +81,7 @@ describe Chef::Provider::User::Solaris do @events = Chef::EventDispatch::Dispatcher.new @run_context = Chef::RunContext.new(@node, {}, @events) - @new_resource = Chef::Resource::User.new("dave") + @new_resource = Chef::Resource::User::SolarisUser.new("dave") @current_resource = @new_resource.dup @provider = Chef::Provider::User::Solaris.new(@new_resource, @run_context) diff --git a/spec/unit/provider/user/windows_spec.rb b/spec/unit/provider/user/windows_spec.rb index 4a62e6ec9d..324b5f503f 100644 --- a/spec/unit/provider/user/windows_spec.rb +++ b/spec/unit/provider/user/windows_spec.rb @@ -30,10 +30,10 @@ end describe Chef::Provider::User::Windows do before(:each) do @node = Chef::Node.new - @new_resource = Chef::Resource::User.new("monkey") + @new_resource = Chef::Resource::User::WindowsUser.new("monkey") @events = Chef::EventDispatch::Dispatcher.new @run_context = Chef::RunContext.new(@node, {}, @events) - @current_resource = Chef::Resource::User.new("monkey") + @current_resource = Chef::Resource::User::WindowsUser.new("monkey") @net_user = double("Chef::Util::Windows::NetUser") allow(Chef::Util::Windows::NetUser).to receive(:new).and_return(@net_user) @@ -89,7 +89,7 @@ describe Chef::Provider::User::Windows do describe "and the attributes do not match" do before do - @current_resource = Chef::Resource::User.new("adam") + @current_resource = Chef::Resource::User::WindowsUser.new("adam") @current_resource.comment "Adam Jacob-foo" @current_resource.uid 1111 @current_resource.gid 1111 diff --git a/spec/unit/provider/user_spec.rb b/spec/unit/provider/user_spec.rb index 1cdbe462f7..1a8ad6ad1b 100644 --- a/spec/unit/provider/user_spec.rb +++ b/spec/unit/provider/user_spec.rb @@ -190,7 +190,7 @@ describe Chef::Provider::User do end describe "compare_user" do - let(:mapping) { + let(:mapping) do { "username" => %w{adam Adam}, "comment" => ["Adam Jacob", "adam jacob"], @@ -200,7 +200,7 @@ describe Chef::Provider::User do "shell" => ["/usr/bin/zsh", "/bin/bash"], "password" => %w{abcd 12345}, } - } + end %w{uid gid comment home shell password}.each do |attribute| it "should return true if #{attribute} doesn't match" do diff --git a/spec/unit/provider_resolver_spec.rb b/spec/unit/provider_resolver_spec.rb index 5d4396ea4d..5ba5ddae03 100644 --- a/spec/unit/provider_resolver_spec.rb +++ b/spec/unit/provider_resolver_spec.rb @@ -480,7 +480,7 @@ describe Chef::ProviderResolver do end end - on_platform %w{freebsd netbsd}, platform_version: "3.1.4" do + on_platform "freebsd", os: "freebsd", platform_version: "10.3" do it "returns a Freebsd provider if it finds the /usr/local/etc/rc.d initscript" do stub_service_providers stub_service_configs(:usr_local_etc_rcd) @@ -507,7 +507,41 @@ describe Chef::ProviderResolver do expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) end - it "foo" do + it "always returns a freebsd provider by default?" do + stub_service_providers + stub_service_configs + expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + end + end + + on_platform "netbsd", os: "netbsd", platform_version: "7.0.1" do + it "returns a Freebsd provider if it finds the /usr/local/etc/rc.d initscript" do + stub_service_providers + stub_service_configs(:usr_local_etc_rcd) + expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + end + + it "returns a Freebsd provider if it finds the /etc/rc.d initscript" do + stub_service_providers + stub_service_configs(:etc_rcd) + expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + end + + it "always returns a Freebsd provider if it finds the /usr/local/etc/rc.d initscript" do + # should only care about :usr_local_etc_rcd stub in the service configs + stub_service_providers(:debian, :invokercd, :insserv, :upstart, :redhat, :systemd) + stub_service_configs(:usr_local_etc_rcd, :initd, :upstart, :xinetd, :systemd) + expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + end + + it "always returns a Freebsd provider if it finds the /usr/local/etc/rc.d initscript" do + # should only care about :etc_rcd stub in the service configs + stub_service_providers(:debian, :invokercd, :insserv, :upstart, :redhat, :systemd) + stub_service_configs(:etc_rcd, :initd, :upstart, :xinetd, :systemd) + expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) + end + + it "always returns a freebsd provider by default?" do stub_service_providers stub_service_configs expect(resolved_provider).to eql(Chef::Provider::Service::Freebsd) @@ -517,347 +551,355 @@ describe Chef::ProviderResolver do end PROVIDERS = - { - bash: [ Chef::Resource::Bash, Chef::Provider::Script ], - breakpoint: [ Chef::Resource::Breakpoint, Chef::Provider::Breakpoint ], - chef_gem: [ Chef::Resource::ChefGem, Chef::Provider::Package::Rubygems ], - cookbook_file: [ Chef::Resource::CookbookFile, Chef::Provider::CookbookFile ], - csh: [ Chef::Resource::Csh, Chef::Provider::Script ], - deploy: [ Chef::Resource::Deploy, Chef::Provider::Deploy::Timestamped ], - deploy_revision: [ Chef::Resource::DeployRevision, Chef::Provider::Deploy::Revision ], - directory: [ Chef::Resource::Directory, Chef::Provider::Directory ], - easy_install_package: [ Chef::Resource::EasyInstallPackage, Chef::Provider::Package::EasyInstall ], - erl_call: [ Chef::Resource::ErlCall, Chef::Provider::ErlCall ], - execute: [ Chef::Resource::Execute, Chef::Provider::Execute ], - file: [ Chef::Resource::File, Chef::Provider::File ], - gem_package: [ Chef::Resource::GemPackage, Chef::Provider::Package::Rubygems ], - git: [ Chef::Resource::Git, Chef::Provider::Git ], - group: [ Chef::Resource::Group, Chef::Provider::Group::Gpasswd ], - homebrew_package: [ Chef::Resource::HomebrewPackage, Chef::Provider::Package::Homebrew ], - http_request: [ Chef::Resource::HttpRequest, Chef::Provider::HttpRequest ], - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], - link: [ Chef::Resource::Link, Chef::Provider::Link ], - log: [ Chef::Resource::Log, Chef::Provider::Log::ChefLog ], - macports_package: [ Chef::Resource::MacportsPackage, Chef::Provider::Package::Macports ], - mdadm: [ Chef::Resource::Mdadm, Chef::Provider::Mdadm ], - mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Mount ], - perl: [ Chef::Resource::Perl, Chef::Provider::Script ], - portage_package: [ Chef::Resource::PortagePackage, Chef::Provider::Package::Portage ], - python: [ Chef::Resource::Python, Chef::Provider::Script ], - remote_directory: [ Chef::Resource::RemoteDirectory, Chef::Provider::RemoteDirectory ], - route: [ Chef::Resource::Route, Chef::Provider::Route ], - ruby: [ Chef::Resource::Ruby, Chef::Provider::Script ], - ruby_block: [ Chef::Resource::RubyBlock, Chef::Provider::RubyBlock ], - script: [ Chef::Resource::Script, Chef::Provider::Script ], - subversion: [ Chef::Resource::Subversion, Chef::Provider::Subversion ], - template: [ Chef::Resource::Template, Chef::Provider::Template ], - timestamped_deploy: [ Chef::Resource::TimestampedDeploy, Chef::Provider::Deploy::Timestamped ], - user: [ Chef::Resource::User, Chef::Provider::User::Useradd ], - whyrun_safe_ruby_block: [ Chef::Resource::WhyrunSafeRubyBlock, Chef::Provider::WhyrunSafeRubyBlock ], - - # We want to check that these are unsupported: - apt_package: nil, - bff_package: nil, - dpkg_package: nil, - dsc_script: nil, - ips_package: nil, - pacman_package: nil, - paludis_package: nil, - rpm_package: nil, - smartos_package: nil, - solaris_package: nil, - yum_package: nil, - windows_package: nil, - windows_service: nil, - - "linux" => { - apt_package: [ Chef::Resource::AptPackage, Chef::Provider::Package::Apt ], - dpkg_package: [ Chef::Resource::DpkgPackage, Chef::Provider::Package::Dpkg ], - pacman_package: [ Chef::Resource::PacmanPackage, Chef::Provider::Package::Pacman ], - paludis_package: [ Chef::Resource::PaludisPackage, Chef::Provider::Package::Paludis ], - rpm_package: [ Chef::Resource::RpmPackage, Chef::Provider::Package::Rpm ], - yum_package: [ Chef::Resource::YumPackage, Chef::Provider::Package::Yum ], - - "debian" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Debian ], - package: [ Chef::Resource::AptPackage, Chef::Provider::Package::Apt ], - # service: [ Chef::Resource::DebianService, Chef::Provider::Service::Debian ], + { + bash: [ Chef::Resource::Bash, Chef::Provider::Script ], + breakpoint: [ Chef::Resource::Breakpoint, Chef::Provider::Breakpoint ], + chef_gem: [ Chef::Resource::ChefGem, Chef::Provider::Package::Rubygems ], + cookbook_file: [ Chef::Resource::CookbookFile, Chef::Provider::CookbookFile ], + csh: [ Chef::Resource::Csh, Chef::Provider::Script ], + deploy: [ Chef::Resource::Deploy, Chef::Provider::Deploy::Timestamped ], + deploy_revision: [ Chef::Resource::DeployRevision, Chef::Provider::Deploy::Revision ], + directory: [ Chef::Resource::Directory, Chef::Provider::Directory ], + easy_install_package: [ Chef::Resource::EasyInstallPackage, Chef::Provider::Package::EasyInstall ], + erl_call: [ Chef::Resource::ErlCall, Chef::Provider::ErlCall ], + execute: [ Chef::Resource::Execute, Chef::Provider::Execute ], + file: [ Chef::Resource::File, Chef::Provider::File ], + gem_package: [ Chef::Resource::GemPackage, Chef::Provider::Package::Rubygems ], + git: [ Chef::Resource::Git, Chef::Provider::Git ], + group: [ Chef::Resource::Group, Chef::Provider::Group::Gpasswd ], + homebrew_package: [ Chef::Resource::HomebrewPackage, Chef::Provider::Package::Homebrew ], + http_request: [ Chef::Resource::HttpRequest, Chef::Provider::HttpRequest ], + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + link: [ Chef::Resource::Link, Chef::Provider::Link ], + log: [ Chef::Resource::Log, Chef::Provider::Log::ChefLog ], + macports_package: [ Chef::Resource::MacportsPackage, Chef::Provider::Package::Macports ], + mdadm: [ Chef::Resource::Mdadm, Chef::Provider::Mdadm ], + mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Mount ], + perl: [ Chef::Resource::Perl, Chef::Provider::Script ], + portage_package: [ Chef::Resource::PortagePackage, Chef::Provider::Package::Portage ], + python: [ Chef::Resource::Python, Chef::Provider::Script ], + remote_directory: [ Chef::Resource::RemoteDirectory, Chef::Provider::RemoteDirectory ], + route: [ Chef::Resource::Route, Chef::Provider::Route ], + ruby: [ Chef::Resource::Ruby, Chef::Provider::Script ], + ruby_block: [ Chef::Resource::RubyBlock, Chef::Provider::RubyBlock ], + script: [ Chef::Resource::Script, Chef::Provider::Script ], + subversion: [ Chef::Resource::Subversion, Chef::Provider::Subversion ], + template: [ Chef::Resource::Template, Chef::Provider::Template ], + timestamped_deploy: [ Chef::Resource::TimestampedDeploy, Chef::Provider::Deploy::Timestamped ], + aix_user: [ Chef::Resource::User::AixUser, Chef::Provider::User::Aix ], + dscl_user: [ Chef::Resource::User::DsclUser, Chef::Provider::User::Dscl ], + linux_user: [ Chef::Resource::User::LinuxUser, Chef::Provider::User::Linux ], + pw_user: [ Chef::Resource::User::PwUser, Chef::Provider::User::Pw ], + solaris_user: [ Chef::Resource::User::SolarisUser, Chef::Provider::User::Solaris ], + windows_user: [ Chef::Resource::User::WindowsUser, Chef::Provider::User::Windows ], + whyrun_safe_ruby_block: [ Chef::Resource::WhyrunSafeRubyBlock, Chef::Provider::WhyrunSafeRubyBlock ], + + # We want to check that these are unsupported: + apt_package: nil, + bff_package: nil, + dpkg_package: nil, + dsc_script: nil, + ips_package: nil, + pacman_package: nil, + paludis_package: nil, + rpm_package: nil, + smartos_package: nil, + solaris_package: nil, + yum_package: nil, + windows_package: nil, + windows_service: nil, + + "linux" => { + apt_package: [ Chef::Resource::AptPackage, Chef::Provider::Package::Apt ], + dpkg_package: [ Chef::Resource::DpkgPackage, Chef::Provider::Package::Dpkg ], + pacman_package: [ Chef::Resource::PacmanPackage, Chef::Provider::Package::Pacman ], + paludis_package: [ Chef::Resource::PaludisPackage, Chef::Provider::Package::Paludis ], + rpm_package: [ Chef::Resource::RpmPackage, Chef::Provider::Package::Rpm ], + yum_package: [ Chef::Resource::YumPackage, Chef::Provider::Package::Yum ], "debian" => { - "7.0" => { - }, - "6.0" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], - # service: [ Chef::Resource::InsservService, Chef::Provider::Service::Insserv ], - }, - "5.0" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Debian ], + package: [ Chef::Resource::AptPackage, Chef::Provider::Package::Apt ], + # service: [ Chef::Resource::DebianService, Chef::Provider::Service::Debian ], + + "debian" => { + "7.0" => { + }, + "6.0" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + # service: [ Chef::Resource::InsservService, Chef::Provider::Service::Insserv ], + }, + "5.0" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + }, + }, + "gcel" => { + "3.1.4" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + }, + }, + "linaro" => { + "3.1.4" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + }, + }, + "linuxmint" => { + "3.1.4" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + # service: [ Chef::Resource::UpstartService, Chef::Provider::Service::Upstart ], + }, + }, + "raspbian" => { + "3.1.4" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + }, + }, + "ubuntu" => { + "11.10" => { + }, + "10.04" => { + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], + }, }, }, - "gcel" => { - "3.1.4" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], - }, - }, - "linaro" => { - "3.1.4" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], - }, - }, - "linuxmint" => { - "3.1.4" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], - # service: [ Chef::Resource::UpstartService, Chef::Provider::Service::Upstart ], - }, - }, - "raspbian" => { - "3.1.4" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], - }, - }, - "ubuntu" => { - "11.10" => { - }, - "10.04" => { - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig ], - }, - }, - }, - - "arch" => { - # TODO should be Chef::Resource::PacmanPackage - package: [ Chef::Resource::Package, Chef::Provider::Package::Pacman ], "arch" => { - "3.1.4" => { - }, - }, - }, - - "freebsd" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Pw ], - user: [ Chef::Resource::User, Chef::Provider::User::Pw ], + # TODO should be Chef::Resource::PacmanPackage + package: [ Chef::Resource::Package, Chef::Provider::Package::Pacman ], - "freebsd" => { - "3.1.4" => { + "arch" => { + "3.1.4" => { + }, }, }, - }, - "suse" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Gpasswd ], + "suse" => { - "12.0" => { - }, - %w{11.1 11.2 11.3} => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Suse ], + group: [ Chef::Resource::Group, Chef::Provider::Group::Gpasswd ], + "suse" => { + "12.0" => { + }, + %w{11.1 11.2 11.3} => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Suse ], + }, + }, + "opensuse" => { + # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], + package: [ Chef::Resource::ZypperPackage, Chef::Provider::Package::Zypper ], + group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], + "12.3" => { + }, + "12.2" => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Suse ], + }, }, }, - "opensuse" => { - # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], - package: [ Chef::Resource::ZypperPackage, Chef::Provider::Package::Zypper ], - group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], - "12.3" => { - }, - "12.2" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Suse ], + + "gentoo" => { + # TODO should be Chef::Resource::PortagePackage + package: [ Chef::Resource::Package, Chef::Provider::Package::Portage ], + portage_package: [ Chef::Resource::PortagePackage, Chef::Provider::Package::Portage ], + # service: [ Chef::Resource::GentooService, Chef::Provider::Service::Gentoo ], + + "gentoo" => { + "3.1.4" => { + }, }, }, - }, - "gentoo" => { - # TODO should be Chef::Resource::PortagePackage - package: [ Chef::Resource::Package, Chef::Provider::Package::Portage ], - portage_package: [ Chef::Resource::PortagePackage, Chef::Provider::Package::Portage ], - # service: [ Chef::Resource::GentooService, Chef::Provider::Service::Gentoo ], - - "gentoo" => { - "3.1.4" => { + "rhel" => { + # service: [ Chef::Resource::SystemdService, Chef::Provider::Service::Systemd ], + package: [ Chef::Resource::YumPackage, Chef::Provider::Package::Yum ], + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Redhat ], + + %w{amazon xcp xenserver ibm_powerkvm cloudlinux parallels} => { + "3.1.4" => { + # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], + }, + }, + %w{redhat centos scientific oracle} => { + "7.0" => { + }, + "6.0" => { + # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], + }, + }, + "fedora" => { + "15.0" => { + }, + "14.0" => { + # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], + }, }, }, + }, - "rhel" => { - # service: [ Chef::Resource::SystemdService, Chef::Provider::Service::Systemd ], - package: [ Chef::Resource::YumPackage, Chef::Provider::Package::Yum ], - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Redhat ], + "freebsd" => { + "freebsd" => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Pw ], + user: [ Chef::Resource::User::PwUser, Chef::Provider::User::Pw ], - %w{amazon xcp xenserver ibm_powerkvm cloudlinux parallels} => { - "3.1.4" => { - # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], - }, - }, - %w{redhat centos scientific oracle} => { - "7.0" => { - }, - "6.0" => { - # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], - }, - }, - "fedora" => { - "15.0" => { - }, - "14.0" => { - # service: [ Chef::Resource::RedhatService, Chef::Provider::Service::Redhat ], + "freebsd" => { + "10.3" => { + }, }, }, }, - }, + "darwin" => { + %w{mac_os_x mac_os_x_server} => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Dscl ], + package: [ Chef::Resource::HomebrewPackage, Chef::Provider::Package::Homebrew ], + osx_profile: [ Chef::Resource::OsxProfile, Chef::Provider::OsxProfile], + user: [ Chef::Resource::User::DsclUser, Chef::Provider::User::Dscl ], - "darwin" => { - %w{mac_os_x mac_os_x_server} => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Dscl ], - package: [ Chef::Resource::HomebrewPackage, Chef::Provider::Package::Homebrew ], - osx_profile: [ Chef::Resource::OsxProfile, Chef::Provider::OsxProfile], - user: [ Chef::Resource::User, Chef::Provider::User::Dscl ], - - "mac_os_x" => { - "10.9.2" => { + "mac_os_x" => { + "10.9.2" => { + }, }, }, }, - }, - - "windows" => { - batch: [ Chef::Resource::Batch, Chef::Provider::Batch ], - dsc_script: [ Chef::Resource::DscScript, Chef::Provider::DscScript ], - env: [ Chef::Resource::Env, Chef::Provider::Env::Windows ], - group: [ Chef::Resource::Group, Chef::Provider::Group::Windows ], - mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Windows ], - package: [ Chef::Resource::WindowsPackage, Chef::Provider::Package::Windows ], - powershell_script: [ Chef::Resource::PowershellScript, Chef::Provider::PowershellScript ], - service: [ Chef::Resource::WindowsService, Chef::Provider::Service::Windows ], - user: [ Chef::Resource::User, Chef::Provider::User::Windows ], - windows_package: [ Chef::Resource::WindowsPackage, Chef::Provider::Package::Windows ], - windows_service: [ Chef::Resource::WindowsService, Chef::Provider::Service::Windows ], "windows" => { - %w{mswin mingw32 windows} => { - "10.9.2" => { + batch: [ Chef::Resource::Batch, Chef::Provider::Batch ], + dsc_script: [ Chef::Resource::DscScript, Chef::Provider::DscScript ], + env: [ Chef::Resource::Env, Chef::Provider::Env::Windows ], + group: [ Chef::Resource::Group, Chef::Provider::Group::Windows ], + mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Windows ], + package: [ Chef::Resource::WindowsPackage, Chef::Provider::Package::Windows ], + powershell_script: [ Chef::Resource::PowershellScript, Chef::Provider::PowershellScript ], + service: [ Chef::Resource::WindowsService, Chef::Provider::Service::Windows ], + user: [ Chef::Resource::User::WindowsUser, Chef::Provider::User::Windows ], + windows_package: [ Chef::Resource::WindowsPackage, Chef::Provider::Package::Windows ], + windows_service: [ Chef::Resource::WindowsService, Chef::Provider::Service::Windows ], + + "windows" => { + %w{mswin mingw32 windows} => { + "10.9.2" => { + }, }, }, }, - }, - - "aix" => { - bff_package: [ Chef::Resource::BffPackage, Chef::Provider::Package::Aix ], - cron: [ Chef::Resource::Cron, Chef::Provider::Cron::Aix ], - group: [ Chef::Resource::Group, Chef::Provider::Group::Aix ], - ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Aix ], - mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Aix ], - # TODO should be Chef::Resource::BffPackage - package: [ Chef::Resource::Package, Chef::Provider::Package::Aix ], - rpm_package: [ Chef::Resource::RpmPackage, Chef::Provider::Package::Rpm ], - user: [ Chef::Resource::User, Chef::Provider::User::Aix ], - # service: [ Chef::Resource::AixService, Chef::Provider::Service::Aix ], "aix" => { + bff_package: [ Chef::Resource::BffPackage, Chef::Provider::Package::Aix ], + cron: [ Chef::Resource::Cron, Chef::Provider::Cron::Aix ], + group: [ Chef::Resource::Group, Chef::Provider::Group::Aix ], + ifconfig: [ Chef::Resource::Ifconfig, Chef::Provider::Ifconfig::Aix ], + mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Aix ], + # TODO should be Chef::Resource::BffPackage + package: [ Chef::Resource::Package, Chef::Provider::Package::Aix ], + rpm_package: [ Chef::Resource::RpmPackage, Chef::Provider::Package::Rpm ], + user: [ Chef::Resource::User::AixUser, Chef::Provider::User::Aix ], + # service: [ Chef::Resource::AixService, Chef::Provider::Service::Aix ], + "aix" => { - "5.6" => { + "aix" => { + "5.6" => { + }, }, }, }, - }, - "hpux" => { "hpux" => { "hpux" => { - "3.1.4" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], + "hpux" => { + "3.1.4" => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], + }, }, }, }, - }, - "netbsd" => { "netbsd" => { "netbsd" => { - "3.1.4" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Groupmod ], + "netbsd" => { + "3.1.4" => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Groupmod ], + }, }, }, }, - }, - - "openbsd" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], - package: [ Chef::Resource::OpenbsdPackage, Chef::Provider::Package::Openbsd ], "openbsd" => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], + package: [ Chef::Resource::OpenbsdPackage, Chef::Provider::Package::Openbsd ], + "openbsd" => { - "3.1.4" => { + "openbsd" => { + "3.1.4" => { + }, }, }, }, - }, - - "solaris2" => { - group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], - ips_package: [ Chef::Resource::IpsPackage, Chef::Provider::Package::Ips ], - package: [ Chef::Resource::SolarisPackage, Chef::Provider::Package::Solaris ], - mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Solaris ], - solaris_package: [ Chef::Resource::SolarisPackage, Chef::Provider::Package::Solaris ], - "smartos" => { - smartos_package: [ Chef::Resource::SmartosPackage, Chef::Provider::Package::SmartOS ], - package: [ Chef::Resource::SmartosPackage, Chef::Provider::Package::SmartOS ], + "solaris2" => { + group: [ Chef::Resource::Group, Chef::Provider::Group::Usermod ], + ips_package: [ Chef::Resource::IpsPackage, Chef::Provider::Package::Ips ], + package: [ Chef::Resource::SolarisPackage, Chef::Provider::Package::Solaris ], + mount: [ Chef::Resource::Mount, Chef::Provider::Mount::Solaris ], + solaris_package: [ Chef::Resource::SolarisPackage, Chef::Provider::Package::Solaris ], "smartos" => { - "3.1.4" => { - }, - }, - }, + smartos_package: [ Chef::Resource::SmartosPackage, Chef::Provider::Package::SmartOS ], + package: [ Chef::Resource::SmartosPackage, Chef::Provider::Package::SmartOS ], - "solaris2" => { - "nexentacore" => { - "3.1.4" => { - }, - }, - "omnios" => { - "3.1.4" => { - user: [ Chef::Resource::User, Chef::Provider::User::Solaris ], - }, - }, - "openindiana" => { - "3.1.4" => { - }, - }, - "opensolaris" => { - "3.1.4" => { + "smartos" => { + "3.1.4" => { + }, }, }, + "solaris2" => { - user: [ Chef::Resource::User, Chef::Provider::User::Solaris ], - "5.11" => { - package: [ Chef::Resource::IpsPackage, Chef::Provider::Package::Ips ], - }, - "5.9" => { + "nexentacore" => { + "3.1.4" => { + }, + }, + "omnios" => { + "3.1.4" => { + user: [ Chef::Resource::User::SolarisUser, Chef::Provider::User::Solaris ], + }, + }, + "openindiana" => { + "3.1.4" => { + }, + }, + "opensolaris" => { + "3.1.4" => { + }, + }, + "solaris2" => { + user: [ Chef::Resource::User::SolarisUser, Chef::Provider::User::Solaris ], + "5.11" => { + package: [ Chef::Resource::IpsPackage, Chef::Provider::Package::Ips ], + }, + "5.9" => { + }, }, }, - }, - }, + }, - "solaris" => { "solaris" => { "solaris" => { - "3.1.4" => { + "solaris" => { + "3.1.4" => { + }, }, }, }, - }, - "exherbo" => { "exherbo" => { "exherbo" => { - "3.1.4" => { - # TODO should be Chef::Resource::PaludisPackage - package: [ Chef::Resource::Package, Chef::Provider::Package::Paludis ], + "exherbo" => { + "3.1.4" => { + # TODO should be Chef::Resource::PaludisPackage + package: [ Chef::Resource::Package, Chef::Provider::Package::Paludis ], + }, }, }, }, - }, - } + } def self.create_provider_tests(providers, test, expected, filter) expected = expected.merge(providers.select { |key, value| key.is_a?(Symbol) }) diff --git a/spec/unit/recipe_spec.rb b/spec/unit/recipe_spec.rb index 3c30f96b20..f42b7563f5 100644 --- a/spec/unit/recipe_spec.rb +++ b/spec/unit/recipe_spec.rb @@ -75,15 +75,15 @@ describe Chef::Recipe do end it "should require a name argument" do - expect { + expect do recipe.cat - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should allow regular errors (not NameErrors) to pass unchanged" do - expect { + expect do recipe.cat("felix") { raise ArgumentError, "You Suck" } - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should add our zen_master to the collection" do @@ -288,9 +288,10 @@ describe Chef::Recipe do end it "validating resources via build_resource" do - expect {recipe.build_resource(:remote_file, "klopp") do - source Chef::DelayedEvaluator.new { "http://chef.io" } - end}.to_not raise_error + expect do + recipe.build_resource(:remote_file, "klopp") do + source Chef::DelayedEvaluator.new { "http://chef.io" } + end end.to_not raise_error end end diff --git a/spec/unit/resource/apt_repository_spec.rb b/spec/unit/resource/apt_repository_spec.rb index cd55ce66cc..cd21873fed 100644 --- a/spec/unit/resource/apt_repository_spec.rb +++ b/spec/unit/resource/apt_repository_spec.rb @@ -19,8 +19,10 @@ require "spec_helper" describe Chef::Resource::AptRepository do - - let(:resource) { Chef::Resource::AptRepository.new("multiverse") } + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:resource) { Chef::Resource::AptRepository.new("multiverse", run_context) } it "should create a new Chef::Resource::AptUpdate" do expect(resource).to be_a_kind_of(Chef::Resource) @@ -35,4 +37,14 @@ describe Chef::Resource::AptRepository do expect(resource.distribution(nil)).to eql(nil) expect(resource.distribution).to eql(nil) end + + it "should resolve to a Noop class when uses_apt? is false" do + expect(Chef::Provider::AptRepository).to receive(:uses_apt?).and_return(false) + expect(resource.provider_for_action(:add)).to be_a(Chef::Provider::Noop) + end + + it "should resolve to a AptRepository class when uses_apt? is true" do + expect(Chef::Provider::AptRepository).to receive(:uses_apt?).and_return(true) + expect(resource.provider_for_action(:add)).to be_a(Chef::Provider::AptRepository) + end end diff --git a/spec/unit/resource/apt_update_spec.rb b/spec/unit/resource/apt_update_spec.rb index 8015cb03b3..6fcba4adce 100644 --- a/spec/unit/resource/apt_update_spec.rb +++ b/spec/unit/resource/apt_update_spec.rb @@ -19,8 +19,10 @@ require "spec_helper" describe Chef::Resource::AptUpdate do - - let(:resource) { Chef::Resource::AptUpdate.new("update") } + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:resource) { Chef::Resource::AptUpdate.new("update", run_context) } it "should create a new Chef::Resource::AptUpdate" do expect(resource).to be_a_kind_of(Chef::Resource) @@ -35,4 +37,14 @@ describe Chef::Resource::AptUpdate do resource.frequency(400) expect(resource.frequency).to eql(400) end + + it "should resolve to a Noop class when uses_apt? is false" do + expect(Chef::Provider::AptUpdate).to receive(:uses_apt?).and_return(false) + expect(resource.provider_for_action(:add)).to be_a(Chef::Provider::Noop) + end + + it "should resolve to a AptUpdate class when uses_apt? is true" do + expect(Chef::Provider::AptUpdate).to receive(:uses_apt?).and_return(true) + expect(resource.provider_for_action(:add)).to be_a(Chef::Provider::AptUpdate) + end end diff --git a/spec/unit/resource/dsc_resource_spec.rb b/spec/unit/resource/dsc_resource_spec.rb index 00e667c9de..b610c262cc 100644 --- a/spec/unit/resource/dsc_resource_spec.rb +++ b/spec/unit/resource/dsc_resource_spec.rb @@ -24,16 +24,16 @@ describe Chef::Resource::DscResource do let(:dsc_test_timeout) { 101 } context "when Powershell supports Dsc" do - let(:dsc_test_run_context) { + let(:dsc_test_run_context) do node = Chef::Node.new node.automatic[:languages][:powershell][:version] = "5.0.10018.0" empty_events = Chef::EventDispatch::Dispatcher.new Chef::RunContext.new(node, {}, empty_events) - } + end - let(:dsc_test_resource) { + let(:dsc_test_resource) do Chef::Resource::DscResource.new(dsc_test_resource_name, dsc_test_run_context) - } + end it "has a default action of `:run`" do expect(dsc_test_resource.action).to eq([:run]) @@ -71,16 +71,16 @@ describe Chef::Resource::DscResource do end it "raises a TypeError if property_name is not a symbol" do - expect { + expect do dsc_test_resource.property("Foo", dsc_test_property_value) - }.to raise_error(TypeError) + end.to raise_error(TypeError) end context "when using DelayedEvaluators" do it "allows setting a dsc property with a property name of type Symbol" do - dsc_test_resource.property(dsc_test_property_name, Chef::DelayedEvaluator.new { + dsc_test_resource.property(dsc_test_property_name, Chef::DelayedEvaluator.new do dsc_test_property_value - }) + end) expect(dsc_test_resource.property(dsc_test_property_name)).to eq(dsc_test_property_value) expect(dsc_test_resource.properties[dsc_test_property_name]).to eq(dsc_test_property_value) end diff --git a/spec/unit/resource/dsc_script_spec.rb b/spec/unit/resource/dsc_script_spec.rb index 4892049884..f0c81e43b5 100644 --- a/spec/unit/resource/dsc_script_spec.rb +++ b/spec/unit/resource/dsc_script_spec.rb @@ -22,15 +22,15 @@ describe Chef::Resource::DscScript do let(:dsc_test_resource_name) { "DSCTest" } context "when Powershell supports Dsc" do - let(:dsc_test_run_context) { + let(:dsc_test_run_context) do node = Chef::Node.new node.automatic[:languages][:powershell][:version] = "4.0" empty_events = Chef::EventDispatch::Dispatcher.new Chef::RunContext.new(node, {}, empty_events) - } - let(:dsc_test_resource) { + end + let(:dsc_test_resource) do Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context) - } + end let(:configuration_code) { 'echo "This is supposed to create a configuration document."' } let(:configuration_path) { "c:/myconfigs/formatc.ps1" } let(:configuration_name) { "formatme" } diff --git a/spec/unit/resource/freebsd_package_spec.rb b/spec/unit/resource/freebsd_package_spec.rb index 0842114c47..4edc3dbc78 100644 --- a/spec/unit/resource/freebsd_package_spec.rb +++ b/spec/unit/resource/freebsd_package_spec.rb @@ -52,10 +52,10 @@ describe Chef::Resource::FreebsdPackage do end end - describe "if __Freebsd_version is greater than or equal to 1000017" do + describe "if freebsd_version is greater than or equal to 1000017" do it "should be Freebsd::Pkgng" do - [1000017, 1000018, 1000500, 1001001, 1100000].each do |__freebsd_version| - @node.automatic_attrs[:os_version] = __freebsd_version + [1000017, 1000018, 1000500, 1001001, 1100000].each do |freebsd_version| + @node.automatic_attrs[:os_version] = freebsd_version @resource.after_created expect(@resource.provider).to eq(Chef::Provider::Package::Freebsd::Pkgng) end @@ -71,13 +71,13 @@ describe Chef::Resource::FreebsdPackage do end end - describe "if __Freebsd_version is less than 1000017 and pkgng not enabled" do + describe "if freebsd_version is less than 1000017 and pkgng not enabled" do it "should be Freebsd::Pkg" do pkg_enabled = OpenStruct.new(:stdout => "\n") allow(@resource).to receive(:shell_out!).with("make -V WITH_PKGNG", :env => nil).and_return(pkg_enabled) - [1000016, 1000000, 901503, 902506, 802511].each do |__freebsd_version| - @node.automatic_attrs[:os_version] = __freebsd_version + [1000016, 1000000, 901503, 902506, 802511].each do |freebsd_version| + @node.automatic_attrs[:os_version] = freebsd_version @resource.after_created expect(@resource.provider).to eq(Chef::Provider::Package::Freebsd::Pkg) end diff --git a/spec/unit/resource/launchd_spec.rb b/spec/unit/resource/launchd_spec.rb index 95febc47cf..98d21a8234 100644 --- a/spec/unit/resource/launchd_spec.rb +++ b/spec/unit/resource/launchd_spec.rb @@ -4,10 +4,11 @@ require "spec_helper" describe Chef::Resource::Launchd do @launchd = Chef::Resource::Launchd.new("io.chef.chef-client") - let(:resource) { Chef::Resource::Launchd.new( + let(:resource) do + Chef::Resource::Launchd.new( "io.chef.chef-client", run_context - )} + ) end it "should create a new Chef::Resource::Launchd" do expect(resource).to be_a_kind_of(Chef::Resource) diff --git a/spec/unit/resource/osx_profile_spec.rb b/spec/unit/resource/osx_profile_spec.rb index 7bd504d414..513e570e7c 100644 --- a/spec/unit/resource/osx_profile_spec.rb +++ b/spec/unit/resource/osx_profile_spec.rb @@ -19,10 +19,11 @@ require "spec_helper" describe Chef::Resource::OsxProfile do - let(:resource) { Chef::Resource::OsxProfile.new( + let(:resource) do + Chef::Resource::OsxProfile.new( "Test Profile Resource", run_context) - } + end it "should create a new Chef::Resource::OsxProfile" do expect(resource).to be_a_kind_of(Chef::Resource) diff --git a/spec/unit/resource/remote_file_spec.rb b/spec/unit/resource/remote_file_spec.rb index 718129aba3..5fac457ebf 100644 --- a/spec/unit/resource/remote_file_spec.rb +++ b/spec/unit/resource/remote_file_spec.rb @@ -86,15 +86,15 @@ describe Chef::Resource::RemoteFile do end it "should only accept a single argument if a delayed evalutor is used" do - expect { + expect do @resource.source("http://opscode.com/", Chef::DelayedEvaluator.new { "http://opscode.com/" }) - }.to raise_error(Chef::Exceptions::InvalidRemoteFileURI) + end.to raise_error(Chef::Exceptions::InvalidRemoteFileURI) end it "should only accept a single array item if a delayed evalutor is used" do - expect { + expect do @resource.source(["http://opscode.com/", Chef::DelayedEvaluator.new { "http://opscode.com/" }]) - }.to raise_error(Chef::Exceptions::InvalidRemoteFileURI) + end.to raise_error(Chef::Exceptions::InvalidRemoteFileURI) end it "does not accept a non-URI as the source" do @@ -102,10 +102,10 @@ describe Chef::Resource::RemoteFile do end it "does not accept a non-URI as the source when read from a delayed evaluator" do - expect { + expect do @resource.source(Chef::DelayedEvaluator.new { "not-a-uri" }) @resource.source - }.to raise_error(Chef::Exceptions::InvalidRemoteFileURI) + end.to raise_error(Chef::Exceptions::InvalidRemoteFileURI) end it "should raise an exception when source is an empty array" do diff --git a/spec/unit/resource/service_spec.rb b/spec/unit/resource/service_spec.rb index e06f5bca5e..7aadc55532 100644 --- a/spec/unit/resource/service_spec.rb +++ b/spec/unit/resource/service_spec.rb @@ -53,9 +53,9 @@ describe Chef::Resource::Service do end it "should not accept a regexp for the service pattern" do - expect { + expect do @resource.pattern /.*/ - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should accept a string for the service start command" do @@ -64,9 +64,9 @@ describe Chef::Resource::Service do end it "should not accept a regexp for the service start command" do - expect { + expect do @resource.start_command /.*/ - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should accept a string for the service stop command" do @@ -75,9 +75,9 @@ describe Chef::Resource::Service do end it "should not accept a regexp for the service stop command" do - expect { + expect do @resource.stop_command /.*/ - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should accept a string for the service status command" do @@ -86,9 +86,9 @@ describe Chef::Resource::Service do end it "should not accept a regexp for the service status command" do - expect { + expect do @resource.status_command /.*/ - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should accept a string for the service restart command" do @@ -97,9 +97,9 @@ describe Chef::Resource::Service do end it "should not accept a regexp for the service restart command" do - expect { + expect do @resource.restart_command /.*/ - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should accept a string for the service reload command" do @@ -108,9 +108,9 @@ describe Chef::Resource::Service do end it "should not accept a regexp for the service reload command" do - expect { + expect do @resource.reload_command /.*/ - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should accept a string for the service init command" do @@ -119,9 +119,9 @@ describe Chef::Resource::Service do end it "should not accept a regexp for the service init command" do - expect { + expect do @resource.init_command /.*/ - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end %w{enabled running}.each do |attrib| diff --git a/spec/unit/resource/user_spec.rb b/spec/unit/resource/user_spec.rb index 9648ee1305..138ffb1bfe 100644 --- a/spec/unit/resource/user_spec.rb +++ b/spec/unit/resource/user_spec.rb @@ -29,7 +29,7 @@ describe Chef::Resource::User, "initialize" do end it "should set the resource_name to :user" do - expect(@resource.resource_name).to eql(:user) + expect(@resource.resource_name).to eql(:user_resource_abstract_base_class) end it "should set the username equal to the argument to initialize" do diff --git a/spec/unit/resource_collection_spec.rb b/spec/unit/resource_collection_spec.rb index 3fec2d9477..5feb34833a 100644 --- a/spec/unit/resource_collection_spec.rb +++ b/spec/unit/resource_collection_spec.rb @@ -98,11 +98,11 @@ describe Chef::ResourceCollection do it "should allow you to iterate over every resource in the collection" do load_up_resources results = Array.new - expect { + expect do rc.each do |r| results << r.name end - }.not_to raise_error + end.not_to raise_error results.each_index do |i| case i when 0 @@ -120,11 +120,11 @@ describe Chef::ResourceCollection do it "should allow you to iterate over every resource by index" do load_up_resources results = Array.new - expect { + expect do rc.each_index do |i| results << rc[i].name end - }.not_to raise_error + end.not_to raise_error results.each_index do |i| case i when 0 diff --git a/spec/unit/resource_definition_spec.rb b/spec/unit/resource_definition_spec.rb index 45dfaffca7..cc19cc7a01 100644 --- a/spec/unit/resource_definition_spec.rb +++ b/spec/unit/resource_definition_spec.rb @@ -53,26 +53,26 @@ describe Chef::ResourceDefinition do end it "should accept a new definition with a symbol for a name" do - expect { + expect do defn.define :smoke do end - }.not_to raise_error - expect { + end.not_to raise_error + expect do defn.define "george washington" do end - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) expect(defn.name).to eql(:smoke) end it "should accept a new definition with a hash" do - expect { + expect do defn.define :smoke, :cigar => "cuban", :cigarette => "marlboro" do end - }.not_to raise_error + end.not_to raise_error end it "should expose the prototype hash params in the params hash" do - defn.define :smoke, :cigar => "cuban", :cigarette => "marlboro" do; end + defn.define(:smoke, :cigar => "cuban", :cigarette => "marlboro") {} expect(defn.params[:cigar]).to eql("cuban") expect(defn.params[:cigarette]).to eql("marlboro") end @@ -91,16 +91,16 @@ describe Chef::ResourceDefinition do end it "should raise an exception if prototype_params is not a hash" do - expect { + expect do defn.define :monkey, Array.new do end - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should raise an exception if define is called without a block" do - expect { + expect do defn.define :monkey - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should load a description from a file" do diff --git a/spec/unit/resource_reporter_spec.rb b/spec/unit/resource_reporter_spec.rb index 0df3a165bd..51075a7d44 100644 --- a/spec/unit/resource_reporter_spec.rb +++ b/spec/unit/resource_reporter_spec.rb @@ -664,9 +664,9 @@ describe Chef::ResourceReporter do it "fails the run and prints an message about the error" do expect(Chef::Log).to receive(:error).with(/500/) - expect { + expect do @resource_reporter.run_started(@run_status) - }.to raise_error(Net::HTTPServerException) + end.to raise_error(Net::HTTPServerException) end end @@ -749,9 +749,9 @@ describe Chef::ResourceReporter do it "should raise if an unkwown error happens" do allow(@rest_client).to receive(:raw_request).and_raise(Exception.new) - expect { + expect do @resource_reporter.post_reporting_data - }.to raise_error(Exception) + end.to raise_error(Exception) end end end diff --git a/spec/unit/resource_resolver_spec.rb b/spec/unit/resource_resolver_spec.rb index f3a20ab0e3..d707ade009 100644 --- a/spec/unit/resource_resolver_spec.rb +++ b/spec/unit/resource_resolver_spec.rb @@ -20,11 +20,11 @@ require "spec_helper" require "chef/resource_resolver" describe Chef::ResourceResolver do - it '#resolve' do + it "#resolve" do expect(described_class.resolve(:execute)).to eq(Chef::Resource::Execute) end - it '#list' do + it "#list" do expect(described_class.list(:package)).to_not be_empty end @@ -33,19 +33,19 @@ describe Chef::ResourceResolver do described_class.new(Chef::Node.new, "execute") end - it '#resolve' do + it "#resolve" do expect(resolver.resolve).to eq Chef::Resource::Execute end - it '#list' do + it "#list" do expect(resolver.list).to eq [ Chef::Resource::Execute ] end - it '#provided_by? returns true when resource class is in the list' do + it "#provided_by? returns true when resource class is in the list" do expect(resolver.provided_by?(Chef::Resource::Execute)).to be_truthy end - it '#provided_by? returns false when resource class is not in the list' do + it "#provided_by? returns false when resource class is not in the list" do expect(resolver.provided_by?(Chef::Resource::File)).to be_falsey end end diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index e88931fa54..e35203c78a 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -95,7 +95,7 @@ describe Chef::Resource do end describe "when an identity attribute has been declared" do - let(:file_resource) { + let(:file_resource) do file_resource_class = Class.new(Chef::Resource) do identity_attr :path attr_accessor :path @@ -104,7 +104,7 @@ describe Chef::Resource do file_resource = file_resource_class.new("identity-attr-test") file_resource.path = "/tmp/foo.txt" file_resource - } + end it "gives the value of its identity attribute" do expect(file_resource.identity).to eq("/tmp/foo.txt") @@ -140,7 +140,7 @@ describe Chef::Resource do end describe "when a set of state attributes has been declared" do - let(:file_resource) { + let(:file_resource) do file_resource_class = Class.new(Chef::Resource) do state_attrs :checksum, :owner, :group, :mode @@ -157,7 +157,7 @@ describe Chef::Resource do file_resource.group = "wheel" file_resource.mode = "0644" file_resource - } + end it "describes its state" do resource_state = file_resource.state @@ -170,14 +170,14 @@ describe Chef::Resource do end describe "load_from" do - let(:prior_resource) { + let(:prior_resource) do prior_resource = Chef::Resource.new("funk") prior_resource.supports(:funky => true) prior_resource.source_line prior_resource.allowed_actions << :funkytown prior_resource.action(:funkytown) prior_resource - } + end before(:each) do resource.allowed_actions << :funkytown run_context.resource_collection << prior_resource @@ -236,9 +236,9 @@ describe Chef::Resource do it "should raise an exception if told to act in other than :delay or :immediate(ly)" do run_context.resource_collection << Chef::Resource::ZenMaster.new("coffee") - expect { + expect do resource.notifies :reload, run_context.resource_collection.find(:zen_master => "coffee"), :someday - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should allow multiple notified resources appear in the actions hash" do @@ -503,12 +503,12 @@ describe Chef::Resource do end describe "retries" do - let(:retriable_resource) { + let(:retriable_resource) do retriable_resource = Chef::Resource::Cat.new("precious", run_context) retriable_resource.provider = Chef::Provider::SnakeOil retriable_resource.action = :purr retriable_resource - } + end before do node.automatic_attrs[:platform] = "fubuntu" @@ -563,11 +563,11 @@ describe Chef::Resource do end it "warns when setting provider_base" do - expect { + expect do class OverrideProviderBaseTest2 < Chef::Resource provider_base Chef::Provider::Package end - }.to raise_error(Chef::Exceptions::DeprecatedFeatureError) + end.to raise_error(Chef::Exceptions::DeprecatedFeatureError) end end @@ -607,11 +607,11 @@ describe Chef::Resource do end describe "when invoking its action" do - let(:resource) { + let(:resource) do resource = Chef::Resource.new("provided", run_context) resource.provider = Chef::Provider::SnakeOil resource - } + end before do node.automatic_attrs[:platform] = "fubuntu" node.automatic_attrs[:platform_version] = "10.04" @@ -797,11 +797,11 @@ describe Chef::Resource do end describe "when resource action is :nothing" do - let(:resource1) { + let(:resource1) do resource1 = Chef::Resource::Cat.new("sugar", run_context) resource1.action = :nothing resource1 - } + end before do node.automatic_attrs[:platform] = "fubuntu" node.automatic_attrs[:platform_version] = "10.04" diff --git a/spec/unit/run_context/child_run_context_spec.rb b/spec/unit/run_context/child_run_context_spec.rb index 13a035c871..47a6c84f7a 100644 --- a/spec/unit/run_context/child_run_context_spec.rb +++ b/spec/unit/run_context/child_run_context_spec.rb @@ -24,16 +24,16 @@ require "support/lib/library_load_order" describe Chef::RunContext::ChildRunContext do context "with a run context with stuff in it" do let(:chef_repo_path) { File.expand_path(File.join(CHEF_SPEC_DATA, "run_context", "cookbooks")) } - let(:cookbook_collection) { + let(:cookbook_collection) do cl = Chef::CookbookLoader.new(chef_repo_path) cl.load_cookbooks Chef::CookbookCollection.new(cl) - } - let(:node) { + end + let(:node) do node = Chef::Node.new node.run_list << "test" << "test::one" << "test::two" node - } + end let(:events) { Chef::EventDispatch::Dispatcher.new } let(:run_context) { Chef::RunContext.new(node, cookbook_collection, events) } diff --git a/spec/unit/run_context_spec.rb b/spec/unit/run_context_spec.rb index 234cd3c9e1..f1c3072b8e 100644 --- a/spec/unit/run_context_spec.rb +++ b/spec/unit/run_context_spec.rb @@ -23,16 +23,16 @@ require "support/lib/library_load_order" describe Chef::RunContext do let(:chef_repo_path) { File.expand_path(File.join(CHEF_SPEC_DATA, "run_context", "cookbooks")) } - let(:cookbook_collection) { + let(:cookbook_collection) do cl = Chef::CookbookLoader.new(chef_repo_path) cl.load_cookbooks Chef::CookbookCollection.new(cl) - } - let(:node) { + end + let(:node) do node = Chef::Node.new node.run_list << "test" << "test::one" << "test::two" node - } + end let(:events) { Chef::EventDispatch::Dispatcher.new } let(:run_context) { Chef::RunContext.new(node, cookbook_collection, events) } @@ -151,13 +151,13 @@ describe Chef::RunContext do describe "querying the contents of cookbooks" do let(:chef_repo_path) { File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks")) } - let(:node) { + let(:node) do node = Chef::Node.new node.normal[:platform] = "ubuntu" node.normal[:platform_version] = "13.04" node.name("testing") node - } + end it "queries whether a given cookbook has a specific template" do expect(run_context).to have_template_in_cookbook("openldap", "test.erb") @@ -212,11 +212,11 @@ describe Chef::RunContext do shared_context "notifying resource is a subclass of Chef::Resource" do let(:declared_type) { :alpaca } - let(:notifying_resource) { + let(:notifying_resource) do r = Class.new(Chef::Resource).new("guinea pig") r.declared_type = declared_type r - } + end it "should be keyed off the resource declared key" do run_context.send(setter, notification) diff --git a/spec/unit/run_list/run_list_expansion_spec.rb b/spec/unit/run_list/run_list_expansion_spec.rb index e1af112dbf..3a39bc79cc 100644 --- a/spec/unit/run_list/run_list_expansion_spec.rb +++ b/spec/unit/run_list/run_list_expansion_spec.rb @@ -104,8 +104,8 @@ describe Chef::RunList::RunListExpansion do end it "produces json tree upon tracing expansion" do - jsonRunList = @expansion.to_json - expect(jsonRunList).to eq(@json) + json_run_list = @expansion.to_json + expect(json_run_list).to eq(@json) end it "has the ordered list of recipes" do diff --git a/spec/unit/runner_spec.rb b/spec/unit/runner_spec.rb index f15f3951e0..c1e10a78f4 100644 --- a/spec/unit/runner_spec.rb +++ b/spec/unit/runner_spec.rb @@ -392,12 +392,12 @@ Multiple failures occurred: it "should resolve resource references in notifications when resources are defined lazily" do first_resource.action = :nothing - lazy_resources = lambda { + lazy_resources = lambda do last_resource = Chef::Resource::Cat.new("peanut", run_context) run_context.resource_collection << last_resource last_resource.notifies(:purr, first_resource.to_s, :delayed) last_resource.action = :purr - } + end second_resource = Chef::Resource::RubyBlock.new("myblock", run_context) run_context.resource_collection << second_resource second_resource.block { lazy_resources.call } diff --git a/spec/unit/search/query_spec.rb b/spec/unit/search/query_spec.rb index 7f815f1757..51667784fb 100644 --- a/spec/unit/search/query_spec.rb +++ b/spec/unit/search/query_spec.rb @@ -27,13 +27,13 @@ describe Chef::Search::Query do let(:query_string) { "search/node?q=platform:rhel&sort=X_CHEF_id_CHEF_X%20asc&start=0" } let(:server_url) { "https://api.opscode.com/organizations/opscode/nodes" } let(:args) { { filter_key => filter_hash } } - let(:filter_hash) { + let(:filter_hash) do { "env" => [ "chef_environment" ], "ruby_plat" => %w{languages ruby platform}, } - } - let(:response) { + end + let(:response) do { "rows" => [ { "url" => "#{server_url}/my-name-is-node", @@ -64,15 +64,15 @@ describe Chef::Search::Query do "start" => 0, "total" => 4, } - } - let(:response_rows) { + end + let(:response_rows) do [ { "env" => "elysium", "ruby_plat" => "nudibranch" }, { "env" => "hades", "ruby_plat" => "i386-mingw32" }, { "env" => "elysium", "ruby_plat" => "centos" }, { "env" => "moon", "ruby_plat" => "solaris2" }, ] - } + end end before(:each) do @@ -86,7 +86,8 @@ describe Chef::Search::Query do let(:query_string_with_rows) { "search/node?q=platform:rhel&sort=X_CHEF_id_CHEF_X%20asc&start=0&rows=4" } let(:query_string_continue_with_rows) { "search/node?q=platform:rhel&sort=X_CHEF_id_CHEF_X%20asc&start=4&rows=4" } - let(:response) { { + let(:response) do + { "rows" => [ { "name" => "my-name-is-node", "chef_environment" => "elysium", @@ -147,28 +148,28 @@ describe Chef::Search::Query do ], "start" => 0, "total" => 4, - } } + } end - let(:big_response) { + let(:big_response) do r = response.dup r["total"] = 8 r - } + end - let(:big_response_empty) { + let(:big_response_empty) do { "start" => 0, "total" => 8, "rows" => [], } - } + end - let(:big_response_end) { + let(:big_response_end) do r = response.dup r["start"] = 4 r["total"] = 8 r - } + end it "accepts a type as the first argument" do expect { query.search("node") }.not_to raise_error diff --git a/spec/unit/user_v1_spec.rb b/spec/unit/user_v1_spec.rb index 51dc3c9118..16f0d0158b 100644 --- a/spec/unit/user_v1_spec.rb +++ b/spec/unit/user_v1_spec.rb @@ -332,7 +332,7 @@ describe Chef::UserV1 do @user.password "some_password" end - let(:payload) { + let(:payload) do { :username => "some_username", :display_name => "some_display_name", @@ -342,7 +342,7 @@ describe Chef::UserV1 do :email => "some_email", :password => "some_password", } - } + end context "when server API V1 is valid on the Chef Server receiving the request" do context "when the user submits valid data" do @@ -354,7 +354,7 @@ describe Chef::UserV1 do end context "when server API V1 is not valid on the Chef Server receiving the request" do - let(:payload) { + let(:payload) do { :username => "some_username", :display_name => "some_display_name", @@ -365,7 +365,7 @@ describe Chef::UserV1 do :password => "some_password", :public_key => "some_public_key", } - } + end before do @user.public_key "some_public_key" @@ -442,7 +442,7 @@ describe Chef::UserV1 do end # update describe "create" do - let(:payload) { + let(:payload) do { :username => "some_username", :display_name => "some_display_name", @@ -451,7 +451,7 @@ describe Chef::UserV1 do :email => "some_email", :password => "some_password", } - } + end before do @user.username "some_username" @user.display_name "some_display_name" @@ -506,11 +506,11 @@ describe Chef::UserV1 do # DEPRECATION # This can be removed after API V0 support is gone describe "reregister" do - let(:payload) { + let(:payload) do { "username" => "some_username", } - } + end before do @user.username "some_username" diff --git a/spec/unit/util/dsc/configuration_generator_spec.rb b/spec/unit/util/dsc/configuration_generator_spec.rb index 12f62deb5a..cfa7a4e264 100644 --- a/spec/unit/util/dsc/configuration_generator_spec.rb +++ b/spec/unit/util/dsc/configuration_generator_spec.rb @@ -25,7 +25,7 @@ describe Chef::Util::DSC::ConfigurationGenerator do Chef::Util::DSC::ConfigurationGenerator.new(node, "tmp") end - describe '#validate_configuration_name!' do + describe "#validate_configuration_name!" do it "should not raise an error if a name contains all upper case letters" do conf_man.send(:validate_configuration_name!, "HELLO") end @@ -40,9 +40,9 @@ describe Chef::Util::DSC::ConfigurationGenerator do %w{! @ # $ % ^ & * & * ( ) - = + \{ \} . ? < > \\ /}.each do |sym| it "raises an Argument error if it configuration name contains #{sym}" do - expect { + expect do conf_man.send(:validate_configuration_name!, "Hello#{sym}") - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end end end @@ -57,15 +57,15 @@ describe Chef::Util::DSC::ConfigurationGenerator do end it "should raise an ArgumentError if you try to override outputpath" do - expect { + expect do conf_man.send(:get_merged_configuration_flags!, { "outputpath" => "a" }, "hello") - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should be case insensitive for switches that are not allowed" do - expect { + expect do conf_man.send(:get_merged_configuration_flags!, { "OutputPath" => "a" }, "hello") - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should be case insensitive to switches that are allowed" do @@ -83,15 +83,15 @@ describe Chef::Util::DSC::ConfigurationGenerator do end it "should raise an ArgumentError if you try to override outputpath" do - expect { + expect do conf_man.send(:get_merged_configuration_flags!, { :outputpath => "a" }, "hello") - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should be case insensitive for switches that are not allowed" do - expect { + expect do conf_man.send(:get_merged_configuration_flags!, { :OutputPath => "a" }, "hello") - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "should be case insensitive to switches that are allowed" do @@ -121,7 +121,7 @@ describe Chef::Util::DSC::ConfigurationGenerator do # end - describe '#write_document_generation_script' do + describe "#write_document_generation_script" do let(:file_like_object) { double("file like object") } it "should write the input to a file" do diff --git a/spec/unit/util/dsc/local_configuration_manager_spec.rb b/spec/unit/util/dsc/local_configuration_manager_spec.rb index 15cf38394e..45fe8df40d 100644 --- a/spec/unit/util/dsc/local_configuration_manager_spec.rb +++ b/spec/unit/util/dsc/local_configuration_manager_spec.rb @@ -23,15 +23,17 @@ describe Chef::Util::DSC::LocalConfigurationManager do let(:lcm) { Chef::Util::DSC::LocalConfigurationManager.new(nil, "tmp") } - let(:normal_lcm_output) { <<-EOH + let(:normal_lcm_output) do + <<-EOH logtype: [machinename]: LCM: [ Start Set ] logtype: [machinename]: LCM: [ Start Resource ] [name] logtype: [machinename]: LCM: [ End Resource ] [name] logtype: [machinename]: LCM: [ End Set ] EOH - } + end - let(:no_whatif_lcm_output) { <<-EOH + let(:no_whatif_lcm_output) do + <<-EOH Start-DscConfiguration : A parameter cannot be found\r\n that matches parameter name 'whatif'. At line:1 char:123 + run-somecommand -whatif @@ -39,16 +41,17 @@ At line:1 char:123 + CategoryInfo : InvalidArgument: (:) [Start-DscConfiguration], ParameterBindingException + FullyQualifiedErrorId : NamedParameterNotFound,SomeCompany.SomeAssembly.Commands.RunSomeCommand EOH - } + end - let(:dsc_resource_import_failure_output) { <<-EOH + let(:dsc_resource_import_failure_output) do + <<-EOH PowerShell provider MSFT_xWebsite failed to execute Test-TargetResource functionality with error message: Please ensure that WebAdministration module is installed. + CategoryInfo : InvalidOperation: (:) [], CimException + FullyQualifiedErrorId : ProviderOperationExecutionFailure + PSComputerName : . PowerShell provider MSFT_xWebsite failed to execute Test-TargetResource functionality with error message: Please ensure that WebAdministration module is installed. + CategoryInfo : InvalidOperation: (:) [], CimException + FullyQualifiedErrorId : ProviderOperationExecutionFailure + PSComputerName : . The SendConfigurationApply function did not succeed. + CategoryInfo : NotSpecified: (root/Microsoft/...gurationManager:String) [], CimException + FullyQualifiedErrorId : MI RESULT 1 + PSComputerName : . EOH - } + end - let(:lcm_status) { + let(:lcm_status) do double("LCM cmdlet status", :stderr => lcm_standard_error, :return_value => lcm_standard_output, :succeeded? => lcm_cmdlet_success) - } + end describe "test_configuration method invocation" do context "when interacting with the LCM using a PowerShell cmdlet" do @@ -77,7 +80,7 @@ EOH let(:lcm_standard_error) { no_whatif_lcm_output } let(:lcm_cmdlet_success) { false } - it 'returns true when passed to #whatif_not_supported?' do + it "returns true when passed to #whatif_not_supported?" do expect(lcm.send(:whatif_not_supported?, no_whatif_lcm_output)).to be_truthy end diff --git a/spec/unit/util/dsc/resource_store.rb b/spec/unit/util/dsc/resource_store.rb index 84b39190b2..a864a2c1da 100644 --- a/spec/unit/util/dsc/resource_store.rb +++ b/spec/unit/util/dsc/resource_store.rb @@ -21,28 +21,30 @@ require "chef/util/dsc/resource_store" describe Chef::Util::DSC::ResourceStore do let(:resource_store) { Chef::Util::DSC::ResourceStore.new } - let(:resource_a) { { + let(:resource_a) do + { "ResourceType" => "AFoo", "Name" => "Foo", "Module" => { "Name" => "ModuleA" }, } - } + end - let(:resource_b) { { + let(:resource_b) do + { "ResourceType" => "BFoo", "Name" => "Foo", "Module" => { "Name" => "ModuleB" }, } - } + end context "when resources are not cached" do - context 'when calling #resources' do + context "when calling #resources" do it "returns an empty array" do expect(resource_store.resources).to eql([]) end end - context 'when calling #find' do + context "when calling #find" do it "returns an empty list if it cannot find any matching resources" do expect(resource_store).to receive(:query_resource).and_return([]) expect(resource_store.find("foo")).to eql([]) diff --git a/spec/unit/util/editor_spec.rb b/spec/unit/util/editor_spec.rb index 7a0ec91533..e53bc9662a 100644 --- a/spec/unit/util/editor_spec.rb +++ b/spec/unit/util/editor_spec.rb @@ -2,7 +2,7 @@ require "spec_helper" require "chef/util/editor" describe Chef::Util::Editor do - describe '#initialize' do + describe "#initialize" do it "takes an Enumerable of lines" do editor = described_class.new(File.open(__FILE__)) expect(editor.lines).to be == IO.readlines(__FILE__) @@ -18,7 +18,7 @@ describe Chef::Util::Editor do subject(:editor) { described_class.new(input_lines) } let(:input_lines) { %w{one two two three} } - describe '#append_line_after' do + describe "#append_line_after" do context "when there is no match" do subject(:execute) { editor.append_line_after("missing", "new") } @@ -44,7 +44,7 @@ describe Chef::Util::Editor do end end - describe '#append_line_if_missing' do + describe "#append_line_if_missing" do context "when there is no match" do subject(:execute) { editor.append_line_if_missing("missing", "new") } @@ -70,7 +70,7 @@ describe Chef::Util::Editor do end end - describe '#remove_lines' do + describe "#remove_lines" do context "when there is no match" do subject(:execute) { editor.remove_lines("missing") } @@ -96,7 +96,7 @@ describe Chef::Util::Editor do end end - describe '#replace' do + describe "#replace" do context "when there is no match" do subject(:execute) { editor.replace("missing", "new") } @@ -123,7 +123,7 @@ describe Chef::Util::Editor do end end - describe '#replace_lines' do + describe "#replace_lines" do context "when there is no match" do subject(:execute) { editor.replace_lines("missing", "new") } diff --git a/spec/unit/util/powershell/cmdlet_spec.rb b/spec/unit/util/powershell/cmdlet_spec.rb index 5c0e66aee2..800e4cc9c0 100644 --- a/spec/unit/util/powershell/cmdlet_spec.rb +++ b/spec/unit/util/powershell/cmdlet_spec.rb @@ -25,7 +25,7 @@ describe Chef::Util::Powershell::Cmdlet do @cmdlet = Chef::Util::Powershell::Cmdlet.new(@node, "Some-Commandlet") end - describe '#validate_switch_name!' do + describe "#validate_switch_name!" do it "should not raise an error if a name contains all upper case letters" do @cmdlet.send(:validate_switch_name!, "HELLO") end @@ -40,14 +40,14 @@ describe Chef::Util::Powershell::Cmdlet do %w{! @ # $ % ^ & * & * ( ) - = + \{ \} . ? < > \\ /}.each do |sym| it "raises an Argument error if it configuration name contains #{sym}" do - expect { + expect do @cmdlet.send(:validate_switch_name!, "Hello#{sym}") - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end end end - describe '#escape_parameter_value' do + describe "#escape_parameter_value" do # Is this list really complete? %w{` " # '}.each do |c| it "escapse #{c}" do @@ -60,23 +60,23 @@ describe Chef::Util::Powershell::Cmdlet do end end - describe '#escape_string_parameter_value' do + describe "#escape_string_parameter_value" do it "surrounds a string with ''" do expect(@cmdlet.send(:escape_string_parameter_value, "stuff")).to eql("'stuff'") end end - describe '#command_switches_string' do + describe "#command_switches_string" do it "raises an ArgumentError if the key is not a symbol" do - expect { + expect do @cmdlet.send(:command_switches_string, { "foo" => "bar" }) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "does not allow invalid switch names" do - expect { + expect do @cmdlet.send(:command_switches_string, { :foo! => "bar" }) - }.to raise_error(ArgumentError) + end.to raise_error(ArgumentError) end it "ignores switches with a false value" do diff --git a/tasks/bin/bundle-platform b/tasks/bin/bundle-platform index 4bd659d307..aa8443e74c 100755 --- a/tasks/bin/bundle-platform +++ b/tasks/bin/bundle-platform @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +require_relative "bundler_patch" platforms = ARGV.shift platforms = platforms.split(" ").map { |p| Gem::Platform.new(p) } diff --git a/tasks/bin/bundler_patch.rb b/tasks/bin/bundler_patch.rb new file mode 100644 index 0000000000..5665e44eca --- /dev/null +++ b/tasks/bin/bundler_patch.rb @@ -0,0 +1,27 @@ +# This is a temporary monkey patch to address https://github.com/bundler/bundler/issues/4896 +# the heart of the fix is line #18 with the addition of: +# && (possibility.activated - existing_node.payload.activated).empty? +# This ensures we do not mis linux platform gems in some scenarios like ffi in kitchen-test. +# There is a permanent fix to bundler (See https://github.com/bundler/bundler/pull/4836) which +# is due to ship in v1.14. Once we adopt that version, we can remove this file + +require "bundler" +require "bundler/vendor/molinillo/lib/molinillo/resolution" + +module Bundler::Molinillo + class Resolver + # A specific resolution from a given {Resolver} + class Resolution + def attempt_to_activate + debug(depth) { "Attempting to activate " + possibility.to_s } + existing_node = activated.vertex_named(name) + if existing_node.payload && (possibility.activated - existing_node.payload.activated).empty? + debug(depth) { "Found existing spec (#{existing_node.payload})" } + attempt_to_activate_existing_spec(existing_node) + else + attempt_to_activate_new_spec + end + end + end + end +end diff --git a/tasks/bin/gem-version-diff b/tasks/bin/gem-version-diff new file mode 100755 index 0000000000..617402d4e6 --- /dev/null +++ b/tasks/bin/gem-version-diff @@ -0,0 +1,37 @@ +#!/usr/bin/env ruby + +require_relative "../../version_policy" + +old_version, new_version = ARGV[0..1] + +require "set" +ENV["BUNDLE_WITHOUT"] = INSTALL_WITHOUT_GROUPS.join(":") +relevant_gems = Set.new +`bundle list`.each_line do |line| + next unless line =~ /^ \* (\S+)/ + relevant_gems.add($1) +end + +old_gems = {} +old_file = `git show #{old_version}:Gemfile.lock` +old_file.each_line do |line| + next unless line =~ /^ (\S+) \(([^\)]+)\)$/ + next unless relevant_gems.include?($1) + old_gems[$1] = $2 +end + +new_gems = {} +new_file = `git show #{new_version}:Gemfile.lock` +new_file.each_line do |line| + next unless line =~ /^ (\S+) \(([^\)]+)\)$/ + next unless relevant_gems.include?($1) + new_gems[$1] = $2 +end + +modified_gems = (old_gems.keys & new_gems.keys).sort.select { |name| new_gems[name] != old_gems[name] }.map { |name| "#{name} - #{new_gems[name]} (was #{old_gems[name]})" } +removed_gems = (old_gems.keys - new_gems.keys).sort.map { |name| "#{name} - #{old_gems[name]}" } +added_gems = (new_gems.keys - old_gems.keys).sort.map { |name| "#{name} - #{new_gems[name]}" } + +puts "MODIFIED:\n#{modified_gems.join("\n")}" if modified_gems.any? +puts "\nADDED:\n#{added_gems.join("\n")}" if added_gems.any? +puts "\nREMOVED:\n#{removed_gems.join("\n")}" if removed_gems.any? diff --git a/tasks/bundle.rb b/tasks/bundle.rb index 059b926f14..0176fe209e 100644 --- a/tasks/bundle.rb +++ b/tasks/bundle.rb @@ -30,9 +30,9 @@ namespace :bundle do puts "-------------------------------------------------------------------" puts "Updating Gemfile.lock ..." puts "-------------------------------------------------------------------" - bundle "install #{args}", delete_gemfile_lock: true + bundle "update #{args}" platforms.each do |platform| - bundle "lock", platform: platform + bundle "update #{args}", platform: platform end end end diff --git a/tasks/cbgb.rb b/tasks/cbgb.rb index 9aa6700137..70ca1036e8 100644 --- a/tasks/cbgb.rb +++ b/tasks/cbgb.rb @@ -44,9 +44,9 @@ begin out << cbgb(cbgb["corporations"], cbgb["Org"]["Corporate-Contributors"]["governers"]) + "\n\n" out << "### " + cbgb["Org"]["Lieutenants"]["title"] + "\n\n" out << cbgb(cbgb["people"], cbgb["Org"]["Lieutenants"]["governers"]) + "\n\n" - File.open(CBGB_TARGET, "w") { |fn| + File.open(CBGB_TARGET, "w") do |fn| fn.write out - } + end end end diff --git a/tasks/maintainers.rb b/tasks/maintainers.rb index 91742854bb..e13d4724b0 100644 --- a/tasks/maintainers.rb +++ b/tasks/maintainers.rb @@ -46,9 +46,9 @@ begin out << format_person(source["Org"]["Lead"]["person"]) + "\n\n" out << format_components(source["Org"]["Components"]) - File.open(TARGET, "w") { |fn| + File.open(TARGET, "w") do |fn| fn.write out - } + end end desc "Synchronize GitHub teams" diff --git a/version_policy.rb b/version_policy.rb index b8bead7bef..e7b6136719 100644 --- a/version_policy.rb +++ b/version_policy.rb @@ -32,7 +32,7 @@ OMNIBUS_OVERRIDES = { "makedepend" => "1.0.5", "ncurses" => "5.9", "pkg-config-lite" => "0.28-1", - "ruby" => "2.1.8", + "ruby" => "2.1.9", # Leave dev-kit pinned to 4.5 on 32-bit, because 4.7 is 20MB larger and we don't want # to unnecessarily make the client any fatter. (Since it's different between # 32 and 64, we have to do it in the project file still.) @@ -74,14 +74,13 @@ OMNIBUS_RUBYGEMS_AT_LATEST_VERSION = { # stove - halite pins to ~> 3.2 in 1.2.1 # rubocop - chef-style pins to 0.39.0 in 0.3.1 # -ACCEPTABLE_OUTDATED_GEMS = %w{ - gherkin - jwt - mini_portile2 - slop - stove - rubocop -} +ACCEPTABLE_OUTDATED_GEMS = [ + "json", # aws-sdk-v1 disallows JSON 2.x (no fix pending yet) + "rack", # Rack 2.0+ requires Ruby 2.2 + "rubocop", # chef-style pins to 0.39.0 in 0.3.1 + "slop", # expected to disappear with pry 0.11 + "typhoeus", # until https://github.com/travis-ci/travis.rb/pull/426 is fixed +] # # Some gems are part of our bundle (must be installed) but not important |