summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Mundrawala <jdmundrawala@gmail.com>2015-02-19 15:17:05 -0800
committerJay Mundrawala <jdmundrawala@gmail.com>2015-02-19 15:17:05 -0800
commit864f9ac95063c7833235c8ed50dcb89653eda03f (patch)
tree93da186fd522bdfc5de6414d011f4c0dd49aeb40
parent194f49bdb7737e0591271ba95021997e90379c5d (diff)
parenta7f5c92960aedf8d5bfc71abbce430ab075e016a (diff)
downloadchef-jdm/merge-into-12-stable.tar.gz
Merge remote-tracking branch 'origin/master' into HEADjdm/merge-into-12-stable
* origin/master: (642 commits) Remove Chef 12 release notes Update Changelog for Chef 12.1.0 Chef 12.1.0.rc.0 Group spec needs to respond to shell_out fix dpkg regression fix Lint/BlockAlignment whitespaces fixes fix Lint/AmbiguousRegexpLiteral fix Lint/LiteralInCondition fix Lint/Loop style Make tests pass on Windows remove unreachable code Fix unit specs for PR #2934 dont raise exceptions in load_current_resource when checking current status update changelog fix typo in msi provider Added spec for #2914 fix virtual package logic in check_package_state use scalar pkg not array package convert is_virtual_package to hash ... Conflicts: .travis.yml CHANGELOG.md DOC_CHANGES.md RELEASE_NOTES.md appveyor.yml lib/chef/application.rb lib/chef/dsl/recipe.rb lib/chef/knife/bootstrap.rb lib/chef/knife/core/bootstrap_context.rb lib/chef/node/attribute.rb lib/chef/node/attribute_collections.rb lib/chef/node/immutable_collections.rb lib/chef/resource.rb lib/chef/run_context.rb lib/chef/version.rb spec/functional/dsl/reboot_pending_spec.rb spec/functional/event_loggers/windows_eventlog_spec.rb spec/functional/resource/link_spec.rb spec/support/platform_helpers.rb spec/unit/knife_spec.rb spec/unit/mixin/deep_merge_spec.rb spec/unit/mixin/shell_out_spec.rb spec/unit/node/attribute_spec.rb spec/unit/node_spec.rb spec/unit/provider/package/apt_spec.rb spec/unit/provider/service/systemd_service_spec.rb spec/unit/provider_resolver_spec.rb spec/unit/recipe_spec.rb spec/unit/resource/resource_notification_spec.rb spec/unit/run_context_spec.rb
-rw-r--r--.gitignore3
-rw-r--r--.kitchen.yml82
-rw-r--r--.mailmap117
-rw-r--r--.rspec2
-rw-r--r--.travis.yml32
-rw-r--r--CHANGELOG.md123
-rw-r--r--CLA_ARCHIVE.md2510
-rw-r--r--CONTRIBUTING.md5
-rw-r--r--DOC_CHANGES.md73
-rw-r--r--MAINTAINERS.md129
-rw-r--r--README.md60
-rw-r--r--RELEASE_NOTES.md495
-rw-r--r--appveyor.yml3
-rwxr-xr-xbin/shef35
-rw-r--r--chef-x86-mingw32.gemspec2
-rw-r--r--chef.gemspec18
-rw-r--r--distro/common/html/_sources/ctl_chef_client.txt2
-rw-r--r--distro/common/html/_sources/ctl_chef_server.txt88
-rw-r--r--distro/common/html/_sources/ctl_chef_solo.txt2
-rw-r--r--distro/common/html/_sources/knife_bootstrap.txt2
-rw-r--r--distro/common/html/_sources/knife_cookbook_site.txt2
-rw-r--r--distro/common/html/_sources/knife_data_bag.txt8
-rw-r--r--distro/common/html/_sources/knife_status.txt2
-rw-r--r--distro/common/html/_static/searchtools.js2
-rw-r--r--distro/common/html/ctl_chef_client.html62
-rw-r--r--distro/common/html/ctl_chef_server.html125
-rw-r--r--distro/common/html/ctl_chef_shell.html46
-rw-r--r--distro/common/html/ctl_chef_solo.html56
-rw-r--r--distro/common/html/index.html4
-rw-r--r--distro/common/html/knife.html2
-rw-r--r--distro/common/html/knife_bootstrap.html40
-rw-r--r--distro/common/html/knife_cookbook_site.html2
-rw-r--r--distro/common/html/knife_data_bag.html8
-rw-r--r--distro/common/html/knife_node.html4
-rw-r--r--distro/common/html/knife_raw.html2
-rw-r--r--distro/common/html/knife_role.html2
-rw-r--r--distro/common/html/knife_search.html6
-rw-r--r--distro/common/html/knife_status.html4
-rw-r--r--distro/common/html/searchindex.js2
-rw-r--r--distro/common/man/man1/chef-shell.173
-rw-r--r--distro/common/man/man1/knife-bootstrap.1134
-rw-r--r--distro/common/man/man1/knife-client.12
-rw-r--r--distro/common/man/man1/knife-configure.12
-rw-r--r--distro/common/man/man1/knife-cookbook-site.15
-rw-r--r--distro/common/man/man1/knife-cookbook.12
-rw-r--r--distro/common/man/man1/knife-data-bag.110
-rw-r--r--distro/common/man/man1/knife-delete.12
-rw-r--r--distro/common/man/man1/knife-deps.12
-rw-r--r--distro/common/man/man1/knife-diff.12
-rw-r--r--distro/common/man/man1/knife-download.12
-rw-r--r--distro/common/man/man1/knife-edit.12
-rw-r--r--distro/common/man/man1/knife-environment.12
-rw-r--r--distro/common/man/man1/knife-exec.12
-rw-r--r--distro/common/man/man1/knife-index-rebuild.12
-rw-r--r--distro/common/man/man1/knife-list.12
-rw-r--r--distro/common/man/man1/knife-node.16
-rw-r--r--distro/common/man/man1/knife-raw.14
-rw-r--r--distro/common/man/man1/knife-recipe-list.12
-rw-r--r--distro/common/man/man1/knife-role.14
-rw-r--r--distro/common/man/man1/knife-search.18
-rw-r--r--distro/common/man/man1/knife-serve.12
-rw-r--r--distro/common/man/man1/knife-show.12
-rw-r--r--distro/common/man/man1/knife-ssh.12
-rw-r--r--distro/common/man/man1/knife-ssl-check.12
-rw-r--r--distro/common/man/man1/knife-ssl-fetch.12
-rw-r--r--distro/common/man/man1/knife-status.12
-rw-r--r--distro/common/man/man1/knife-tag.12
-rw-r--r--distro/common/man/man1/knife-upload.12
-rw-r--r--distro/common/man/man1/knife-user.12
-rw-r--r--distro/common/man/man1/knife-xargs.12
-rw-r--r--distro/common/man/man1/knife.12
-rw-r--r--distro/common/man/man8/chef-apply.886
-rw-r--r--distro/common/man/man8/chef-client.881
-rw-r--r--distro/common/man/man8/chef-solo.885
-rw-r--r--distro/common/markdown/man1/knife-bootstrap.mkd2
-rw-r--r--distro/common/markdown/man1/knife-cookbook-site.mkd2
-rw-r--r--distro/common/markdown/man1/knife-data-bag.mkd2
-rw-r--r--distro/common/markdown/man1/knife-environment.mkd2
-rw-r--r--distro/common/markdown/man1/knife.mkd2
-rw-r--r--kitchen-tests/.chef/client.rb11
-rw-r--r--kitchen-tests/.kitchen.travis.yml14
-rw-r--r--kitchen-tests/.kitchen.yml24
-rw-r--r--kitchen-tests/cookbooks/audit_test/.gitignore16
-rw-r--r--kitchen-tests/cookbooks/audit_test/.kitchen.yml16
-rw-r--r--kitchen-tests/cookbooks/audit_test/Berksfile3
-rw-r--r--kitchen-tests/cookbooks/audit_test/README.md12
-rw-r--r--kitchen-tests/cookbooks/audit_test/chefignore95
-rw-r--r--kitchen-tests/cookbooks/audit_test/metadata.rb8
-rw-r--r--kitchen-tests/cookbooks/audit_test/recipes/default.rb26
-rw-r--r--kitchen-tests/cookbooks/audit_test/recipes/error_duplicate_control_groups.rb17
-rw-r--r--kitchen-tests/cookbooks/audit_test/recipes/error_no_block.rb7
-rw-r--r--kitchen-tests/cookbooks/audit_test/recipes/error_orphan_control.rb13
-rw-r--r--kitchen-tests/cookbooks/audit_test/recipes/failed_specs.rb14
-rw-r--r--kitchen-tests/cookbooks/audit_test/recipes/serverspec_collision.rb31
-rw-r--r--kitchen-tests/cookbooks/audit_test/recipes/serverspec_support.rb37
-rw-r--r--kitchen-tests/cookbooks/audit_test/recipes/with_include_recipe.rb16
-rw-r--r--kitchen-tests/cookbooks/webapp/README.md1
-rw-r--r--kitchen-tests/cookbooks/webapp/attributes/default.rb13
-rw-r--r--kitchen-tests/cookbooks/webapp/recipes/default.rb7
-rw-r--r--kitchen-tests/test/fixtures/platforms/centos/5.json14
-rw-r--r--kitchen-tests/test/fixtures/platforms/centos/6.json14
-rw-r--r--kitchen-tests/test/fixtures/platforms/ubuntu/10.04.json14
-rw-r--r--kitchen-tests/test/fixtures/platforms/ubuntu/12.04.json52
-rw-r--r--kitchen-tests/test/fixtures/platforms/ubuntu/14.04.json14
-rw-r--r--kitchen-tests/test/fixtures/platforms/ubuntu/14.10.json14
-rw-r--r--kitchen-tests/test/fixtures/serverspec_helper.rb2
-rw-r--r--kitchen-tests/test/integration/webapp/serverspec/localhost/default_spec.rb12
-rw-r--r--lib/chef.rb7
-rw-r--r--lib/chef/api_client.rb12
-rw-r--r--lib/chef/api_client/registration.rb16
-rw-r--r--lib/chef/application.rb40
-rw-r--r--lib/chef/application/agent.rb18
-rw-r--r--lib/chef/application/apply.rb18
-rw-r--r--lib/chef/application/client.rb80
-rw-r--r--lib/chef/application/knife.rb3
-rw-r--r--lib/chef/application/solo.rb30
-rw-r--r--lib/chef/application/windows_service.rb1
-rw-r--r--lib/chef/application/windows_service_manager.rb10
-rw-r--r--lib/chef/applications.rb1
-rw-r--r--lib/chef/audit/audit_event_proxy.rb93
-rw-r--r--lib/chef/audit/audit_reporter.rb169
-rw-r--r--lib/chef/audit/control_group_data.rb140
-rw-r--r--lib/chef/audit/rspec_formatter.rb37
-rw-r--r--lib/chef/audit/runner.rb178
-rw-r--r--lib/chef/chef_fs/chef_fs_data_store.rb13
-rw-r--r--lib/chef/chef_fs/config.rb29
-rw-r--r--lib/chef/chef_fs/data_handler/policy_data_handler.rb15
-rw-r--r--lib/chef/chef_fs/data_handler/user_data_handler.rb1
-rw-r--r--lib/chef/chef_fs/file_system.rb2
-rw-r--r--lib/chef/chef_fs/file_system/base_fs_dir.rb5
-rw-r--r--lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb5
-rw-r--r--lib/chef/chef_fs/file_system/chef_repository_file_system_policies_dir.rb (renamed from lib/chef/shef/ext.rb)25
-rw-r--r--lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb4
-rw-r--r--lib/chef/client.rb133
-rw-r--r--lib/chef/config.rb38
-rw-r--r--lib/chef/cookbook/metadata.rb6
-rw-r--r--lib/chef/cookbook_manifest.rb275
-rw-r--r--lib/chef/cookbook_site_streaming_uploader.rb47
-rw-r--r--lib/chef/cookbook_uploader.rb13
-rw-r--r--lib/chef/cookbook_version.rb265
-rw-r--r--lib/chef/data_bag.rb7
-rw-r--r--lib/chef/data_bag_item.rb9
-rw-r--r--lib/chef/deprecation/warnings.rb9
-rw-r--r--lib/chef/dsl/audit.rb51
-rw-r--r--lib/chef/dsl/include_recipe.rb5
-rw-r--r--lib/chef/dsl/reboot_pending.rb2
-rw-r--r--lib/chef/dsl/recipe.rb80
-rw-r--r--lib/chef/encrypted_data_bag_item/assertions.rb3
-rw-r--r--lib/chef/environment.rb7
-rw-r--r--lib/chef/event_dispatch/base.rb37
-rw-r--r--lib/chef/event_dispatch/dispatcher.rb8
-rw-r--r--lib/chef/exceptions.rb55
-rw-r--r--lib/chef/file_access_control/unix.rb12
-rw-r--r--lib/chef/file_access_control/windows.rb14
-rw-r--r--lib/chef/formatters/doc.rb48
-rw-r--r--lib/chef/guard_interpreter.rb (renamed from spec/unit/monkey_patches/string_spec.rb)27
-rw-r--r--lib/chef/guard_interpreter/resource_guard_interpreter.rb5
-rw-r--r--lib/chef/http.rb3
-rw-r--r--lib/chef/knife.rb8
-rw-r--r--lib/chef/knife/bootstrap.rb99
-rw-r--r--lib/chef/knife/bootstrap/chef_vault_handler.rb165
-rw-r--r--lib/chef/knife/bootstrap/client_builder.rb190
-rw-r--r--lib/chef/knife/bootstrap/templates/README.md (renamed from lib/chef/knife/bootstrap/README.md)0
-rw-r--r--lib/chef/knife/bootstrap/templates/archlinux-gems.erb (renamed from lib/chef/knife/bootstrap/archlinux-gems.erb)9
-rw-r--r--lib/chef/knife/bootstrap/templates/chef-aix.erb (renamed from lib/chef/knife/bootstrap/chef-aix.erb)9
-rw-r--r--lib/chef/knife/bootstrap/templates/chef-full.erb (renamed from lib/chef/knife/bootstrap/chef-full.erb)11
-rw-r--r--lib/chef/knife/client_create.rb15
-rw-r--r--lib/chef/knife/cookbook_site_download.rb2
-rw-r--r--lib/chef/knife/cookbook_site_list.rb2
-rw-r--r--lib/chef/knife/cookbook_site_search.rb2
-rw-r--r--lib/chef/knife/cookbook_site_share.rb67
-rw-r--r--lib/chef/knife/cookbook_site_show.rb6
-rw-r--r--lib/chef/knife/cookbook_site_unshare.rb2
-rw-r--r--lib/chef/knife/cookbook_test.rb1
-rw-r--r--lib/chef/knife/cookbook_upload.rb21
-rw-r--r--lib/chef/knife/core/bootstrap_context.rb17
-rw-r--r--lib/chef/knife/core/generic_presenter.rb7
-rw-r--r--lib/chef/knife/core/object_loader.rb2
-rw-r--r--lib/chef/knife/core/subcommand_loader.rb24
-rw-r--r--lib/chef/knife/core/ui.rb10
-rw-r--r--lib/chef/knife/node_run_list_remove.rb14
-rw-r--r--lib/chef/knife/raw.rb17
-rw-r--r--lib/chef/knife/role_env_run_list_add.rb86
-rw-r--r--lib/chef/knife/role_env_run_list_clear.rb55
-rw-r--r--lib/chef/knife/role_env_run_list_remove.rb57
-rw-r--r--lib/chef/knife/role_env_run_list_replace.rb59
-rw-r--r--lib/chef/knife/role_env_run_list_set.rb70
-rw-r--r--lib/chef/knife/role_run_list_add.rb86
-rw-r--r--lib/chef/knife/role_run_list_clear.rb55
-rw-r--r--lib/chef/knife/role_run_list_remove.rb57
-rw-r--r--lib/chef/knife/role_run_list_replace.rb59
-rw-r--r--lib/chef/knife/role_run_list_set.rb70
-rw-r--r--lib/chef/knife/search.rb8
-rw-r--r--lib/chef/knife/serve.rb3
-rw-r--r--lib/chef/knife/ssh.rb2
-rw-r--r--lib/chef/knife/ssl_check.rb4
-rw-r--r--lib/chef/knife/ssl_fetch.rb15
-rw-r--r--lib/chef/log.rb11
-rw-r--r--lib/chef/mixin/command.rb2
-rw-r--r--lib/chef/mixin/command/windows.rb6
-rw-r--r--lib/chef/mixin/get_source_from_package.rb1
-rw-r--r--lib/chef/mixin/params_validate.rb4
-rw-r--r--lib/chef/mixin/securable.rb8
-rw-r--r--lib/chef/mixin/shell_out.rb8
-rw-r--r--lib/chef/mixin/template.rb16
-rw-r--r--lib/chef/mixin/why_run.rb2
-rw-r--r--lib/chef/monkey_patches/fileutils.rb65
-rw-r--r--lib/chef/monkey_patches/net_http.rb4
-rw-r--r--lib/chef/monkey_patches/numeric.rb15
-rw-r--r--lib/chef/monkey_patches/object.rb9
-rw-r--r--lib/chef/monkey_patches/pathname.rb32
-rw-r--r--lib/chef/monkey_patches/regexp.rb34
-rw-r--r--lib/chef/monkey_patches/securerandom.rb44
-rw-r--r--lib/chef/monkey_patches/string.rb49
-rw-r--r--lib/chef/monkey_patches/tempfile.rb64
-rw-r--r--lib/chef/monkey_patches/uri.rb70
-rw-r--r--lib/chef/monologger.rb2
-rw-r--r--lib/chef/node.rb7
-rw-r--r--lib/chef/node/attribute.rb20
-rw-r--r--lib/chef/node/attribute_collections.rb20
-rw-r--r--lib/chef/node/immutable_collections.rb14
-rw-r--r--lib/chef/org.rb148
-rw-r--r--lib/chef/platform/provider_mapping.rb5
-rw-r--r--lib/chef/platform/provider_priority_map.rb2
-rw-r--r--lib/chef/platform/query_helpers.rb3
-rw-r--r--lib/chef/policy_builder/policyfile.rb59
-rw-r--r--lib/chef/provider/deploy.rb3
-rw-r--r--lib/chef/provider/directory.rb6
-rw-r--r--lib/chef/provider/dsc_script.rb20
-rw-r--r--lib/chef/provider/env.rb16
-rw-r--r--lib/chef/provider/execute.rb91
-rw-r--r--lib/chef/provider/file.rb8
-rw-r--r--lib/chef/provider/group.rb2
-rw-r--r--lib/chef/provider/group/dscl.rb7
-rw-r--r--lib/chef/provider/ifconfig.rb50
-rw-r--r--lib/chef/provider/ifconfig/aix.rb52
-rw-r--r--lib/chef/provider/lwrp_base.rb2
-rw-r--r--lib/chef/provider/mount.rb4
-rw-r--r--lib/chef/provider/mount/mount.rb7
-rw-r--r--lib/chef/provider/mount/solaris.rb2
-rw-r--r--lib/chef/provider/package.rb345
-rw-r--r--lib/chef/provider/package/aix.rb55
-rw-r--r--lib/chef/provider/package/apt.rb82
-rw-r--r--lib/chef/provider/package/dpkg.rb31
-rw-r--r--lib/chef/provider/package/macports.rb14
-rw-r--r--lib/chef/provider/package/openbsd.rb107
-rw-r--r--lib/chef/provider/package/pacman.rb28
-rw-r--r--lib/chef/provider/package/portage.rb7
-rw-r--r--lib/chef/provider/package/rpm.rb45
-rw-r--r--lib/chef/provider/package/rubygems.rb18
-rw-r--r--lib/chef/provider/package/solaris.rb38
-rw-r--r--lib/chef/provider/package/windows/msi.rb2
-rw-r--r--lib/chef/provider/package/yum-dump.py4
-rw-r--r--lib/chef/provider/package/yum.rb168
-rw-r--r--lib/chef/provider/package/zypper.rb35
-rw-r--r--lib/chef/provider/powershell_script.rb8
-rw-r--r--lib/chef/provider/registry_key.rb4
-rw-r--r--lib/chef/provider/remote_directory.rb2
-rw-r--r--lib/chef/provider/script.rb41
-rw-r--r--lib/chef/provider/service.rb2
-rw-r--r--lib/chef/provider/service/freebsd.rb2
-rw-r--r--lib/chef/provider/service/openbsd.rb216
-rw-r--r--lib/chef/provider/service/upstart.rb2
-rw-r--r--lib/chef/provider/service/windows.rb100
-rw-r--r--lib/chef/provider/user.rb2
-rw-r--r--lib/chef/provider/user/dscl.rb23
-rw-r--r--lib/chef/providers.rb2
-rw-r--r--lib/chef/recipe.rb16
-rw-r--r--lib/chef/request_id.rb2
-rw-r--r--lib/chef/resource.rb1211
-rw-r--r--lib/chef/resource/chef_gem.rb23
-rw-r--r--lib/chef/resource/conditional.rb17
-rw-r--r--lib/chef/resource/dsc_script.rb14
-rw-r--r--lib/chef/resource/execute.rb21
-rw-r--r--lib/chef/resource/file.rb14
-rw-r--r--lib/chef/resource/file/verification.rb122
-rw-r--r--lib/chef/resource/ips_package.rb2
-rw-r--r--lib/chef/resource/lwrp_base.rb13
-rw-r--r--lib/chef/resource/macports_package.rb3
-rw-r--r--lib/chef/resource/openbsd_package.rb51
-rw-r--r--lib/chef/resource/package.rb4
-rw-r--r--lib/chef/resource/paludis_package.rb2
-rw-r--r--lib/chef/resource/reboot.rb2
-rw-r--r--lib/chef/resource/remote_file.rb1
-rw-r--r--lib/chef/resource/rpm_package.rb9
-rw-r--r--lib/chef/resource/script.rb11
-rw-r--r--lib/chef/resource/template.rb5
-rw-r--r--lib/chef/resource/windows_package.rb2
-rw-r--r--lib/chef/resource/windows_service.rb18
-rw-r--r--lib/chef/resource_builder.rb137
-rw-r--r--lib/chef/resource_definition.rb2
-rw-r--r--lib/chef/resource_reporter.rb2
-rw-r--r--lib/chef/resources.rb1
-rw-r--r--lib/chef/role.rb21
-rw-r--r--lib/chef/run_context.rb16
-rw-r--r--lib/chef/search/query.rb153
-rw-r--r--lib/chef/shell/ext.rb4
-rw-r--r--lib/chef/util/diff.rb5
-rw-r--r--lib/chef/util/dsc/configuration_generator.rb36
-rw-r--r--lib/chef/util/dsc/lcm_output_parser.rb10
-rw-r--r--lib/chef/util/dsc/local_configuration_manager.rb16
-rw-r--r--lib/chef/util/file_edit.rb4
-rw-r--r--lib/chef/util/path_helper.rb5
-rw-r--r--lib/chef/util/windows/net_use.rb6
-rw-r--r--lib/chef/version.rb2
-rw-r--r--lib/chef/win32/api.rb1
-rw-r--r--lib/chef/win32/api/security.rb26
-rw-r--r--lib/chef/win32/file.rb21
-rw-r--r--lib/chef/win32/security.rb46
-rw-r--r--lib/chef/win32/security/token.rb8
-rw-r--r--lib/chef/win32/version.rb4
-rw-r--r--pedant.gemfile1
-rw-r--r--spec/data/recipes.tgzbin0 -> 293 bytes
-rw-r--r--spec/functional/application_spec.rb2
-rw-r--r--spec/functional/audit/rspec_formatter_spec.rb54
-rw-r--r--spec/functional/audit/runner_spec.rb137
-rw-r--r--spec/functional/dsl/reboot_pending_spec.rb20
-rw-r--r--spec/functional/dsl/registry_helper_spec.rb12
-rw-r--r--spec/functional/event_loggers/windows_eventlog_spec.rb10
-rw-r--r--spec/functional/file_content_management/deploy_strategies_spec.rb33
-rw-r--r--spec/functional/http/simple_spec.rb2
-rw-r--r--spec/functional/knife/cookbook_delete_spec.rb48
-rw-r--r--spec/functional/knife/exec_spec.rb6
-rw-r--r--spec/functional/knife/smoke_test.rb2
-rw-r--r--spec/functional/knife/ssh_spec.rb46
-rwxr-xr-xspec/functional/provider/remote_file/cache_control_data_spec.rb16
-rw-r--r--spec/functional/provider/whyrun_safe_ruby_block_spec.rb4
-rw-r--r--spec/functional/rebooter_spec.rb2
-rwxr-xr-xspec/functional/resource/aix_service_spec.rb3
-rwxr-xr-xspec/functional/resource/aixinit_service_spec.rb6
-rw-r--r--spec/functional/resource/bash_spec.rb88
-rw-r--r--spec/functional/resource/deploy_revision_spec.rb199
-rwxr-xr-xspec/functional/resource/env_spec.rb6
-rw-r--r--spec/functional/resource/execute_spec.rb160
-rw-r--r--spec/functional/resource/file_spec.rb14
-rw-r--r--spec/functional/resource/git_spec.rb26
-rw-r--r--spec/functional/resource/group_spec.rb53
-rw-r--r--spec/functional/resource/ifconfig_spec.rb4
-rw-r--r--spec/functional/resource/link_spec.rb155
-rw-r--r--spec/functional/resource/mount_spec.rb10
-rw-r--r--spec/functional/resource/ohai_spec.rb2
-rw-r--r--spec/functional/resource/package_spec.rb44
-rw-r--r--spec/functional/resource/powershell_spec.rb99
-rw-r--r--spec/functional/resource/reboot_spec.rb4
-rw-r--r--spec/functional/resource/registry_spec.rb182
-rw-r--r--spec/functional/resource/remote_directory_spec.rb38
-rw-r--r--spec/functional/resource/remote_file_spec.rb36
-rw-r--r--spec/functional/resource/template_spec.rb8
-rw-r--r--spec/functional/resource/user/dscl_spec.rb8
-rw-r--r--spec/functional/resource/user/useradd_spec.rb115
-rw-r--r--spec/functional/resource/windows_service_spec.rb98
-rw-r--r--spec/functional/run_lock_spec.rb18
-rw-r--r--spec/functional/shell_spec.rb6
-rw-r--r--spec/functional/tiny_server_spec.rb24
-rw-r--r--spec/functional/util/path_helper_spec.rb2
-rw-r--r--spec/functional/version_spec.rb2
-rw-r--r--spec/functional/win32/registry_helper_spec.rb250
-rw-r--r--spec/functional/win32/security_spec.rb67
-rw-r--r--spec/functional/win32/service_manager_spec.rb114
-rw-r--r--spec/functional/win32/versions_spec.rb12
-rw-r--r--spec/integration/client/client_spec.rb111
-rw-r--r--spec/integration/knife/chef_fs_data_store_spec.rb20
-rw-r--r--spec/integration/knife/common_options_spec.rb6
-rw-r--r--spec/integration/knife/cookbook_api_ipv6_spec.rb4
-rw-r--r--spec/integration/knife/deps_spec.rb8
-rw-r--r--spec/integration/knife/diff_spec.rb12
-rw-r--r--spec/integration/knife/download_spec.rb12
-rw-r--r--spec/integration/knife/list_spec.rb4
-rw-r--r--spec/integration/knife/raw_spec.rb10
-rw-r--r--spec/integration/knife/serve_spec.rb6
-rw-r--r--spec/integration/knife/show_spec.rb6
-rw-r--r--spec/integration/knife/upload_spec.rb36
-rw-r--r--spec/integration/recipes/lwrp_inline_resources_spec.rb2
-rw-r--r--spec/integration/solo/solo_spec.rb23
-rw-r--r--spec/spec_helper.rb42
-rw-r--r--spec/stress/win32/file_spec.rb4
-rw-r--r--spec/stress/win32/security_spec.rb8
-rw-r--r--spec/support/chef_helpers.rb6
-rw-r--r--spec/support/matchers/leak.rb4
-rw-r--r--spec/support/mock/platform.rb2
-rw-r--r--spec/support/pedant/Gemfile3
-rw-r--r--spec/support/pedant/pedant_config.rb11
-rw-r--r--spec/support/pedant/run_pedant.rb31
-rw-r--r--spec/support/platform_helpers.rb20
-rw-r--r--spec/support/shared/functional/directory_resource.rb26
-rw-r--r--spec/support/shared/functional/file_resource.rb166
-rw-r--r--spec/support/shared/functional/http.rb2
-rw-r--r--spec/support/shared/functional/securable_resource.rb128
-rw-r--r--spec/support/shared/functional/securable_resource_with_reporting.rb84
-rw-r--r--spec/support/shared/functional/win32_service.rb60
-rw-r--r--spec/support/shared/functional/windows_script.rb16
-rw-r--r--spec/support/shared/integration/knife_support.rb13
-rw-r--r--spec/support/shared/matchers/exit_with_code.rb8
-rw-r--r--spec/support/shared/unit/api_error_inspector.rb16
-rw-r--r--spec/support/shared/unit/execute_resource.rb44
-rw-r--r--spec/support/shared/unit/file_system_support.rb4
-rw-r--r--spec/support/shared/unit/platform_introspector.rb42
-rw-r--r--spec/support/shared/unit/provider/file.rb449
-rw-r--r--spec/support/shared/unit/provider/useradd_based_user_provider.rb138
-rw-r--r--spec/support/shared/unit/script_resource.rb72
-rw-r--r--spec/support/shared/unit/windows_script_resource.rb16
-rw-r--r--spec/unit/api_client/registration_spec.rb94
-rw-r--r--spec/unit/api_client_spec.rb176
-rw-r--r--spec/unit/application/apply_spec.rb46
-rw-r--r--spec/unit/application/client_spec.rb190
-rw-r--r--spec/unit/application/knife_spec.rb62
-rw-r--r--spec/unit/application/solo_spec.rb102
-rw-r--r--spec/unit/application_spec.rb183
-rw-r--r--spec/unit/audit/audit_event_proxy_spec.rb311
-rw-r--r--spec/unit/audit/audit_reporter_spec.rb393
-rw-r--r--spec/unit/audit/control_group_data_spec.rb478
-rw-r--r--spec/unit/audit/rspec_formatter_spec.rb (renamed from lib/chef/monkey_patches/file.rb)19
-rw-r--r--spec/unit/audit/runner_spec.rb135
-rw-r--r--spec/unit/chef_fs/config_spec.rb52
-rw-r--r--spec/unit/chef_fs/diff_spec.rb24
-rw-r--r--spec/unit/chef_fs/file_pattern_spec.rb553
-rw-r--r--spec/unit/chef_fs/file_system/operation_failed_error_spec.rb12
-rw-r--r--spec/unit/chef_fs/file_system_spec.rb39
-rw-r--r--spec/unit/chef_fs/parallelizer.rb174
-rw-r--r--spec/unit/chef_spec.rb2
-rw-r--r--spec/unit/client_spec.rb360
-rw-r--r--spec/unit/config_fetcher_spec.rb26
-rw-r--r--spec/unit/config_spec.rb171
-rw-r--r--spec/unit/cookbook/chefignore_spec.rb12
-rw-r--r--spec/unit/cookbook/cookbook_version_loader_spec.rb6
-rw-r--r--spec/unit/cookbook/metadata_spec.rb298
-rw-r--r--spec/unit/cookbook/syntax_check_spec.rb67
-rw-r--r--spec/unit/cookbook_loader_spec.rb120
-rw-r--r--spec/unit/cookbook_manifest_spec.rb609
-rw-r--r--spec/unit/cookbook_site_streaming_uploader_spec.rb54
-rw-r--r--spec/unit/cookbook_spec.rb30
-rw-r--r--spec/unit/cookbook_uploader_spec.rb40
-rw-r--r--spec/unit/cookbook_version_file_specificity_spec.rb554
-rw-r--r--spec/unit/cookbook_version_spec.rb338
-rw-r--r--spec/unit/daemon_spec.rb62
-rw-r--r--spec/unit/data_bag_item_spec.rb210
-rw-r--r--spec/unit/data_bag_spec.rb70
-rw-r--r--spec/unit/deprecation_spec.rb41
-rw-r--r--spec/unit/digester_spec.rb6
-rw-r--r--spec/unit/dsl/audit_spec.rb43
-rw-r--r--spec/unit/dsl/data_query_spec.rb2
-rw-r--r--spec/unit/dsl/platform_introspection_spec.rb28
-rw-r--r--spec/unit/dsl/reboot_pending_spec.rb36
-rw-r--r--spec/unit/dsl/regsitry_helper_spec.rb12
-rw-r--r--spec/unit/encrypted_data_bag_item_spec.rb140
-rw-r--r--spec/unit/environment_spec.rb210
-rw-r--r--spec/unit/exceptions_spec.rb48
-rw-r--r--spec/unit/file_access_control_spec.rb118
-rw-r--r--spec/unit/file_cache_spec.rb22
-rw-r--r--spec/unit/file_content_management/deploy/cp_spec.rb4
-rw-r--r--spec/unit/file_content_management/deploy/mv_unix_spec.rb20
-rw-r--r--spec/unit/file_content_management/deploy/mv_windows_spec.rb46
-rw-r--r--spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb28
-rw-r--r--spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb24
-rw-r--r--spec/unit/formatters/error_inspectors/cookbook_sync_error_inspector_spec.rb2
-rw-r--r--spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb32
-rw-r--r--spec/unit/formatters/error_inspectors/run_list_expansion_error_inspector_spec.rb8
-rw-r--r--spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb116
-rw-r--r--spec/unit/guard_interpreter_spec.rb41
-rw-r--r--spec/unit/handler/json_file_spec.rb20
-rw-r--r--spec/unit/handler_spec.rb78
-rw-r--r--spec/unit/http/basic_client_spec.rb6
-rw-r--r--spec/unit/http/http_request_spec.rb20
-rw-r--r--spec/unit/http/simple_spec.rb6
-rw-r--r--spec/unit/http/ssl_policies_spec.rb30
-rw-r--r--spec/unit/http/validate_content_length_spec.rb31
-rw-r--r--spec/unit/http_spec.rb25
-rw-r--r--spec/unit/knife/bootstrap/chef_vault_handler_spec.rb153
-rw-r--r--spec/unit/knife/bootstrap/client_builder_spec.rb178
-rw-r--r--spec/unit/knife/bootstrap_spec.rb235
-rw-r--r--spec/unit/knife/client_bulk_delete_spec.rb48
-rw-r--r--spec/unit/knife/client_create_spec.rb100
-rw-r--r--spec/unit/knife/client_delete_spec.rb30
-rw-r--r--spec/unit/knife/client_edit_spec.rb8
-rw-r--r--spec/unit/knife/client_list_spec.rb4
-rw-r--r--spec/unit/knife/client_reregister_spec.rb18
-rw-r--r--spec/unit/knife/configure_client_spec.rb40
-rw-r--r--spec/unit/knife/configure_spec.rb170
-rw-r--r--spec/unit/knife/cookbook_bulk_delete_spec.rb30
-rw-r--r--spec/unit/knife/cookbook_create_spec.rb118
-rw-r--r--spec/unit/knife/cookbook_delete_spec.rb98
-rw-r--r--spec/unit/knife/cookbook_download_spec.rb112
-rw-r--r--spec/unit/knife/cookbook_list_spec.rb18
-rw-r--r--spec/unit/knife/cookbook_metadata_from_file_spec.rb16
-rw-r--r--spec/unit/knife/cookbook_metadata_spec.rb88
-rw-r--r--spec/unit/knife/cookbook_show_spec.rb58
-rw-r--r--spec/unit/knife/cookbook_site_download_spec.rb52
-rw-r--r--spec/unit/knife/cookbook_site_share_spec.rb127
-rw-r--r--spec/unit/knife/cookbook_site_unshare_spec.rb30
-rw-r--r--spec/unit/knife/cookbook_test_spec.rb32
-rw-r--r--spec/unit/knife/cookbook_upload_spec.rb176
-rw-r--r--spec/unit/knife/core/bootstrap_context_spec.rb59
-rw-r--r--spec/unit/knife/core/cookbook_scm_repo_spec.rb72
-rw-r--r--spec/unit/knife/core/object_loader_spec.rb6
-rw-r--r--spec/unit/knife/core/subcommand_loader_spec.rb140
-rw-r--r--spec/unit/knife/core/ui_spec.rb156
-rw-r--r--spec/unit/knife/data_bag_from_file_spec.rb2
-rw-r--r--spec/unit/knife/environment_compare_spec.rb24
-rw-r--r--spec/unit/knife/environment_create_spec.rb32
-rw-r--r--spec/unit/knife/environment_delete_spec.rb28
-rw-r--r--spec/unit/knife/environment_edit_spec.rb30
-rw-r--r--spec/unit/knife/environment_from_file_spec.rb34
-rw-r--r--spec/unit/knife/environment_list_spec.rb14
-rw-r--r--spec/unit/knife/environment_show_spec.rb20
-rw-r--r--spec/unit/knife/index_rebuild_spec.rb34
-rw-r--r--spec/unit/knife/knife_help.rb48
-rw-r--r--spec/unit/knife/node_bulk_delete_spec.rb28
-rw-r--r--spec/unit/knife/node_delete_spec.rb22
-rw-r--r--spec/unit/knife/node_edit_spec.rb34
-rw-r--r--spec/unit/knife/node_environment_set_spec.rb24
-rw-r--r--spec/unit/knife/node_from_file_spec.rb16
-rw-r--r--spec/unit/knife/node_list_spec.rb18
-rw-r--r--spec/unit/knife/node_run_list_add_spec.rb58
-rw-r--r--spec/unit/knife/node_run_list_remove_spec.rb41
-rw-r--r--spec/unit/knife/node_run_list_set_spec.rb54
-rw-r--r--spec/unit/knife/raw_spec.rb43
-rw-r--r--spec/unit/knife/role_bulk_delete_spec.rb24
-rw-r--r--spec/unit/knife/role_create_spec.rb24
-rw-r--r--spec/unit/knife/role_delete_spec.rb20
-rw-r--r--spec/unit/knife/role_edit_spec.rb26
-rw-r--r--spec/unit/knife/role_env_run_list_add_spec.rb217
-rw-r--r--spec/unit/knife/role_env_run_list_clear_spec.rb100
-rw-r--r--spec/unit/knife/role_env_run_list_remove_spec.rb108
-rw-r--r--spec/unit/knife/role_env_run_list_replace_spec.rb108
-rw-r--r--spec/unit/knife/role_env_run_list_set_spec.rb102
-rw-r--r--spec/unit/knife/role_from_file_spec.rb20
-rw-r--r--spec/unit/knife/role_list_spec.rb14
-rw-r--r--spec/unit/knife/role_run_list_add_spec.rb179
-rw-r--r--spec/unit/knife/role_run_list_clear_spec.rb90
-rw-r--r--spec/unit/knife/role_run_list_remove_spec.rb98
-rw-r--r--spec/unit/knife/role_run_list_replace_spec.rb101
-rw-r--r--spec/unit/knife/role_run_list_set_spec.rb92
-rw-r--r--spec/unit/knife/ssh_spec.rb132
-rw-r--r--spec/unit/knife/ssl_check_spec.rb54
-rw-r--r--spec/unit/knife/ssl_fetch_spec.rb57
-rw-r--r--spec/unit/knife/status_spec.rb10
-rw-r--r--spec/unit/knife/tag_create_spec.rb10
-rw-r--r--spec/unit/knife/tag_delete_spec.rb12
-rw-r--r--spec/unit/knife/tag_list_spec.rb8
-rw-r--r--spec/unit/knife/user_create_spec.rb36
-rw-r--r--spec/unit/knife/user_delete_spec.rb8
-rw-r--r--spec/unit/knife/user_edit_spec.rb14
-rw-r--r--spec/unit/knife/user_list_spec.rb4
-rw-r--r--spec/unit/knife/user_reregister_spec.rb20
-rw-r--r--spec/unit/knife/user_show_spec.rb10
-rw-r--r--spec/unit/knife_spec.rb72
-rw-r--r--spec/unit/lwrp_spec.rb102
-rw-r--r--spec/unit/mash_spec.rb12
-rw-r--r--spec/unit/mixin/checksum_spec.rb4
-rw-r--r--spec/unit/mixin/command_spec.rb26
-rw-r--r--spec/unit/mixin/convert_to_class_name_spec.rb12
-rw-r--r--spec/unit/mixin/deep_merge_spec.rb98
-rw-r--r--spec/unit/mixin/deprecation_spec.rb10
-rw-r--r--spec/unit/mixin/enforce_ownership_and_permissions_spec.rb28
-rw-r--r--spec/unit/mixin/homebrew_user_spec.rb6
-rw-r--r--spec/unit/mixin/params_validate_spec.rb142
-rw-r--r--spec/unit/mixin/path_sanity_spec.rb28
-rw-r--r--spec/unit/mixin/securable_spec.rb354
-rw-r--r--spec/unit/mixin/shell_out_spec.rb83
-rw-r--r--spec/unit/mixin/template_spec.rb62
-rw-r--r--spec/unit/mixin/windows_architecture_helper_spec.rb10
-rw-r--r--spec/unit/mixin/xml_escape_spec.rb14
-rw-r--r--spec/unit/monkey_patches/uri_spec.rb2
-rw-r--r--spec/unit/monologger_spec.rb6
-rw-r--r--spec/unit/node/attribute_spec.rb321
-rw-r--r--spec/unit/node/immutable_collections_spec.rb44
-rw-r--r--spec/unit/node_spec.rb389
-rw-r--r--spec/unit/org_spec.rb196
-rw-r--r--spec/unit/platform/query_helpers_spec.rb10
-rw-r--r--spec/unit/platform_spec.rb92
-rw-r--r--spec/unit/policy_builder/expand_node_object_spec.rb35
-rw-r--r--spec/unit/policy_builder/policyfile_spec.rb230
-rw-r--r--spec/unit/provider/directory_spec.rb10
-rw-r--r--spec/unit/provider/dsc_script_spec.rb12
-rw-r--r--spec/unit/provider/env_spec.rb41
-rw-r--r--spec/unit/provider/execute_spec.rb207
-rw-r--r--spec/unit/provider/file/content_spec.rb16
-rw-r--r--spec/unit/provider/git_spec.rb15
-rw-r--r--spec/unit/provider/group/dscl_spec.rb19
-rw-r--r--spec/unit/provider/group_spec.rb26
-rw-r--r--spec/unit/provider/ifconfig/aix_spec.rb5
-rw-r--r--spec/unit/provider/ifconfig/debian_spec.rb38
-rw-r--r--spec/unit/provider/ifconfig_spec.rb4
-rw-r--r--spec/unit/provider/mdadm_spec.rb4
-rw-r--r--spec/unit/provider/mount/aix_spec.rb10
-rw-r--r--spec/unit/provider/mount/mount_spec.rb44
-rw-r--r--spec/unit/provider/mount/solaris_spec.rb40
-rw-r--r--spec/unit/provider/package/aix_spec.rb45
-rw-r--r--spec/unit/provider/package/apt_spec.rb27
-rw-r--r--spec/unit/provider/package/dpkg_spec.rb29
-rw-r--r--spec/unit/provider/package/freebsd/pkgng_spec.rb2
-rw-r--r--spec/unit/provider/package/freebsd/port_spec.rb2
-rw-r--r--spec/unit/provider/package/ips_spec.rb3
-rw-r--r--spec/unit/provider/package/macports_spec.rb28
-rw-r--r--spec/unit/provider/package/openbsd_spec.rb66
-rw-r--r--spec/unit/provider/package/pacman_spec.rb29
-rw-r--r--spec/unit/provider/package/portage_spec.rb22
-rw-r--r--spec/unit/provider/package/rpm_spec.rb216
-rw-r--r--spec/unit/provider/package/rubygems_spec.rb79
-rw-r--r--spec/unit/provider/package/solaris_spec.rb47
-rw-r--r--spec/unit/provider/package/yum_spec.rb273
-rw-r--r--spec/unit/provider/package/zypper_spec.rb21
-rw-r--r--spec/unit/provider/package_spec.rb278
-rw-r--r--spec/unit/provider/package_spec.rbe0
-rw-r--r--spec/unit/provider/remote_directory_spec.rb50
-rw-r--r--spec/unit/provider/remote_file/ftp_spec.rb6
-rw-r--r--spec/unit/provider/route_spec.rb6
-rw-r--r--spec/unit/provider/script_spec.rb104
-rw-r--r--spec/unit/provider/service/aix_service_spec.rb10
-rw-r--r--spec/unit/provider/service/arch_service_spec.rb10
-rw-r--r--spec/unit/provider/service/debian_service_spec.rb16
-rw-r--r--spec/unit/provider/service/freebsd_service_spec.rb18
-rw-r--r--spec/unit/provider/service/gentoo_service_spec.rb16
-rw-r--r--spec/unit/provider/service/init_service_spec.rb10
-rw-r--r--spec/unit/provider/service/insserv_service_spec.rb4
-rw-r--r--spec/unit/provider/service/invokercd_service_spec.rb10
-rw-r--r--spec/unit/provider/service/macosx_spec.rb14
-rw-r--r--spec/unit/provider/service/openbsd_service_spec.rb543
-rw-r--r--spec/unit/provider/service/redhat_spec.rb8
-rw-r--r--spec/unit/provider/service/simple_service_spec.rb4
-rw-r--r--spec/unit/provider/service/solaris_smf_service_spec.rb28
-rw-r--r--spec/unit/provider/service/systemd_service_spec.rb22
-rw-r--r--spec/unit/provider/service/upstart_service_spec.rb8
-rw-r--r--spec/unit/provider/service/windows_spec.rb144
-rw-r--r--spec/unit/provider/service_spec.rb2
-rw-r--r--spec/unit/provider/user/dscl_spec.rb68
-rw-r--r--spec/unit/provider/user_spec.rb2
-rw-r--r--spec/unit/provider_resolver_spec.rb14
-rw-r--r--spec/unit/provider_spec.rb46
-rw-r--r--spec/unit/recipe_spec.rb277
-rw-r--r--spec/unit/registry_helper_spec.rb286
-rw-r--r--spec/unit/resource/chef_gem_spec.rb120
-rw-r--r--spec/unit/resource/conditional_action_not_nothing_spec.rb4
-rw-r--r--spec/unit/resource/conditional_spec.rb71
-rw-r--r--spec/unit/resource/deploy_spec.rb4
-rw-r--r--spec/unit/resource/dsc_script_spec.rb32
-rw-r--r--spec/unit/resource/execute_spec.rb4
-rw-r--r--spec/unit/resource/file/verification_spec.rb111
-rw-r--r--spec/unit/resource/file_spec.rb14
-rw-r--r--spec/unit/resource/openbsd_package_spec.rb49
-rw-r--r--spec/unit/resource/remote_file_spec.rb24
-rw-r--r--spec/unit/resource/resource_notification_spec.rb36
-rw-r--r--spec/unit/resource/rpm_package_spec.rb12
-rw-r--r--spec/unit/resource/scm_spec.rb8
-rw-r--r--spec/unit/resource/script_spec.rb8
-rw-r--r--spec/unit/resource/subversion_spec.rb2
-rw-r--r--spec/unit/resource_builder_spec.rb1
-rw-r--r--spec/unit/resource_collection/resource_list_spec.rb4
-rw-r--r--spec/unit/resource_collection/resource_set_spec.rb6
-rw-r--r--spec/unit/resource_collection/stepable_iterator_spec.rb48
-rw-r--r--spec/unit/resource_collection_spec.rb104
-rw-r--r--spec/unit/resource_definition_spec.rb2
-rw-r--r--spec/unit/resource_reporter_spec.rb236
-rw-r--r--spec/unit/resource_spec.rb256
-rw-r--r--spec/unit/rest/auth_credentials_spec.rb146
-rw-r--r--spec/unit/rest_spec.rb24
-rw-r--r--spec/unit/role_spec.rb169
-rw-r--r--spec/unit/run_context/cookbook_compiler_spec.rb36
-rw-r--r--spec/unit/run_context_spec.rb107
-rw-r--r--spec/unit/run_list/run_list_expansion_spec.rb42
-rw-r--r--spec/unit/run_list/run_list_item_spec.rb56
-rw-r--r--spec/unit/run_list/versioned_recipe_list_spec.rb28
-rw-r--r--spec/unit/run_list_spec.rb110
-rw-r--r--spec/unit/run_lock_spec.rb28
-rw-r--r--spec/unit/run_status_spec.rb48
-rw-r--r--spec/unit/scan_access_control_spec.rb46
-rw-r--r--spec/unit/search/query_spec.rb120
-rw-r--r--spec/unit/shell/model_wrapper_spec.rb26
-rw-r--r--spec/unit/shell/shell_ext_spec.rb64
-rw-r--r--spec/unit/shell/shell_session_spec.rb48
-rw-r--r--spec/unit/shell_out_spec.rb8
-rw-r--r--spec/unit/shell_spec.rb54
-rw-r--r--spec/unit/user_spec.rb100
-rw-r--r--spec/unit/util/backup_spec.rb64
-rw-r--r--spec/unit/util/diff_spec.rb62
-rw-r--r--spec/unit/util/dsc/configuration_generator_spec.rb54
-rw-r--r--spec/unit/util/dsc/lcm_output_parser_spec.rb47
-rw-r--r--spec/unit/util/dsc/local_configuration_manager_spec.rb20
-rw-r--r--spec/unit/util/editor_spec.rb20
-rw-r--r--spec/unit/util/file_edit_spec.rb20
-rw-r--r--spec/unit/util/path_helper_spec.rb84
-rw-r--r--spec/unit/util/powershell/cmdlet_spec.rb18
-rw-r--r--spec/unit/util/selinux_spec.rb60
-rw-r--r--spec/unit/util/threaded_job_queue_spec.rb12
-rw-r--r--spec/unit/version/platform_spec.rb10
-rw-r--r--spec/unit/version_class_spec.rb30
-rw-r--r--spec/unit/version_constraint/platform_spec.rb14
-rw-r--r--spec/unit/version_constraint_spec.rb86
-rw-r--r--spec/unit/windows_service_spec.rb30
-rw-r--r--spec/unit/workstation_config_loader_spec.rb4
-rw-r--r--tasks/rspec.rb34
691 files changed, 26279 insertions, 11686 deletions
diff --git a/.gitignore b/.gitignore
index a9e4338e2a..ecba9f4030 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,6 @@ Berksfile.lock
# Vagrant
Vagrantfile
.vagrant/
+
+# Kitchen Tests Local Mode Data
+kitchen-tests/nodes/*
diff --git a/.kitchen.yml b/.kitchen.yml
new file mode 100644
index 0000000000..ed49eb3e57
--- /dev/null
+++ b/.kitchen.yml
@@ -0,0 +1,82 @@
+driver:
+ name: vagrant
+ forward_agent: yes
+ customize:
+ cpus: 4
+ memory: 4096
+ synced_folders:
+ - ['.', '/home/vagrant/chef']
+
+provisioner:
+ name: chef_zero
+ require_chef_omnibus: 12.0.0.rc.1
+
+platforms:
+ - name: centos-5.10
+ run_list:
+ - name: centos-6.5
+ run_list:
+ - name: debian-7.2.0
+ run_list:
+ - name: debian-7.4
+ run_list:
+ - name: debian-6.0.8
+ run_list:
+ - name: freebsd-9.2
+ run_list:
+ - name: freebsd-10.0
+ run_list:
+ - name: ubuntu-10.04
+ run_list:
+ - name: ubuntu-12.04
+ run_list:
+ - name: ubuntu-12.10
+ run_list:
+ - name: ubuntu-13.04
+ run_list:
+ - name: ubuntu-13.10
+ run_list:
+ - name: ubuntu-14.04
+ run_list:
+ # The following boxes are shared via VagrantCloud. Until kitchen-vagrant
+ # is updated you'll need to add the box manually:
+ #
+ # vagrant box add chef/windows-8.1-professional
+ #
+ # Please note this may require a `vagrant login` if the box is private.
+ #
+ # The following boxes are VMware only also. You can enable VMware Fusion
+ # as the default provider by copying `.kitchen.local.yml.vmware.example`
+ # over to `.kitchen.local.yml`.
+ #
+ - name: macosx-10.8
+ driver:
+ box: chef/macosx-10.8 # private
+ - name: macosx-10.9
+ driver:
+ box: chef/macosx-10.9 # private
+ - name: macosx-10.10
+ driver:
+ box: chef/macosx-10.10 # private
+ # - name: windows-7-professional
+ # provisioner:
+ # name: windows_chef_zero
+ # require_chef_omnibus: 11.12.4
+ # driver:
+ # box: chef/windows-7-professional # private
+ # - name: windows-8.1-professional
+ # provisioner:
+ # name: windows_chef_zero
+ # require_chef_omnibus: 11.12.4
+ # driver:
+ # box: chef/windows-8.1-professional # private
+ # - name: windows-2008r2-standard
+ # provisioner:
+ # name: windows_chef_zero
+ # require_chef_omnibus: 11.12.4
+ # driver:
+ # box: chef/windows-server-2008r2-standard # private
+
+suites:
+ - name: chef
+ run_list:
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000000..a7b6b6b277
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,117 @@
+# Daniel DeLeo
+Daniel DeLeo <dan@chef.io> Daniel DeLeo <dan@opscode.com>
+Daniel DeLeo <dan@chef.io> Dan DeLeo <danielsdeleo@mac.com>
+Daniel DeLeo <dan@chef.io> Dan DeLeo <dan@kallistec.com>
+Daniel DeLeo <dan@chef.io> danielsdeleo <dan@getchef.com>
+Daniel DeLeo <dan@chef.io> danielsdeleo <dan@opscode.com>
+Daniel DeLeo <dan@chef.io> Daniel DeLeo <danielsdeleo@mac.com>
+
+# Adam Jacob
+Adam Jacob <adam@chef.io> Adam Jacob <adam@opscode.com>
+Adam Jacob <adam@chef.io> Adam Jacob <adam@hjksolutions.com>
+Adam Jacob <adam@chef.io> Adam Jacob <adam@latte.(none)>
+Adam Jacob <adam@chef.io> Adam Jacob <adam@ubuntu-apache1.(none)>
+
+# Bryan McLellan
+Bryan McLellan <btm@chef.io> Bryan McLellan <btm@getchef.com>
+Bryan McLellan <btm@chef.io> Bryan McLellan <bryan.mclellan@webtrends.com>
+Bryan McLellan <btm@chef.io> Bryan McLellan <btm@opscode.com>
+Bryan McLellan <btm@chef.io> Bryan McLellan <btm@loftninjas.org>
+Bryan McLellan <btm@chef.io> Bryan McLellan <bryanm@widemile.com>
+
+# Lamont Granquist
+Lamont Granquist <lamont@chef.io> Lamont Granquist <lamont@getchef.com>
+Lamont Granquist <lamont@chef.io> lamont-opscode <lamont@opscode.com>
+Lamont Granquist <lamont@chef.io> Lamont Granquist <lamont@opscode.com>
+Lamont Granquist <lamont@chef.io> Lamont Granquist <lamont@scriptkiddie.org>
+Lamont Granquist <lamont@chef.io> lamont-granquist <lamont@scriptkiddie.org>
+
+# Serdar Sutay
+Serdar Sutay <serdar@chef.io> Serdar Sutay <serdar@opscode.com>
+Serdar Sutay <serdar@chef.io> sersut <serdar@opscode.com>
+Serdar Sutay <serdar@chef.io> ssutay <serdar@opscode.com>
+
+# Claire McQuin
+Claire McQuin <claire@chef.io> Claire McQuin <claire@getchef.com>
+Claire McQuin <claire@chef.io> Claire McQuin <mcquin@users.noreply.github.com>
+Claire McQuin <claire@chef.io> Claire McQuin <claire@opscode.com>
+Claire McQuin <claire@chef.io> Claire McQuin <clairemcquin@seamcquin01.local>
+
+# John Keiser
+John Keiser <jkeiser@chef.io> John Keiser <jkeiser@opscode.com>
+John Keiser <jkeiser@chef.io> jkeiser <jkeiser@opscode.com>
+John Keiser <jkeiser@chef.io> John Keiser <john@johnkeiser.com>
+John Keiser <jkeiser@chef.io> John Keiser <johnkeiser@John-Keisers-MacBook-Pro.local>
+
+# Seth Chisamore
+Seth Chisamore <schisamo@chef.io> Seth Chisamore <schisamo@getchef.com>
+Seth Chisamore <schisamo@chef.io> Seth Chisamore <schisamo@opscode.com>
+
+# Joshua Timberman
+Joshua Timberman <joshua@chef.io> jtimberman <joshua@chef.io>
+Joshua Timberman <joshua@chef.io> Joshua Timberman <joshua@opscode.com>
+Joshua Timberman <joshua@chef.io> Joshua Timberman <jtimberman@cider.local>
+Joshua Timberman <joshua@chef.io> Joshua Timberman <jtimberman@users.noreply.github.com>
+Joshua Timberman <joshua@chef.io> jtimberman <joshua.timberman@gmail.com>
+Joshua Timberman <joshua@chef.io> jtimberman <joshua@opscode.com>
+Joshua Timberman <joshua@chef.io> jtimberman <jtimberman@www1test.housepub.org>
+
+# Nuo Yan
+Nuo Yan <nuo@opscode.com>
+Nuo Yan <nuo@opscode.com> Nuo Yan <nuoyan@nuo-yans-macbook-pro.(none)>
+Nuo Yan <nuo@opscode.com> Nuo Yan <nuoyan@nuo-yans-macbook-pro.local>
+
+# Thom May
+Thom May <thom@clearairturbulence.org>
+Thom May <thom@clearairturbulence.org> Thom May <thom.may@betfair.com>
+Thom May <thom@clearairturbulence.org> Thom May <thom@digital-science.com>
+Thom May <thom@clearairturbulence.org> Thom May <thom@virelais.nyc.joostas.com>
+Thom May <thom@clearairturbulence.org> Thom May <tmay@expedia.com>
+
+# Stephen Delano
+Stephen Delano <stephen@chef.io> Stephen Delano <stephen@opscode.com>
+Stephen Delano <stephen@chef.io> Stephen Delano <stephen@opscode-stephen.(none)>
+Stephen Delano <stephen@chef.io> Stephen Delano <stephen@opscode-stephen.local>
+Stephen Delano <stephen@chef.io> sdelano <stephen@opscode.com>
+
+# AJ Christensen
+AJ Christensen <aj@opscode.com>
+AJ Christensen <aj@opscode.com> AJ Christensen <aj@junglist.gen.nz>
+
+# Seth Falcon
+Seth Falcon <seth@chef.io> Seth Falcon <seth@opscode.com>
+Seth Falcon <seth@chef.io> Seth Falcon <sethfalcon@gmail.com>
+
+# Adam Edwards
+Adam Edwards <adamed@chef.io> Adam Edwards <adamed@opscode.com>
+Adam Edwards <adamed@chef.io> adamedx <adamed@getchef.com>
+Adam Edwards <adamed@chef.io> adamedx <adamed@opscode.com>
+Adam Edwards <adamed@chef.io> adamedx <admed@opscode.com>
+
+# Prajakta Purohit
+Prajakta Purohit <prajakta@chef.io> Prajakta Purohit <prajakta@opscode.com>
+Prajakta Purohit <prajakta@chef.io> PrajaktaPurohit <prajakta@opscode.com>
+
+kaustubh-d <kaustubh@clogeny.com>
+kaustubh-d <kaustubh@clogeny.com> kaustubh <kaustubh.deo@gmail.com>
+kaustubh-d <kaustubh@clogeny.com> kaustubh-d <kausubh@clogeny.com>
+
+# Xabier de Zuazo
+Xabier de Zuazo <xabier@onddo.com>
+Xabier de Zuazo <xabier@onddo.com> Xabier de Zuazo <xabier.zuazo@evandti.com>
+Xabier de Zuazo <xabier@onddo.com> Xabier de Zuazo <xabier@zuazo.org>
+
+# Tim Hinderliter
+Tim Hinderliter <tim@opscode.com>
+Tim Hinderliter <tim@opscode.com> tim@opscode.com <tim@opscode.com>
+Tim Hinderliter <tim@opscode.com> timh <tim@opscode.com>
+
+# Mark Paradise
+Marc Paradise <marc@chef.io> Marc Paradise <marc@opscode.com>
+Marc Paradise <marc@chef.io> marc@opscode.com <marc@opscode.com>
+
+# Tyler Ball
+Tyler Ball <tyleraball@gmail.com> tyler-ball <tyleraball@gmail.com>
+
+# Steven Danna
+Steven Danna <steve@chef.io> Steven Danna <steve@opscode.com> \ No newline at end of file
diff --git a/.rspec b/.rspec
index 7bfa3f20e6..eb3ef03653 100644
--- a/.rspec
+++ b/.rspec
@@ -1,2 +1,2 @@
--color
--fs
+-fd
diff --git a/.travis.yml b/.travis.yml
index 2ebb6dde96..699d8237ad 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,15 +1,9 @@
-# Temporary workaround for issue with rubygems 2.2.0 with bundler 1.5 on ruby
-# 1.8.7.
-#
-# A fix has been merged to rubygems but not yet released. See:
-# https://github.com/rubygems/rubygems/commit/f8e0f1d5f67cfc4e1966cc1e2db367aebf8a09e4
-#
-# See also CHEF-4916
-#
-# This workaround should be removed when that fix is released.
+language: ruby
+
+sudo: false
+# Early warning system to catch if Rubygems breaks something
before_install:
-- gem update --system 2.1.11
-- gem --version
+ gem update --system
branches:
only:
@@ -18,7 +12,15 @@ branches:
- 11-stable
- 12-stable
-script: bundle exec rspec --color --format progress
+# do not run expensive spec tests on PRs, only on branches
+script: "
+echo '--color\n-fp' > .rspec;
+if [ ${TRAVIS_PULL_REQUEST} = 'false' ];
+then
+ bundle exec rake spec:all;
+else
+ bundle exec rake spec;
+fi"
env:
global:
@@ -28,6 +30,7 @@ matrix:
include:
- rvm: 2.0.0
- rvm: 2.1.5
+ - rvm: 2.2.0
- rvm: 2.1.5
gemfile: pedant.gemfile
script: bundle exec rake pedant
@@ -40,9 +43,10 @@ matrix:
before_script:
- cd kitchen-tests
script:
- - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then bundle exec kitchen test; fi
+# FIXME: we should fix centos-6 against AWS and then enable it here
+ - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then bundle exec kitchen test ubuntu; fi
after_script:
- - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then bundle exec kitchen destroy; fi
+ - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then bundle exec kitchen destroy ubuntu; fi
env:
- KITCHEN_YAML=.kitchen.travis.yml
- EC2_SSH_KEY_PATH=~/.ssh/id_aws.pem
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 64fbbbd2e5..949c2b8bfb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,19 +1,128 @@
+## Unreleased
+
+## 12.1.0
+
+* [**Andre Elizondo**](https://github.com/andrewelizondo)
+ Typo fixes
+* [**Vasiliy Tolstov**](https://github.com/vtolstov):
+ cleanup cookbook path from stale files (when using chef-solo with a tarball url)
+* [**Nathan Cerny**](https://github.com/ncerny):
+ Fix rubygems provider to use https instead of http.
+* [**Anshul Sharma**](https://github.com/justanshulsharma)
+ removed securerandom patch
+* [**Scott Bonds**](https://github.com/bonds)
+ add package support for OpenBSD
+* [**Lucy Wyman**](https://github.com/lucywyman)
+ Added support for handling empty version strings to rubygems provider.
+* [**Yulian Kuncheff**](https://github.com/Daegalus)
+ Correctly set the pre-release identifier during knife bootstrap.
+* [**Anshul Sharma**](https://github.com/justanshulsharma)
+ `knife node run_list remove` now accepts run_list options in the same form as add
+* [**Veres Lajos**](https://github.com/vlajos)
+ Typo fixes
+* [**Tim Smith**](https://github.com/tas50)
+ Typo fixes
+* [Pull 2505](https://github.com/opscode/chef/pull/2505) Make Chef handle URIs in a case-insensitive manner
+* [**Phil Dibowitz**](https://github.com/jaymzh):
+ Drop SSL warnings now that we have a safe default
+* [Pull 2684](https://github.com/chef/chef/pull/2684) Remove ole_initialize/uninitialize which cause problems with Ruby >= 2
+* [**BinaryBabel**](https://github.com/binarybabel)
+ Make knife cookbook site share prefer gnutar when packaging
+* [**Dave Eddy**](https://github.com/bahamas10)
+ Support arrays for not_if and only_if
+* [**Scott Bonds**](https://github.com/bonds)
+ Add service provider for OpenBSD
+* [**Alex Slynko**](https://github.com/alex-slynko-wonga)
+ Change env provider to preserve ordering
+* [**Rob Redpath**](https://github.com/robredpath)
+ Add --lockfile opt for chef-client and chef-solo
+* [**Josh Murphy**](https://github.com/jdmurphy)
+ Check cookbooks exist in path(s) before attempting to upload them with --all
+* [**Vasiliy Tolstov**](https://github.com/vtolstov)
+ add ability to fetch recipes like in chef-solo when using local-mode
+* [**Jan**](https://github.com/habermann24)
+ FIX data_bag_item.rb:161: warning: circular argument reference - data_bag
+* [**David Radcliffe**](https://github.com/dwradcliffe)
+ add banner for knife serve command
+* [**Yukihiko Sawanobori**](https://github.com/sawanoboly)
+ use Chef::JSONCompat.parse for file_contents
+* [**Xabier de Zuazo**] (https://github.com/zuazo)
+ Remove some simple Ruby 1.8 and 1.9 code
+* [**Xabier de Zuazo**] (https://github.com/zuazo)
+ Remove all RSpec test filters related to Ruby 1.8 and 1.9
+* [**Xabier de Zuazo**] (https://github.com/zuazo)
+ Fix knife cookbook upload messages
+* [**David Crowder**] (https://github.com/david-crowder)
+ refactor to use shell_out in rpm provider
+* [**Phil Dibowitz**](https://github.com/jaymzh):
+ Multi-package support
+* [**Naotoshi Seo**](https://github.com/sonots):
+ Support HTTP/FTP source on rpm_package
+ add json_attribs option for chef-apply command
+ allow_downgrade in rpm_package
+* [**AJ Christensen**](https://github.com/fujin):
+ Isolate/fix the no-fork fault. [Issue 2709](https://github.com/chef/chef/issues/2709)
+* [**Cory Stephenson**](https://github.com/Aevin1387):
+ Remove comments of a service being enabled/disabled in FreeBSD. [Fixes #1791](https://github.com/chef/chef/issues/1791)
+* [**Will Albenzi**](https://github.com/walbenzi):
+ CHEF-4591: Knife commands to manipulate env_run_list on nodes
+* [**Jon Cowie**](https://github.com/jonlives):
+ CHEF-2911: Fix yum_package provider to respect version requirements in package name and version attribute
+* [**Anshul Sharma**](https://github.com/justanshulsharma):
+ * Node::Attribute to_s should print merged attributes [Issue 1526](https://github.com/chef/chef/issues/1562)
+ * Access keys attribute in `knife show` list incorrect information [Issue 1974](https://github.com/chef/chef/issues/1974)
+ * Guard interpreter loading incorrect resource [Issue 2683](https://github.com/chef/chef/issues/2683)
+
+### Chef Contributions
+* ruby 1.9.3 support is dropped
+* Update Chef to use RSpec 3.2
+* Cleaned up script and execute provider + specs
+* Added deprecation warnings around the use of command attribute in script resources
+* Audit mode feature added - see the RELEASE_NOTES for details
+* shell_out now sets `LANGUAGE` and `LANG` to the `Chef::Config[:internal_locale]` in addition to `LC_ALL` forcing
+* chef_gem supports a compile_time flag and will warn if it is not set (behavior will change in the future)
+* suppress CHEF-3694 warnings on the most trivial resource cloning
+* fixed bugs in the deep_merge_cache logic introduced in 12.0.0 around `node['foo']` vs `node[:foo]` vs. `node.foo`
+* add `include_recipe "::recipe"` sugar to reference a recipe in the current cookbook
+* Add --proxy-auth option to `knife raw`
+* added Chef::Org model class for Chef Organizations in Chef 12 Server
+* `powershell_script` should now correctly get the exit code for scripts that it runs. See [Issue 2348](https://github.com/chef/chef/issues/2348)
+* Useradd functional tests fail randomly
+* Add comments to trusted_certs_content
+* fixes a bug where providers would not get defined if a top-level ruby constant with the same name was already defined (ark cookbook, chrome cookbook)
+* Fix a bug in `reboot`, `ips_package`, `paludis_package`, `windows_package` resources where `action :nothing` was not permitted
+* Use Chef::ApiClient#from_hash in `knife client create` to avoid json_class requirement. [Issue 2542](https://github.com/chef/chef/issues/2542)
+* Add support for policyfile native API (preview). These APIs are unstable, and you may be forced to delete data uploaded to them in a
+ future release, so only use them for demonstration purposes.
+* Deprecation warning for 'knife cookbook test'
+* dsc_script should now correctly honor timeout. See [Issue 2831](https://github.com/chef/chef/issues/2831)
+* Added an `imports` attribute to dsc_script. This attribute allows you to specify DSC resources that need to be imported for your script.
+* Fixed error where guard resources (using :guard_interpreter) were not ran in `why_run` mode [Issue 2694](https://github.com/chef/chef/issues/2694)
+* Add `verify` method to File resource per RFC027
+* Move supermarket.getchef.com to supermarket.chef.io
+* Check with AccessCheck for permission to write to directory on Windows
+* Add declare_resource/build_resource comments, fix faulty ||=
+* Knife bootstrap creates a client and ships it to the node to implement validatorless bootstraps
+* Knife bootstrap can use the client it creates to setup chef-vault items for the node
+
## 12.0.3
* [**Phil Dibowitz**](https://github.com/jaymzh):
- [Issue 2594](https://github.com/opscode/chef/issues/2594) Restore missing require in `digester`.
+[Issue 2594](https://github.com/opscode/chef/issues/2594) Restore missing require in `digester`.
## 12.0.2
* [Issue 2578](https://github.com/opscode/chef/issues/2578) Check that `installed` is not empty for `keg_only` formula in Homebrew provider
* [Issue 2609](https://github.com/opscode/chef/issues/2609) Resolve the circular dependency between ProviderResolver and Resource.
* [Issue 2596](https://github.com/opscode/chef/issues/2596) Fix nodes not writing to disk
-* [Issue 2625](https://github.com/opscode/chef/issues/2625) Fix missing `shell_out!` for `windows_package` resource
* [Issue 2580](https://github.com/opscode/chef/issues/2580) Make sure the relative paths are preserved when using link resource.
* [Pull 2630](https://github.com/opscode/chef/pull/2630) Improve knife's SSL error messaging
-* [Issue 2602](https://github.com/opscode/chef/issues/2602) Fix `subscribes` resource notifications.
* [Issue 2606](https://github.com/opscode/chef/issues/2606) chef 12 ignores default_release for apt_package
-* [**BackSlasher**](https://github.com/BackSlasher)
+* [Issue 2602](https://github.com/opscode/chef/issues/2602) Fix `subscribes` resource notifications.
+* [Issue 2578](https://github.com/opscode/chef/issues/2578) Check that `installed` is not empty for `keg_only` formula in Homebrew provider.
+* [**gh2k**](https://github.com/gh2k):
+ [Issue 2625](https://github.com/opscode/chef/issues/2625) Fix missing `shell_out!` for `windows_package` resource
+* [**BackSlasher**](https://github.com/BackSlasher):
[Issue 2634](https://github.com/opscode/chef/issues/2634) Fix `option ':command' is not a valid option` error in subversion provider.
-* [**Seth Vargo**](https://github.com/sethvargo)
+* [**Seth Vargo**](https://github.com/sethvargo):
[Issue 2345](https://github.com/opscode/chef/issues/2345) Allow knife to install cookbooks with metadata.json.
## 12.0.1
@@ -266,7 +375,6 @@
* Allow events to be logged to Windows Event Log
* Fixed bug in env resource where a value containing the delimiter could never correctly match the existing values
* More intelligent service check for systemd on Ubuntu 14.10.
-* [Issue 2380](https://github.com/opscode/chef/issues/2380) chef-shell on Windows no longer tries to load /etc/chef/client.rb
## 11.16.4
@@ -324,7 +432,7 @@
* [**Nikhil Benesch**](https://github.com/benesch):
Implemented a threaded download queue for synchronizing cookbooks. (CHEF-4423)
* [**Chulki Lee**](https://github.com/chulkilee):
- Raise an error when source is accidently passed to apt_package (CHEF-5113)
+ Raise an error when source is accidentally passed to apt_package (CHEF-5113)
* [**Cam Cope**](https://github.com/ccope):
Add an open_timeout when opening an http connection (CHEF-5152)
* [**Sander van Harmelen**](https://github.com/svanharmelen):
@@ -429,3 +537,4 @@
would not share the same actions/default_action as their parent
* Raise error if a guard_interpreter is specified and a block is passed to a guard (conditional)
* Allow specifying a guard_interpreter after a conditional on a resource (Fixes #1943)
+* Windows package type should be a symbol (Fixes #1997)
diff --git a/CLA_ARCHIVE.md b/CLA_ARCHIVE.md
new file mode 100644
index 0000000000..2593a71470
--- /dev/null
+++ b/CLA_ARCHIVE.md
@@ -0,0 +1,2510 @@
+
+Corporate CLAs
+
+The list of Corporate CLAs allowed to contribute to Opscode projects. Only contributions from approved employees of these companies are acceptable.
+
+Employees get approved by being listed on the schedule A of the Corporate CLA.
+
+| **Number:** | **Company:** | **Date:** |
+|:------------|:---------------------------------------|:----------|
+| 1 | Opscode | |
+| 2 | Engine Yard | 1/7/09 |
+| 3 | Wikia | |
+| 4 | Aptana | 2/12/09 |
+| 5 | CleanOffer | 3/2/09 |
+| 6 | 37signals | 3/4/09 |
+| 7 | Nomitor | 3/9/09 |
+| 8 | We Go To 12 | 4/30/09 |
+| 9 | Plus2 Pty | 5/8/09 |
+| 10 | Phusion | 6/22/09 |
+| 11 | Rightscale | 6/30/09 |
+| 12 | Rubaidh | 7/27/09 |
+| 13 | Peritor GmbH | 8/12/09 |
+| 14 | Heroku | 8/13/09 |
+| 15 | Internet Exchange | 9/22/09 |
+| 16 | Betfair | 9/30/09 |
+| 17 | Sojern | 11/2/09 |
+| 18 | Runa | 12/20/09 |
+| 19 | MaxMedia | 1/11/10 |
+| 20 | Quantifind | 2/11/10 |
+| 21 | VMware | 2/11/10 |
+| 22 | Rackspace | 2/26/10 |
+| 23 | Leaway Enterprise | 3/16/10 |
+| 24 | Bueda | 3/30/10 |
+| 25 | Divergent Logic | 5/3/10 |
+| 26 | Basho Technologies | 5/4/10 |
+| 27 | Seven Scale | 5/13/10 |
+| 28 | IglooNET | 5/21/10 |
+| 29 | Freistil Consulting | 5/25/10 |
+| 30 | Promet Solutions | 5/25/10 |
+| 31 | Mint Digital | 6/16/10 |
+| 32 | Picklive | 6/16/10 |
+| 33 | 42 Lines | 6/27/10 |
+| 34 | Wildfire Interactiv | 7/9/10 |
+| 35 | Dynamic Network Services | 7/21/10 |
+| 36 | PeerPong | 8/4/10 |
+| 37 | domainfactory GmbH | 8/16/10 |
+| 38 | Tecnh | 8/17/10 |
+| 39 | 9Summer | 9/9/10 |
+| 40 | Wixpress | 9/13/10 |
+| 41 | Blue Box Group | 9/29/10 |
+| 42 | FindsYou Limited | 10/6/10 |
+| 43 | Highgroove Studios | 10/25/10 |
+| 44 | ZeStuff | 10/28/10 |
+| 45 | Worlize | 10/28/10 |
+| 46 | Automated Labs | 11/3/10 |
+| 47 | Estately | 11/4/10 |
+| 48 | Kapoq | 11/10/10 |
+| 49 | Openminds | 11/10/10 |
+| 50 | MobileCause | 11/10/10 |
+| 51 | Atalanta Systems | 11/14/10 |
+| 52 | Menue Americas | 11/17/10 |
+| 53 | Sociable Limited | 12/1/10 |
+| 54 | Nine Summer | 12/6/10 |
+| 55 | Neo Technology | 1/27/11 |
+| 56 | Moriz GmbH | 2/2/11 |
+| 57 | AegisCo | 2/14/11 |
+| 58 | SetJam | 2/15/11 |
+| 59 | Tippr | 2/18/11 |
+| 60 | Ning | 2/24/11 |
+| 61 | Workday | 3/12/11 |
+| 62 | 7digital | 3/3/11 |
+| 63 | PagerDuty | 3/17/11 |
+| 64 | Gnowsis | 3/25/11 |
+| 65 | Unboxed Consulting | 4/1/11 |
+| 66 | CustomInk | 4/8/11 |
+| 67 | TalentBox | 4/25/11 |
+| 68 | Wavii | 4/29/11 |
+| 69 | Datadog | 5/4/11 |
+| 70 | Viximo | 5/10/11 |
+| 71 | ZephirWorks | 5/11/11 |
+| 72 | Dell | 5/12/11 |
+| 73 | Newsweek/Daily Beast Company | 5/19/11 |
+| 74 | WordStream | 5/19/11 |
+| 75 | Flagbit | 6/14/11 |
+| 76 | Applications Online | 6/17/11 |
+| 77 | Versapay | 7/5/11 |
+| 78 | DigiTar | 7/19/11 |
+| 79 | DreamHost | 7/21/11 |
+| 80 | Edmunds.com | 7/22/11 |
+| 81 | Every Ware | 7/25/11 |
+| 82 | Ask.com | 8/1/11 |
+| 83 | bring.out doo Sarajevo | 8/11/11 |
+| 84 | Kos Media | 8/15/11 |
+| 85 | reallyenglish.com | 8/15/11 |
+| 86 | Fewbytes | 8/18/11 |
+| 87 | Business Intelligence Associates | 8/19/11 |
+| 88 | Tacit Knowledge | 8/22/11 |
+| 89 | Zenexity | 8/30/11 |
+| 90 | ClassDo | 8/30/11 |
+| 91 | Myplanet | 9/2/11 |
+| 92 | ihiji | 9/16/11 |
+| 93 | "Port 80 Productions, LLC" | 10/28/11 |
+| 94 | Green Alto | 11/2/11 |
+| 95 | "Heavy Water Software, Inc." | 11/4/11 |
+| 96 | Wealthfront Inc. | 11/15/11 |
+| 97 | "Kickstarter, Inc." | 11/18/11 |
+| 98 | Webtrends Inc | 11/22/11 |
+| 99 | "Infochimps, Inc." | 11/28/11 |
+| 100 | "Cycle Computing, LLC" | 11/29/11 |
+| 101 | "Ubalo, Inc" | 12/8/11 |
+| 102 | "SweetSpot Diabetes Care, Inc." | 12/12/11 |
+| 103 | "RideCharge, Inc." | 12/15/11 |
+| 104 | "Riot Games, Inc." | 12/15/11 |
+| 105 | Fiksu | 12/21/11 |
+| 106 | WhitePages Inc. | 1/3/12 |
+| 107 | "CX, Inc." | 1/12/12 |
+| 108 | Spoke Software | 1/15/12 |
+| 109 | Xforty Technologies | 1/25/12 |
+| 110 | "Democracy Works, Inc" | 1/30/12 |
+| 111 | "Pure Lake Software, Inc." | 2/10/12 |
+| 112 | Sveriges Television AB | 2/14/12 |
+| 113 | Reaktor Innovations | 2/14/12 |
+| 114 | "Oxygen Cloud, Inc." | 2/14/12 |
+| 115 | Robojar Pty Ltd | 2/17/12 |
+| 116 | Green and Secure IT Limited | 2/19/12 |
+| 117 | ModCloth | 2/23/12 |
+| 118 | Joyent | 2/29/12 |
+| 119 | "Wallrazor, Inc." | 3/4/12 |
+| 120 | "Cerner Innovation, Inc." | 3/8/12 |
+| 121 | "Numenta, Inc." | 3/27/12 |
+| 122 | Kotiri Software Ltd. | 4/3/12 |
+| 123 | "The Frontside Software, Inc." | 4/5/12 |
+| 124 | "Needle, Inc." | 4/5/12 |
+| 125 | "Gap, Inc." | 4/10/12 |
+| 126 | Youscribe | 4/11/12 |
+| 127 | Deutsche Telekom Laboratories | 4/17/12 |
+| 128 | "Relevance, Inc." | 4/20/12 |
+| 129 | Truer Sound LLC | 4/20/12 |
+| 130 | Websym Technologies Private Ltd. | 4/30/12 |
+| 131 | DreamBox Learning Inc | 5/3/12 |
+| 132 | Simple | 5/7/12 |
+| 133 | "Consumer Club, Inc" | 5/10/12 |
+| 134 | Onddo Labs | 5/18/12 |
+| 135 | CyberAgent Corp. | 5/22/12 |
+| 136 | SourceIndex IT-Services | 6/7/12 |
+| 137 | "Scribd, Inc." | 6/15/12 |
+| 138 | Civolution BV | 6/18/12 |
+| 139 | Drillinginfo | 6/18/12 |
+| 140 | NaviNet | 6/20/12 |
+| 141 | "Voxel Dot Net, Inc" | 6/26/12 |
+| 142 | Asbury Theological Seminary | 6/27/12 |
+| 143 | The Cloudscaling Group | 6/27/12 |
+| 144 | "Creationline, Inc." | 6/27/12 |
+| 145 | "Action Verb, LLC" | 7/10/12 |
+| 146 | Iugu Servicos na Internet LTDA | 7/11/12 |
+| 147 | OpeniT | 7/18/12 |
+| 148 | Cloudreach Limited | 7/24/12 |
+| 149 | Bonnier Corporation | 7/25/12 |
+| 150 | "OneHealth Solutions, Inc." | 7/25/12 |
+| 151 | Hewlett-Packard | 7/26/12 |
+| 152 | Paydici Corp. | 7/26/12 |
+| 153 | "Novell, Inc." | 8/1/12 |
+| 154 | Schuberg Phillis B.V. | 8/3/12 |
+| 155 | RelatelIQ Inc. | 8/3/12 |
+| 156 | HomeMade Digital Ltd | 8/7/12 |
+| 157 | "PrimeRevenue, Inc" | 8/10/12 |
+| 158 | Calxeda | 8/14/12 |
+| 159 | Big Cartel LLC | 8/17/12 |
+| 160 | Atlassian | 8/27/12 |
+| 161 | One Connect Limited | 9/7/12 |
+| 162 | Sonian Inc | 9/8/12 |
+| 163 | The App Business | 9/19/12 |
+| 164 | "Pat Deegan, PhD & Associates, LLC" | 9/26/12 |
+| 165 | OmniTI | 9/26/12 |
+| 166 | "Cloudant, Inc." | 10/5/12 |
+| 167 | ZestFinance | 10/8/12 |
+| 168 | Firebelly Design | 10/8/12 |
+| 169 | Nu Echo | 10/16/12 |
+| 170 | OpenConcept Consulting Inc. | 10/18/12 |
+| 171 | Apptentive | 10/20/12 |
+| 172 | "Document Swarm, LLC" | 10/20/12 |
+| 173 | "Tilting @, LLC" | 10/29/12 |
+| 174 | "Sift Science, Inc" | 10/31/12 |
+| 175 | FluxSauce | 11/1/12 |
+| 176 | Rocket Internet GmbH | 11/2/12 |
+| 177 | Coding-Knight LTD | 11/6/12 |
+| 178 | Tapp | 11/13/12 |
+| 179 | Taqtiqa LLC | 11/14/12 |
+| 180 | "Nordstrom, Inc" | 11/15/12 |
+| 181 | Daptiv Solutions LLC | 11/26/12 |
+| 182 | Lime Pepper Ltd | 11/28/12 |
+| 183 | "Straydog Software, Inc." | 11/29/12 |
+| 184 | "Fidelity Technology Group, LLC" | 12/6/12 |
+| 185 | "Angelweb, Unipessoal Lda." | 12/14/12 |
+| 186 | bcs kommunikationslosungen | 12/17/12 |
+| 187 | "North County Tech Center, LLC" | 12/22/12 |
+| 188 | Emergent One | 1/9/13 |
+| 189 | Ninefold Pty Limited | 1/9/13 |
+| 190 | DecisionDesk | 1/13/13 |
+| 191 | Belly Inc | 1/15/13 |
+| 192 | cloudbau Gmbh | 1/18/13 |
+| 193 | ActBlue Technical Services | 1/18/13 |
+| 194 | HiganWorks LLC | 1/22/13 |
+| 195 | Ontario Systems | 1/23/13 |
+| 196 | "Lytro, Inc." | 1/23/13 |
+| 197 | Grupa Allegro Sp. z o.o. | 1/31/13 |
+| 198 | Workday Inc. | 2/5/13 |
+| 199 | "Atlas Digital, LLC" | 2/6/13 |
+| 200 | Intoximeters | 2/15/13 |
+| 201 | Airbnb | 2/17/13 |
+| 202 | Valtech AB | 2/20/13 |
+| 203 | AWeber Communications | 2/25/13 |
+| 204 | adesso mobile solutions GmbH | 3/4/13 |
+| 205 | "Banno, LLC" | 3/5/13 |
+| 206 | AboutUs | 3/8/13 |
+| 207 | "Google, Inc" | 3/14/13 |
+| 208 | cloudControl GmbH | 3/21/13 |
+| 209 | Springest | 3/25/13 |
+| 210 | Criteo | 3/26/13 |
+| 211 | "Thinking Phone Networks, Inc." | 4/8/13 |
+| 212 | Evolving Web Inc | 4/11/13 |
+| 213 | BinaryBabel OSS | 4/17/13 |
+| 214 | Tout Industries | 4/18/13 |
+| 215 | "Lookout, Inc." | 4/22/13 |
+| 216 | Recorded Future Inc | 4/23/13 |
+| 217 | Irrational Industries | 5/1/13 |
+| 218 | "Socrata, Inc" | 5/1/13 |
+| 219 | "Aspera, Inc" | 5/1/13 |
+| 220 | "Hadapt, Inc" | 5/3/13 |
+| 221 | Moncai | 5/7/13 |
+| 222 | IBM | 5/14/13 |
+| 223 | Yahoo Inc. | 5/14/13 |
+| 224 | Texas A&M University College of Arch. | 5/20/13 |
+| 225 | MoPub | 5/21/13 |
+| 226 | "Onelogin, Inc" | 5/24/13 |
+| 227 | Yola | 5/28/13 |
+| 228 | CopperEgg | 5/28/13 |
+| 229 | "MeetMe, Inc" | 5/30/13 |
+| 230 | Boadree Innovations Kft. | 6/17/13 |
+| 231 | "Bitium, inc" | 6/21/13 |
+| 232 | Heart of Sales LLC DBA Ace of Sales | 7/4/13 |
+| 233 | NetSrv Consulting Ltd | 7/7/13 |
+| 234 | "AURIN Project" | 7/11/13 |
+| 235 | Onlife Health Inc | 7/17/13 |
+| 236 | Roblox Inc. | 7/17/13 |
+| 237 | "Taos Mountain, Inc" | 7/24/13 |
+| 238 | CoreMedia AG | 7/31/13 |
+| 239 | "PROS, Inc. a Delaware Corporation" | 8/14/13 |
+| 240 | Identive Group | 8/21/13 |
+| 241 | University of Derby | 8/22/13 |
+| 242 | TeamSnap | 8/29/13 |
+| 243 | Social Ally Pty Ltd | 8/29/13 |
+| 244 | Ecodev Sarl | 9/9/13 |
+| 245 | kreuzwerker GmbH | 9/18/13 |
+| 246 | Central Desktop | 9/18/13 |
+| 247 | Siili Solutions | 9/19/13 |
+| 248 | Twiket LTD | 9/23/13 |
+| 249 | Cloudsoft | 9/25/13 |
+| 250 | MYOB NZ Limited | 9/26/13 |
+| 251 | Mollie B.V. | 9/30/13 |
+| 252 | Unbounce | 10/1/13 |
+| 253 | Shutl Ltd. | 10/2/13 |
+| 254 | Rapid7 | 10/7/13 |
+| 255 | "Our Film Festival, Inc (dba Fandor)" | 10/7/13 |
+| 256 | "Ooyala, Inc." | 10/9/13 |
+| 257 | Squaremouth Inc | 10/10/13 |
+| 258 | Optiflows | 10/11/13 |
+| 259 | General Sensing LTD | 10/10/13 |
+| 260 | Deployable LTD | 10/22/13 |
+| 261 | Klarna | 10/23/13 |
+| 262 | "Nike, Inc." | 10/25/13 |
+| 263 | SoundCloud Ltd. | 11/5/13 |
+| 264 | Project Florida | 11/5/13 |
+| 265 | Intuit | 11/6/13 |
+| 266 | ComputeNext | 11/6/13 |
+| 267 | The Weather Companies | 11/8/13 |
+| 268 | PTC Inc | 11/13/13 |
+| 269 | RamTank Inc | 11/19/13 |
+| 270 | GoCardless | 11/24/13 |
+| 271 | ZANOX AG | 11/30/13 |
+| 272 | ARINC | 12/3/13 |
+| 273 | Lockheed Martin Corporation | 12/3/13 |
+| 274 | Brightcove | 12/16/13 |
+| 275 | "Sprint.ly, Inc" | 12/27/13 |
+| 276 | Cramer Development | 1/10/14 |
+| 277 | "BlackBerry, Inc." | 1/20/14 |
+| 278 | Cerner Innovation Inc | 2/6/14 |
+| 279 | Cerner Innovation Inc | 2/11/14 |
+| 280 | Engine Yard | 2/12/14 |
+| 281 | Crux Hosted Services | 2/18/14 |
+| 282 | Blue Spurs | 2/24/14 |
+| 283 | GitLab.com | 3/1/14 |
+| 284 | Yelp | 3/7/14 |
+| 285 | Workday | 3/10/14 |
+| 286 | BMC Software Inc | 3/13/14 |
+| 287 | Itison | 3/14/14 |
+| 288 | "OnBeep, Inc." | 3/19/14 |
+| 289 | Level 11 Consulting | 3/19/14 |
+| 290 | Linaro Limited | 4/4/14 |
+| 291 | Spanlink Communications | 4/17/14 |
+| 292 | "WESEEK, Inc" | 4/29/14 |
+| 293 | "Iniqa UK, Ltd" | 6/4/14 |
+| 294 | Jemstep | 6/13/1 |
+
+
+
+
+Allowed Contributors
+
+The list of allowed contributors to Opscode projects. Persons listed as associated with a company may also be individual contributors as well.
+
+To get on the list, check out our instructions on how to contribute.
+
+1. Adam Jacob Opscode
+1. Andy Delcambre Engineyard 1/7/09
+1. Arjuna Christensen 1/7/09
+1. Artur Bergman Wikia
+1. Benjamin Black Opscode 1/10/09
+1. Bryan McLellan 1/7/09
+1. Dan Walters 3/7/09
+1. Edward Muller Engineyard 1/28/09
+1. Ezra Zygmuntowicz Engineyard 1/7/09
+1. Jason Cook Wikia
+1. Joe Williams 1/17/09
+1. Kris Rasmussen Aptana 2/12/09
+1. Lee Jensen Engineyard 1/24/09
+1. Nick Sullivan Wikia
+1. Paul Nasrat 1/19/09
+1. Pawel Rein Wikia
+1. Przemek Malkowski Wikia
+1. Sean Cribbs 2/5/09
+1. Steve Berryman 1/20/09
+1. Steven Parkes Aptana 2/12/09
+1. Thom May 1/21/09
+1. Tim Dysinger 1/28/09
+1. Michael Hale 2/16/09
+1. Mathieu Sauve-Frankel 2/22/09
+1. Matthew Landauer 2/25/09
+1. John Hampton CleanOffer 3/2/09
+1. Nadeem Bitar CleanOffer 3/2/09
+1. James Gartrell 2/6/09
+1. Joshua Sierles 37signals 3/4/09
+1. Mark Imbriaco 37signals 3/4/09
+1. Stephen Haynes Nomitor 3/9/09
+1. Yun Huang Yong Nomitor 3/9/09
+1. David Lee 3/9/09
+1. Matthew Kent 3/24/09
+1. Dave Myron 4/3/09
+1. Miguel Cabeça 8/4/09
+1. Jason Jackson 4/9/09
+1. Caleb Tennis 4/10/09
+1. Michael Lim 4/14/09
+1. David Balatero 4/28/09
+1. David Grandinetti We Go To 12 4/30/09
+1. Lachlan Cox Plus2 Pty 5/8/09
+1. Scott Likens 4/30/09
+1. Andrew Willis 5/25/09
+1. Hongli Lai Phusion 6/22/09
+1. Ninh Bui Phusion 6/22/09
+1. Edmund Haselwanter cloudbau Gmbh 6/25/09
+1. Raphael Simon RightScale 6/30/09
+1. Tony Spataro RightScale 6/30/09
+1. Stéphane Crivisier 6/30/09
+1. Matthew Todd Highgroove Studios 7/1/09
+1. Grant Zanetti 2/1/09
+1. Peter Woodman 6/22/09
+1. Daniel DeLeo 7/10/09
+1. Jeppe Madsen 9/13/09
+1. Cary Penniman RightScale 7/20/09
+1. J. Chris Anderson 8/7/09
+1. Graeme Mathieson Rubaidh 8/10/09
+1. Mark Connell Rubaidh 8/10/09
+1. Jonathan Weiss Peritor GmbH 8/12/09
+1. Mathias Meyer Peritor GmbH 8/12/09
+1. Pedro Belo Heroku 8/13/09
+1. Ricardo Chimal Jr. Heroku 8/13/09
+1. Adam Wiggins Heroku 8/13/09
+1. Ryan Tomayko Heroku 8/13/09
+1. Blake Mizerany Heroku 8/13/09
+1. Diego Algorta
+1. Kevin Hunt 8/14/09
+1. Sidney Burks 8/20/09
+1. Joe Van Dyk 9/1/09
+1. Sig Lange 9/1/09
+1. Alexander van Zoest 9/1/09
+1. Nathan Mueller 9/7/09
+1. Roman Heinrich 9/11/09
+1. Gábor Vészi 9/20/09
+1. Kenneth Kalmer Internet Exchange 9/22/09
+1. Luca Greco 9/22/09
+1. Charles Cook Betfair 9/30/09
+1. Mario Giammarco 10/6/09
+1. Matthew King 10/14/09
+1. James Golick 10/27/09
+1. Jörn Berrisch 10/28/09
+1. Peter Crossley 10/30/09
+1. Eric Hankins Sojern 11/2/09
+1. David McRae Sojern 11/2/09
+1. Dan Fitch Sojern 11/2/09
+1. Ian Meyer 11/8/09
+1. John Alberts 11/9/09
+1. Lee Marlow 11/11/09
+1. Tollef Fog Heen 11/12/09
+1. Cuong Chi Nghiem 11/13/09
+1. Gordon Thiesfeld 11/18/09
+1. Dreamcat4 11/21/09
+1. Guy Bolton King 12/3/09
+1. Robert Berger Runa 12/20/09
+1. Siva Jagadeesan Runa 12/20/09
+1. Ivan Pirlik 12/22/09
+1. David Abdemoulaie 12/23/09
+1. Alex Soto 12/29/09
+1. Bryan Helmkamp 12/30/09
+1. Jesse Nelson 1/6/10
+1. Seth Chisamore Opscode 1/11/10
+1. Alfredo Deza MaxMedia 1/11/10
+1. N. Alan Johnson Jr. 1/15/10
+1. Pavel Valodzka 2/8/10
+1. Kyle Maxwell Quantifind 2/11/10
+1. Doug MacEachern VMware 2/11/10
+1. Jan Zimmek 2/14/10
+1. Dan Prince Rackspace 2/26/10
+1. Gabe Westmaas Rackspace 2/26/10
+1. Tim Harper 3/8/10
+1. Renaud Chaput 3/10/10
+1. Daniel Peterson 3/11/10
+1. Amit Cohen Leaway Enterprise 3/16/10
+1. Avishai Ish-Shalom Leaway Enterprise 3/16/10
+1. Or Cohen Leaway Enterprise 3/16/10
+1. Jon Swope 3/19/10
+1. Jonathan Tron 3/19/10
+1. Christopher Peplin Bueda 3/30/10
+1. Trotter Cashion 4/3/10
+1. Benjamin Standefer 4/6/10
+1. P. Barrett Little 4/7/10
+1. John Nixon 4/13/10
+1. Bruce Krysiak 4/13/10
+1. Akzhan Abdulin 4/14/10
+1. Grant Rodgers 4/17/10
+1. Wesley Beary 4/22/10
+1. Farzad Farid 4/23/10
+1. Olivier Raginel 4/26/10
+1. Jacques Crocker 5/3/10
+1. Pierre Baillet 5/3/10
+1. Joel Merrick 5/3/10
+1. James Sanders 5/3/10
+1. John Goulah 5/3/10
+1. Toomas Pelberg 5/3/10
+1. Ceaser Larry Divergent Logic 5/3/10
+1. Justin Sheehy Basho Technologies 5/4/10
+1. Andrew Gross Basho Technologies 5/4/10
+1. Bryan Fink Basho Technologies 5/4/10
+1. Ben Mabey 5/5/10
+1. Christopher Durtschi Divergent Logic 5/7/10
+1. Kevin Carter Divergent Logic 5/7/10
+1. Saimon Moore 5/13/10
+1. Troy Davis Seven Scale 5/13/10
+1. Eric Lindvall Seven Scale 5/13/10
+1. Alexey Ivanov 5/14/10
+1. Pritesh Mehta 5/19/10
+1. Ondrej Kudlik IglooNET 5/21/10
+1. Marek Hulan IglooNET 5/21/10
+1. Chad Woolley 5/22/10
+1. Jochen Lillich Freistil Consulting 5/25/10
+1. Marius Ducea Promet Solutions 5/25/10
+1. Eric Butler 5/26/10
+1. Sahil Cooner 6/6/10
+1. Richard Nicholas Betfair 6/9/10
+1. Dan Slimmon 6/10/10
+1. Craig Webster Picklive 6/16/10
+1. Dean Strelau Mint Digital 6/17/10
+1. Kurt Yoder 6/25/10
+1. Jim Browne 42 Lines 6/27/10
+1. Andrey Sibiryov 7/7/10
+1. Anthony Newman Betfair 7/8/10
+1. Thomas Hoover 7/8/10
+1. Dylan Egan Wildfire Interactive 7/9/10
+1. Michael Carruthers Wildfire Interactive 7/11/10
+1. Jon Seaberg RightScale 7/20/10
+1. Sean O'Meara 7/20/10
+1. Cory von Wallenstein Dynamic Network Services 7/21/10
+1. Michael Leinartas 7/22/10
+1. Thomas Bishop 7/23/10
+1. Jon Wood 7/29/10
+1. Dmitry Vyal 8/4/10
+1. Gilles Devaux PeerPong 8/4/10
+1. Chris Pepper 8/5/10
+1. Dennis Klein 8/6/10
+1. Warwick Poole 8/12/10
+1. Ken Ming Ong 8/15/10
+1. Ash Berlin 8/16/10
+1. Jochen Tuchbreiter domainfactory GmbH 8/16/10
+1. Mat Ellis Tecnh 8/17/10
+1. Michael MacDonald 8/17/10
+1. Jorge Luiz deBrito Falcão 8/18/10
+1. Jamie Winsor 8/19/10
+1. Darrin Eden 8/19/10
+1. Jonathan Smith 8/19/10
+1. Andrew Fulcher 8/23/10
+1. Matthias Marschall 8/25/10
+1. Peter Struijk 8/25/10
+1. Robert Anthony Postill 8/28/10
+1. Joshua Timberman Opscode 9/6/10
+1. Benjamin Rockwood 9/6/10
+1. Douglas Knight 9/9/10
+1. Andrew Cole 9Summer 9/9/10
+1. Dimitri Krassovski Wixpress 9/13/10
+1. Gregory Man Wixpress 9/13/10
+1. Allan Feid 9/17/10
+1. Ringo De Smet 9/26/10
+1. Tomasz Napierala 9/27/10
+1. Jesse Proudman Blue Box Group 9/29/10
+1. Ian Parades Blue Box Group 9/29/10
+1. Lee Huffman Blue Box Group 9/29/10
+1. Christopher Horton 10/1/10
+1. Jude Sutton FindsYou Limited 10/6/10
+1. James Le Cuirot FindsYou Limited 10/6/10
+1. Richard Pelavin 10/7/10
+1. Blake Irvin ModCloth 10/8/10
+1. Jim Van Fleet 10/14/10
+1. Laurent Désarmes 10/14/10
+1. Jay T. McCanta 10/15/10
+1. Eric G. Wolfe 10/20/10
+1. Sami Haahtinen 10/21/10
+1. Chris Kelly Highgroove Studios 10/25/10
+1. Gerald L. Hevener Jr. 10/25/10
+1. Charles Quinn Highgroove Studios 10/25/10
+1. Jonathan Wallace Highgroove Studios 10/25/10
+1. Jason Ardell 10/26/10
+1. Sean Carey 10/27/10
+1. Pierre-Luc Brunet ZeStuff 10/28/10
+1. Sean Walbran 10/28/10
+1. Brian McKelvey Worlize 10/28/10
+1. Jeffrey Hulten Automated Labs 11/3/10
+1. Doug Cole Estately 11/4/10
+1. Ben Bleything Estately 11/4/10
+1. Sebastian Boehm 11/6/10
+1. Ches Martin 11/8/10
+1. Eric C. Herot 11/8/10
+1. Oliver Hankeln 11/10/10
+1. David Nolan Kapoq 11/10/10
+1. Frank Louwers Openminds 11/10/10
+1. Bernard Grymonpon Openminds 11/10/10
+1. Bram Gillemon Openminds 11/10/10
+1. Paul Cortens MobileCause 11/10/10
+1. Austin Schneider MobileCause 11/10/10
+1. Kevin Ahrens 11/13/10
+1. Stephen Nelson-Smith Atalanta Systems 11/14/10
+1. Caleb Groom 11/16/10
+1. Michael Ivey 11/17/10
+1. Wojciech Wnetrzak 11/20/10
+1. Dmitriy Tkachenko 11/22/10
+1. Filip Tepper 11/24/10
+1. Denis Barushev 11/27/10
+1. Pedro F. <<pancho>> Horrillo Guerra 11/28/10
+1. James Harton Sociable Limited 12/1/10
+1. Noah Kantrowitz 12/4/10
+1. Anthony Burton 12/4/10
+1. David Esposito Nine Summer 12/6/10
+1. Mike Lecza Nine Summer 12/6/10
+1. Andrew Cole Nine Summer 12/6/10
+1. Michael Winser Nine Summer 12/6/10
+1. Cory Burke Nine Summer 12/6/10
+1. Charles Duffy Tippr 12/7/10
+1. John Vincent 12/10/10
+1. Dustin Currie 12/14/10
+1. Mark Sonnabaum 12/14/10
+1. Elliot Murphy 12/22/10
+1. Laradji Nacer 12/30/10
+1. Todd Nine 1/3/11
+1. Elijah Wright 1/5/11
+1. Anshul Khandelwal 1/13/11
+1. Michael Carruthers 1/16/11
+1. Vishvananda Ishaya 1/17/11
+1. Scott Frazer 1/17/11
+1. Eric Hodel 1/21/11
+1. Eric Heydrick 1/25/11
+1. Andreas Kollegger Neo Technology 1/27/11
+1. Steve Lum 1/31/11
+1. Anthony Goddard 2/1/11
+1. Roland Moriz Moriz GmbH 2/2/11
+1. Emil Sit Hadapt 2/2/11
+1. Ranjib Dey 2/3/11
+1. Ryan Davis 2/8/11
+1. Eric Coleman 2/8/11
+1. James Casey 2/9/11
+1. Maciej Pasternacki 2/9/11
+1. Grzegorz Marszalek 2/11/11
+1. James Sulinski AegisCo 2/14/11
+1. Erik Sabowski AegisCo 2/14/11
+1. Maciej Pasternacki SetJam 2/15/11
+1. Steven Dossett Ning 2/17/11
+1. Dane Knecht Tippr 2/18/11
+1. Mark Imbriaco Heroku 2/28/11
+1. Jonathan Matthews 7digital 3/3/11
+1. Patrick Collins 3/7/11
+1. Jim Hopp Workday 3/12/11
+1. Ken Dove Workday 3/12/11
+1. Philip Reynolds Workday 3/12/11
+1. Victor Zakharyev Workday 3/12/11
+1. Greg Fuller Workday 3/12/11
+1. Michael Callahan Workday 3/15/11
+1. Don Norton Workday 3/15/11
+1. Joe Nuspl Workday 3/15/11
+1. Dan Thom Workday 3/15/11
+1. Rick Cooper Workday 3/15/11
+1. Patrick Debois 3/14/11
+1. Michael Guterl 3/15/11
+1. Andrew Miklas PagerDuty 3/17/11
+1. Tristan Sloughter 3/22/11
+1. Jonathon Ramsey 3/23/11
+1. Jesai Langenbach 3/24/11
+1. Maciej Pasternacki Gnowsis 3/25/11
+1. Omri Cohen 3/28/11
+1. Joseph Sokol-Margolis 3/31/11
+1. Alex Tomlins Unboxed Consulting 4/1/11
+1. Holger Just 4/5/11
+1. Jake Vanderdray CustomInk 4/8/11
+1. Nathen Harvey CustomInk 4/8/11
+1. Padraig O'Sullivan 4/8/11
+1. Christian Trabold 4/16/11
+1. KC Braunschweig Edmunds.com 4/19/11
+1. Josh Pasqualetto 4/21/11
+1. Christopher C. Johnson 4/21/11
+1. Christian Paredes 4/22/11
+1. Viral Shah 4/24/11
+1. Bradley Fritz 4/24/11
+1. Nat Lownes 4/25/11
+1. Jonathan Tron TalentBox 4/25/11
+1. Joseph Halter TalentBox 4/25/11
+1. Wilson Felipe Nunes Fernandes Pereira 4/27/11
+1. Michael Grubb 4/27/11
+1. Brandon Konkle 4/28/11
+1. Matt Griffin 4/28/11
+1. Anh K. Huynh 4/28/11
+1. Erik Frey Wavii 4/29/11
+1. Spike Gronim Wavii 4/29/11
+1. Ian MacLeod Wavii 4/29/11
+1. Guido Bartolucci Wavii 4/29/11
+1. Fletcher Nichol 5/3/11
+1. James Kane 7digital 5/4/11
+1. Paul Richards 7digital 5/4/11
+1. Alexis Le-Quoc Datadog 5/4/11
+1. Matthew Singleton Datadog 5/4/11
+1. Carlo Cabanilla Datadog 5/4/11
+1. Olivier Pomel Datadog 5/4/11
+1. Fabrice Ollivier Datadog 5/4/11
+1. Matt Griffin Viximo 5/10/11
+1. Chris Chiodo Viximo 5/10/11
+1. Adam Bell Viximo 5/10/11
+1. Sergio Rubio 5/10/11
+1. Elmer Rivera 5/10/11
+1. Andrea Campi ZephirWorks 5/11/11
+1. Andrea Carlo Granata ZephirWorks 5/11/11
+1. Marco Pierleoni ZephirWorks 5/11/11
+1. Pietro Giorgianni ZephirWorks 5/11/11
+1. Jesse Newland 5/11/11
+1. Greg Swallow 5/12/11
+1. Scott Jensen Dell 5/12/11
+1. Greg Althaus Dell 5/12/11
+1. Andi Abes Dell 5/12/11
+1. Rob Hirschfeld Dell 5/12/11
+1. Paul Webster Dell 5/12/11
+1. Mitchell Hashimoto 5/12/11
+1. Jamie van Dyke 5/17/11
+1. Vladimir Kozhukalov 5/18/11
+1. Nathan Butler Newsweek/Daily Beast Company 5/19/11
+1. Ken Garland Newsweek/Daily Beast Company 5/19/11
+1. Michael Yankovski WordStream 5/19/11
+1. Augusto Becciu 5/19/11
+1. Greg Albrecht 5/19/11
+1. Eric James Buth 5/24/11
+1. Dan Porter 5/24/11
+1. Adrian Silva Atalanta Systems 5/25/11
+1. Spike Morelli Atalanta Systems 5/25/11
+1. Paul Nicholson 5/27/11
+1. Mandi Walls 5/27/11
+1. Carl Perry DreamHost 5/29/11
+1. Greg Thornton 5/30/11
+1. Joseph Heck 6/1/11
+1. Charles Ray Johnson, Jr. 6/2/11
+1. Joseph Anthony Pasquale Holsten 6/5/11
+1. John Donagher 6/6/11
+1. David Fuhr Flagbit 6/14/11
+1. Jörg Weller Flagbit 6/14/11
+1. Marcel Cary 6/15/11
+1. Yedidya "Jay" Feldblum Applications Online 6/17/11
+1. Michael Contento 6/20/11
+1. Yogesh Pathade 6/22/11
+1. Gavin Sandie 6/25/11
+1. Bryan Horstmann-Allen 6/28/11
+1. Glenn Pratt 7/5/11
+1. Andrew Narkewicz Versapay 7/5/11
+1. Zachary Tomas Stevens 7/11/11
+1. Richard Gould 7/11/11
+1. Philip Cohen 7/15/11
+1. Christopher Michael McClimans 7/18/11
+1. Jason J.W. Williams 7/19/11
+1. Nuo Yan 7/21/11
+1. Jaroslaw Åšmiejczak 7/25/11
+1. Dimitri Aivaliotis Every Ware 7/25/11
+1. Eric Rochester 7/27/11
+1. Alex North-Keys Tippr 7/29/11
+1. Adam Knight Tippr 7/29/11
+1. Eugene Wood Ask.com 8/1/11
+1. Aron Bartling Ask.com 8/1/11
+1. Jack Francis Ask.com 8/1/11
+1. Richard Marshall Ask.com 8/1/11
+1. Mikola Kucharski Ask.com 8/1/11
+1. Rory Mitchell Ask.com 8/3/11
+1. Oskar Stolc Ask.com 8/3/11
+1. Jack (John) Roehrig Ask.com 8/3/11
+1. Paul Stahlke Ask.com 8/3/11
+1. Jorge Mazzei Ask.com 8/3/11
+1. Pakojo Samm Ask.com 8/3/11
+1. David Smith Ask.com 8/3/11
+1. Mike Adolphs 8/5/11
+1. Ernad Husremović bring.out doo Sarajevo 8/11/11
+1. Jasmin Beganović bring.out doo Sarajevo 8/11/11
+1. Saša Vranić bring.out doo Sarajevo 8/11/11
+1. Å ator Emir bring.out doo Sarajevo 8/11/11
+1. Jeremy Bingham Kos Media 8/15/11
+1. Michael Taras Kos Media 8/15/11
+1. Tomoyuki Sakurai reallyenglish.com 8/15/11
+1. Mitsuru Yoshida reallyenglish.com 8/15/11
+1. Avishai Ish-Shalom Fewbytes 8/18/11
+1. Or Cohen Fewbytes 8/18/11
+1. Domenico Delle Side 8/19/11
+1. Paul Morton Business Intelligence Associates 8/19/11
+1. Phil Austin Business Intelligence Associates 8/19/11
+1. Andrian Jardan 8/22/11
+1. Vladimir Girnet Tacit Knowledge 8/22/11
+1. Scott Askew Tacit Knowledge 8/22/11
+1. Emmett Finneran 8/26/11
+1. Arthur Gautier Zenexity 8/30/11
+1. Edward Middleton ClassDo 8/30/11
+1. Michael Pearson 8/31/11
+1. Nikolay Sturm 9/1/11
+1. Nathan Lloyd Smith 9/1/11
+1. Patrick Connolly Myplanet 9/2/11
+1. Yashar Rassoulli Myplanet 9/2/11
+1. James Walker Myplanet 9/2/11
+1. Chris Read 9/6/11
+1. Prashant Srivastava 9/7/11
+1. Brad Knowles ihiji 9/16/11
+1. Stuart Rench ihiji 9/16/11
+1. Michael Maniscalco ihiji 9/16/11
+1. Brian Cunnie 9/19/11
+1. Joseph F. Reynolds 9/20/11
+1. Gabriel McArthur 9/21/11
+1. David Keith Hudgins 9/21/11
+1. Paul MacDougall 9/23/11
+1. Bulat Shakirzyanov 9/23/11
+1. Jorge Eduardo Espada 9/28/11
+1. Eric Dennis 9/28/11
+1. Stuart Glenn 9/29/11
+1. Bryan Wilson Berry 10/4/11
+1. Christopher Sturm 10/5/11
+1. John Sumsion 10/12/11
+1. Steven Phung 10/13/11
+1. Claudio Cesar Sanchez Tejeda 10/14/11
+1. Igor Afonov 10/26/11
+1. Dan Buettner Port 80 Production, LLC 10/28/11
+1. Robby Grossman 10/31/11
+1. Alan Harper 11/1/11
+1. Juanje Ojeda 11/1/11
+1. Stephane Jourdan Green Alto 11/2/11
+1. Gregory Karekinian Green Alto 11/2/11
+1. Samuel Maftoul Green Alto 11/2/11
+1. Darrin Eden Heavy Water Software, Inc. 11/4/11
+1. Sean Escriva Heavy Water Software, Inc. 11/4/11
+1. Jake Davis Heavy Water Software, Inc. 11/4/11
+1. AJ Christensen Heavy Water Software, Inc. 11/4/11
+1. Michael Weinberg Heavy Water Software, Inc. 11/4/11
+1. Aaron Baer Heavy Water Software, Inc. 11/4/11
+1. Matthew Kanwisher 11/8/11
+1. Joshua McKenty 11/9/11
+1. Iulian-Corneliu Costan 11/11/11
+1. Daniel Oliver 11/14/11
+1. Adam Garside 11/15/11
+1. Ian Wolfcat Atha Wealthfront Inc. 11/15/11
+1. John Hitchings Wealthfront Inc. 11/15/11
+1. David Fortunato Wealthfront Inc. 11/15/11
+1. Julien Wetterwald Wealthfront Inc. 11/15/11
+1. Kevin Peterson Wealthfront Inc. 11/15/11
+1. Maksim Horbul 11/16/11
+1. Roberto Gaiser 11/16/11
+1. Robert Di Marco 11/17/11
+1. Victor Lowther Dell 11/17/11
+1. Jerry Chen 11/18/11
+1. Murali Raju 11/18/11
+1. Benjamin Smith 11/18/11
+1. Aaron Suggs Kickstarter, Inc. 11/18/11
+1. Lance Ivy Kickstarter, Inc. 11/18/11
+1. Cedric Howe Kickstarter, Inc. 11/18/11
+1. Tieg Zaharia Kickstarter, Inc. 11/18/11
+1. Teemu Matilainen Reaktor Innovations 11/22/11
+1. Dave Solbes Webtrends Inc 11/22/11
+1. Grant Hutchins 11/25/11
+1. Eric Saxby ModCloth 11/27/11
+1. Gabriel Evans 11/27/11
+1. Tim Smith Webtrends Inc 11/28/11
+1. Nathaniel Eliot Infochimps, Inc 11/28/11
+1. Adam Seever Infochimps, Inc 11/28/11
+1. Travis Dempsey Infochimps, Inc 11/28/11
+1. Dhruv Bansal Infochimps, Inc 11/28/11
+1. Andrew Kaczorek Cycle Computing, LLC 11/29/11
+1. Chris Chalfant Cycle Computing, LLC 11/29/11
+1. Dan Harris Cycle Computing, LLC 11/29/11
+1. Ian Alderman Cycle Computing, LLC 11/29/11
+1. Stephen Balukoff 11/30/11
+1. Kendrick Martin Webtrends Inc 12/1/11
+1. Adnan Wahab 12/3/11
+1. Alex Howells 12/4/11
+1. Cameron Johnston Needle, Inc. 12/5/11
+1. Justin Huff 12/8/11
+1. Ian Downes Ubalo, Inc 12/8/11
+1. Erik Hollensbe 12/9/11
+1. Karel Minarik 12/11/11
+1. Adam Greene SweetSpot Diabetes Care, Inc. 12/12/11
+1. Justin Schumacher SweetSpot Diabetes Care, Inc. 12/12/11
+1. Dan Root SweetSpot Diabetes Care, Inc. 12/12/11
+1. Paul Dowman 12/12/11
+1. Andrew Le 12/12/11
+1. Paul Welch 12/13/11
+1. Harlan Barnes 12/13/11
+1. Philip Kates Rackspace US, Inc 12/13/11
+1. Brandon Philips Rackspace US, Inc 12/13/11
+1. Paul Querna Rackspace US, Inc 12/13/11
+1. Arthur Pirogovski 12/13/11
+1. John Scott Sanders, Jr RideCharge, Inc 12/15/11
+1. Jamie Winsor Riot Games 12/15/11
+1. Josiah Kiehl Riot Games 12/15/11
+1. Jesse Howarth Riot Games 12/15/11
+1. Michael Matsuuara Riot Games 12/15/11
+1. Cliff Dickerson Riot Games 12/15/11
+1. Philip Gollucci RideCharge, Inc 12/15/11
+1. Radim Marek 12/17/11
+1. Hugo Fichter 12/19/11
+1. Chris Christensen 12/20/11
+1. Chet Luther 12/20/11
+1. Mark Luntzel 12/20/11
+1. Kevin Karwaski Fiksu 12/21/11
+1. David Calavera 12/22/11
+1. Michael Stillwell 12/23/11
+1. Aaron Bull Schaefer 12/28/11
+1. Max Rabin 1/3/12
+1. Michael Bradshaw WhitePages Inc. 1/3/12
+1. Michael Cook WhitePages Inc. 1/3/12
+1. Jack Foy WhitePages Inc. 1/3/12
+1. Devin Ben-Hur WhitePages Inc. 1/3/12
+1. Jeff Bellegarde WhitePages Inc. 1/3/12
+1. John Dyer 1/4/12
+1. Sam Marx 1/5/12
+1. Praveen Arimbrathodiyil 1/6/12
+1. Joshua Buysse 1/6/12
+1. Dale Hui 1/6/12
+1. Jesse Campbell 1/8/12
+1. Roberto Carlos Morano 1/9/12
+1. Miah Johnson Scribd, Inc. 1/10/12
+1. Ian Delahorne 1/12/12
+1. Mike Javorski Spoke Software 1/15/12
+1. Michael A. Fiedler 1/16/12
+1. Luis Bosque 1/16/12
+1. Qiming He 1/18/12
+1. Hector Castro 1/19/12
+1. Wade Warren Wikia 1/23/12
+1. Geoff Papilion Wikia 1/23/12
+1. Justin Ryan Wikia 1/23/12
+1. David King Xforty Technologies 1/25/12
+1. Christian Pearce Xforty Technologies 1/25/12
+1. Andrew Libby Xforty Technologies 1/25/12
+1. Joshua Hou 1/27/12
+1. Alice Kaerast 1/28/12
+1. Brett Hoerner 1/28/12
+1. Jon-Erik Schneiderhan 1/30/12
+1. Wes Morgan Democracy Works, Inc 1/30/12
+1. Ernie Brodeur 1/31/12
+1. Stephen Figgins 1/31/12
+1. Tal Rotbart 2/1/12
+1. Benjamin Lindsey 2/1/12
+1. Markus Schirp 2/1/12
+1. Tryn Mirell 2/2/12
+1. Hari Krishna Dara 2/7/12
+1. Andrew Grangaard 2/8/12
+1. Adam Mielke 2/8/12
+1. Andrew Allan 2/9/12
+1. Antonio Soares de Azevedo Terceiro 2/9/12
+1. Istvan Szukacs 2/9/12
+1. Brian Parker Pure Lake Software, Inc. 2/10/12
+1. Sean Porter 2/10/12
+1. William Carroll 2/12/12
+1. Paul Diaconescu Sveriges Television AB 2/14/12
+1. Jonas Eklof Sveriges Television AB 2/14/12
+1. Per Bjorn Sveriges Television AB 2/14/12
+1. Frank Hoffsumer Sveriges Television AB 2/14/12
+1. Samppa Kytomaki Reaktor Innovations 2/14/12
+1. Zuhaib Siddique Atlassian 2/14/12
+1. Andrew Robson Oxygen Cloud, Inc. 2/14/12
+1. Aaron Follette Oxygen Cloud, Inc. 2/14/12
+1. Erik Bakker 2/16/12
+1. David Golden 2/16/12
+1. Jacques Chester Robojar Pty Ltd 2/17/12
+1. Nicholas VINOT 2/18/12
+1. Matthew MacDonald-Wallace 2/19/12
+1. Andrew Gross 2/20/12
+1. Andrew Fecheyr Lippins 2/21/12
+1. Shoaib Kamil 2/21/12
+1. Martin Vidner 2/23/12
+1. Jake Ritorto ModCloth 2/23/12
+1. Seth Kingry ModCloth 2/23/12
+1. Manuel Gutierrez ModCloth 2/23/12
+1. Graham McMillan World Wide Web Hosting, LLC 2/24/12
+1. Nicholas Stielau 2/24/12
+1. McClain Looney 2/24/12
+1. Jim Meyer 2/29/12
+1. Trevor Orsztynowicz Joyent 2/29/12
+1. Kevin Chang Joyent 2/29/12
+1. Geoffery Nix ModCloth 3/1/12
+1. Roberto Sanchez ModCloth 3/1/12
+1. Dan Buch ModCloth 3/1/12
+1. Ziad Sawalha Rackspace 3/2/12
+1. Benedikt Böhm 3/4/12
+1. Steven Ivy Wallrazer, Inc. 3/4/12
+1. Krzysztof Wilczynski 3/5/12
+1. Elson Orlando Rodriguez 3/5/12
+1. Michael Schubert 3/5/12
+1. Douglas Thrift Rightscale 3/5/12
+1. Andrew Benz 3/6/12
+1. Yann Robin Youscribe 3/6/12
+1. Javier Frias 3/6/12
+1. Josh Miller Edmunds.com 3/6/12
+1. Moritz Winter 3/6/12
+1. Aaron Blythe Cerner Innovation, Inc. 3/8/12
+1. Kevin Shekleton Cerner Innovation, Inc. 3/8/12
+1. Josh Murphy Cerner Innovation, Inc. 3/8/12
+1. Bryan Baugher Cerner Innovation, Inc. 3/8/12
+1. Sachin Sagar Ra 3/8/12
+1. Tarik Jabri 3/8/12
+1. Michael W. Myers 3/10/12
+1. Marcus Cobden 3/11/12
+1. Coimbatore Sankarraman Shyam Sundar 3/12/13
+1. Chris Roberts Heavy Water Software, Inc. 3/13/12
+1. Justin Mazzi World Wide Web Hosting, LLC 3/13/12
+1. Joshua Priddle World Wide Web Hosting, LLC 3/13/12
+1. Paul Stengel World Wide Web Hosting, LLC 3/13/12
+1. Vince Stratful World Wide Web Hosting, LLC 3/13/12
+1. Artem Veremey 3/13/12
+1. Jon Cowie 3/15/12
+1. Philip Kromer Infochimps, Inc 3/17/12
+1. Ben Dean 3/18/12
+1. Zachary Cook 3/19/12
+1. Welby McRoberts 3/20/12
+1. Ian Coffey Voxel Dot Net, Inc 3/20/12
+1. David Amian Valle 3/21/12
+1. Lewis J. Goettner, III 3/21/12
+1. Bernardo Gomez Palacio 3/23/12
+1. Chris Gaffney 3/23/12
+1. Igor Kurochkin 3/24/12
+1. Oleksiy Kovyrin 3/24/12
+1. Jordan Dea-Mattson Numenta, Inc. 3/26/12
+1. Cody Ebberson Numenta, Inc. 3/27/12
+1. Martin Hasan Bramwell 3/28/12
+1. Mohammed Siddick 3/28/12
+1. Ira Abramaov Fewbytes 3/29/12
+1. Paul McCallick 3/29/12
+1. Jon-Paul Sullivan Hewlett-Packard 3/30/12
+1. Sascha Bates 3/30/12
+1. Julian Cardona Edmunds.com 4/2/12
+1. David Hudson Edmunds.com 4/2/12
+1. Andrew Crump Kotiri Software Ltd. 4/3/12
+1. Zach Dunn 4/5/12
+1. Logan Lowell The Frontside Software, Inc. 4/5/12
+1. Charles Lowell The Frontside Software, Inc. 4/5/12
+1. Chris Buben 4/5/12
+1. Joseph Brian Passavanti 4/5/12
+1. Denis Barishev 4/6/12
+1. Jonas Courteau 4/6/12
+1. Eric Hankins 4/10/12
+1. Chris Buben Gap, Inc. 4/10/12
+1. Oliver Fross Gap, Inc. 4/10/12
+1. Jeffery Padgett Gap, Inc. 4/10/12
+1. Philip Vieira 4/10/12
+1. Guilhem Lettron Youscribe 4/11/12
+1. Sebastien Balant Youscribe 4/11/12
+1. Robert E. Lewis 4/13/12
+1. David Joos 4/16/12
+1. Umang Chouhan 4/16/12
+1. Sören Blom Deutsche Telekom Laboratories 4/17/12
+1. Alex Redington Relevance, Inc. 4/20/12
+1. Gabriel Horner Relevance, Inc. 4/20/12
+1. Lake Denman Relevance, Inc. 4/20/12
+1. Larry Karnowski Relevance, Inc./Truer Sound LLC 4/20/12
+1. Sam Umbach Relevance, Inc./Truer Sound LLC 4/20/12
+1. Jeremiah Snapp Asbury Theological Seminary 4/20/12
+1. Brian Bianco 4/20/12
+1. Brandon Martin 4/21/12
+1. Alexander Gordeev 4/24/12
+1. Joe Miller 4/25/12
+1. Nick Peirson 4/27/12
+1. Marc Morata Fite 4/27/12
+1. Seth Thomas 4/27/12
+1. Chris Griego 4/28/12
+1. Dmytro Ilchenko 4/30/12
+1. Morgan Nelson 4/30/12
+1. Chirag Jog Websym Technologies Private Ltd. 4/30/12
+1. Kalpak Shah Websym Technologies Private Ltd. 4/30/12
+1. Mohit Sethi Websym Technologies Private Ltd. 4/30/12
+1. Kyle VanderBeek 5/2/12
+1. TANABE Ken-ichi 5/2/12
+1. Brandon Adams DreamBox Learning, Inc. 5/3/12
+1. Hui Hu 5/5/12
+1. Will Maier Simple 5/7/12
+1. Chris Brentano Simple 5/7/12
+1. Cosmin Stejerean Simple 5/7/12
+1. Brian Merritt Simple 5/7/12
+1. Pascal Deschenes 5/8/12
+1. Michael Glenn 5/8/12
+1. Dan Crosta 5/9/12
+1. Daniel Condomitti 5/9/12
+1. Matthew Butcher 5/10/12
+1. Ben Poweski Consumer Club, Inc. 5/10/12
+1. Chris Griego Consumer Club, Inc. 5/10/12
+1. Jim Hughes Consumer Club, Inc. 5/10/12
+1. Morgan Nelson Consumer Club, Inc. 5/10/12
+1. Kristina Rodgers Consumer Club, Inc. 5/10/12
+1. Derek Schultz 5/11/12
+1. Anay Nayak 5/15/12
+1. Patrick Ting 5/17/12
+1. Xabier de Zuazo Oteiza Onddo Labs 5/18/12
+1. Raul Rodriguez Munoz Onddo Labs 5/18/12
+1. Ramez Mourad 5/21/12
+1. Jonathan Manton 5/22/12
+1. Philipp Wollermann CyberAgent Corp. 5/22/12
+1. Koji Hasebe CyberAgent Corp. 5/22/12
+1. Jean-Daniel Bussy CyberAgent Corp. 5/22/12
+1. Yoshihisa Sakamoto CyberAgent Corp. 5/22/12
+1. Kohei Maeda CyberAgent Corp. 5/22/12
+1. Eric Edgar 5/23/12
+1. Rodolphe Blancho 5/23/12
+1. Kevin Nuckolls 5/24/12
+1. Michael Nygard Relevance, Inc. 5/29/12
+1. Martin Fenner 5/30/12
+1. Lukasz Kaniowski 5/31/12
+1. Brian Flad 5/31/12
+1. Justin Witrick Rackspace 6/1/12
+1. Nickalaus Willever 6/1/12
+1. Harold "Waldo" Grunenwald III 6/4/12
+1. Bjorn Albers 6/4/12
+1. Timothy Martin Potter 6/5/12
+1. Greg Fitzgerald 6/6/12
+1. Sebastian Wendel SourceIndex IT-Services 6/7/12
+1. Leif Madsen 6/7/12
+1. Jonathan del Strother 6/7/12
+1. Bernd Roth 6/8/12
+1. Madhurranjan Mohaan 6/11/12
+1. Seth Vargo 6/11/12
+1. Gregory Jones 6/12/12
+1. Joshua Brand 6/15/12
+1. David Stainton Scribd, Inc. 6/15/12
+1. Sriram Devadas 6/17/12
+1. Christopher Webber 6/17/12
+1. Raf Geens Civolution BV 6/18/12
+1. Greg Symons Drillinginfo 6/18/12
+1. Clark Archer Drillinginfo 6/18/12
+1. David Eddy 6/18/12
+1. Jonathan Hartman Rackspace 6/21/12
+1. Boyd Edward Hemphill 6/21/12
+1. Martha Greenberg 6/24/12
+1. Paul Meserve 6/25/12
+1. Michael H. Oshita 6/25/12
+1. James W. Brinkerhoff Voxel Dot Net, Inc 6/26/12
+1. Evan Vetere Voxel Dot Net, Inc 6/26/12
+1. Kris Beevers Voxel Dot Net, Inc 6/26/12
+1. Patrick Dowell Voxel Dot Net, Inc 6/26/12
+1. Zachary Voase 6/26/12
+1. Paul Guth The Cloudscaling Group, Inc. 6/27/12
+1. Rodolphe Pineau The Cloudscaling Group, Inc. 6/27/12
+1. Jeremy Deininger The Cloudscaling Group, Inc. 6/27/12
+1. Blake Barnett The Cloudscaling Group, Inc. 6/27/12
+1. HIGUCHI Daisuke Creationline, Inc. 6/27/12
+1. Jey Hotta Creationline, Inc. 6/27/12
+1. Kent R. Spillner 7/6/12
+1. Brian Dols 7/6/12
+1. Frank Rosquin 7/10/12
+1. Bill Moritz 7/10/12
+1. Alfred Rossi Action Verb, LLC 7/10/12
+1. Patrick Ribeiro Negri lugu Seervicos na Internet LTDA 7/11/12
+1. Marcelo Paez lugu Seervicos na Internet LTDA 7/11/12
+1. Alexandre Paez lugu Seervicos na Internet LTDA 7/11/12
+1. Wong Liang Zan 7/11/12
+1. Matthew Andersen 7/12/12
+1. Jacob Atzen 7/13/12
+1. Chris Parsons 7/13/12
+1. Timothy Jones 7/14/12
+1. Ameya Prakash Gangamwar 7/15/12
+1. Adrien Brault 7/16/12
+1. Michael T. Halligan 7/17/12
+1. Andreas Boehrnsen OpeniT 7/18/12
+1. Jay Levitt 7/20/12
+1. Jose Luis Fernandez Perez 7/21/12
+1. Aaron J. Peterson 7/22/12
+1. Jim Croft Cloudreach Limited 7/24/12
+1. Richard Bowden Cloudreach Limited 7/24/12
+1. Joe Geldart Cloudreach Limited 7/24/12
+1. Bryce Lynn Tacit Knowledge 7/24/12
+1. Brian Smith Bonnier Corporation 7/25/12
+1. Michael Linde Bonnier Corporation 7/25/12
+1. Peter Lauda Bonnier Corporation 7/25/12
+1. Rakesh Patel OneHealth Solutions, Inc. 7/25/12
+1. Jay Perry 7/26/12
+1. Mark Roddy 7/26/12
+1. Andrew Regan 7/26/12
+1. Takeshi Kondo 7/26/12
+1. Paul Rossman 7/26/12
+1. Bryan Stearns Paydici Corp. 7/26/12
+1. Jim Harvey Paydici Corp. 7/26/12
+1. Bill Burcham Paydici Corp. 7/26/12
+1. Steve Rude 7/26/12
+1. Richard Clamp 7/29/12
+1. Christopher Kelly 7/30/12
+1. Deepak Kannan 7/30/12
+1. Roy Liu 7/31/12
+1. Artiom Lunev 7/31/12
+1. Anna Marseille D. Gabutero 7/31/12
+1. Lucas Jandrew Riot Games 8/1/12
+1. Dafydd Crosby 8/1/12
+1. Christoph Thiel Novell, Inc. 8/1/12
+1. Ralf Haferkamp Novell, Inc. 8/1/12
+1. Adam Spiers Novell, Inc. 8/1/12
+1. Tim Serong Novell, Inc. 8/1/12
+1. Sascha Peilicke Novell, Inc. 8/1/12
+1. Bernhard Wiedemann Novell, Inc. 8/1/12
+1. Ionuts Artarisi Novell, Inc. 8/1/12
+1. Vincent Untz Novell, Inc. 8/1/12
+1. Martin Vidner Novell, Inc. 8/1/12
+1. J. Daniel Schmidt Novell, Inc. 8/1/12
+1. Stefan Fent Novell, Inc. 8/1/12
+1. Danny Kukawka Novell, Inc. 8/1/12
+1. Michal Vyskocil Novell, Inc. 8/1/12
+1. Kristian Vlaardingerbroek Schuberg Philis B.V. 8/3/12
+1. Jon Gretarsson RelatelIQ Inc. 8/3/12
+1. Danial Pearce 8/5/12
+1. Stathis Touloumis 8/5/12
+1. Matthew Scott Moyer 8/7/12
+1. Benedict Steele 8/7/12
+1. James Tan Novell, Inc. 8/7/12
+1. John Kip Larsen 8/8/12
+1. Chris Buryta 8/9/12
+1. Sahil Muthoo 8/10/12
+1. Kyle Goodwin PrimeRevenue, Inc 8/10/12
+1. Ben Rosenblum PrimeRevenue, Inc 8/10/12
+1. Aaron Kalin 8/10/12
+1. John Dewey 8/11/12
+1. Abel Lopez 8/13/12
+1. Lyndon Washington 8/14/12
+1. Ripal Nathuji Calxeda 8/14/12
+1. Gardner Bickford 8/15/12
+1. Nick Heppner 8/16/12
+1. Jeffrey Dutton 8/16/12
+1. Taklon Wu 8/17/12
+1. Craig Tracey 8/17/12
+1. Lee Jensen Big Cartel LLC 8/17/12
+1. Chris Cameron Big Cartel LLC 8/17/12
+1. Kelley Reynolds Big Cartel LLC 8/17/12
+1. Michael Wallman 8/17/12
+1. Edward Sargisson 8/19/12
+1. Winfield Peterson 8/20/12
+1. Mathew Davies 8/21/12
+1. Justin Shepherd Rackspace 8/21/12
+1. Jason Cannavale Rackspace 8/21/12
+1. Ron Pedde Rackspace 8/21/12
+1. Joseph Breu Rackspace 8/21/12
+1. William Kelly Rackspace 8/21/12
+1. Darren Birkett Rackspace 8/21/12
+1. Evan Callicoat Rackspace 8/21/12
+1. Andrew Ferk 8/23/12
+1. Shaun Hope 8/23/12
+1. Matt Kynaston 8/24/12
+1. Ben Marini 8/25/12
+1. Garret Heaton Atlassian 8/27/12
+1. Julian Dunn 8/27/12
+1. Jordan Evans 8/28/12
+1. Andrew Laski 8/31/12
+1. Mat Schaffer 8/31/12
+1. Elliot Pahl 9/3/12
+1. Richard Shade Rightscale 9/5/12
+1. Dmytro Kovalov 9/5/12
+1. Shishir Das 9/6/12
+1. Kimball Johnson One Connect Limited 9/7/12
+1. Roy Crombleholme One Connect Limited 9/7/12
+1. Martin Foster One Connect Limited 9/7/12
+1. Alex Klepa 9/7/12
+1. Brendan Hay 9/7/12
+1. Paul Graydon 9/7/12
+1. Steve Layland 9/7/12
+1. Thomas Dudziak 9/7/12
+1. Felix Sheng 9/8/12
+1. Sean Porter Sonian Inc 9/8/12
+1. Josh Pasqualetto Sonian Inc 9/8/12
+1. TJ Vanderpoel Sonian Inc 9/8/12
+1. Justin Kolberg Sonian Inc 9/8/12
+1. Decklin Foster Sonian Inc 9/8/12
+1. Randall Morse 9/10/12
+1. Pete Cheslock Dyn 9/10/12
+1. Max Stepanov 9/11/12
+1. Sean Gallagher 9/11/12
+1. Autif Khan 9/11/12
+1. Jacques Marneweck 9/12/12
+1. William Herry 9/16/12
+1. Pawel Kozlowski 9/16/12
+1. Lawrence Gilbert 9/18/12
+1. Bob Walker 9/18/12
+1. Nathan Schimke 9/18/12
+1. Graham Christensen 9/19/12
+1. Alessandro Dal Grande The App Business 9/19/12
+1. Saager Suhas Mhatre 9/23/12
+1. Charles J Blaine 9/23/12
+1. Andres de Barbara 9/23/12
+1. Adam Vinsh 9/25/12
+1. Elliot Murphy Pat Deegan, PhD & Associates, LLC 9/26/12
+1. John Nishinaga Pat Deegan, PhD & Associates, LLC 9/26/12
+1. Farley Knight Pat Deegan, PhD & Associates, LLC 9/26/12
+1. Jon Sime OmniTI 9/26/12
+1. Clinton Wolfe OmniTI 9/26/12
+1. Theo Schlossnagle OmniTI 9/26/12
+1. Robert Treat OmniTI 9/26/12
+1. Adam DePue 9/26/12
+1. Martin Contento 9/27/12
+1. Milos Gajdos 9/27/12
+1. Brad Gignac Rackspace 9/28/12
+1. Robert Allen 9/30/12
+1. Chia-liang Kao 10/1/12
+1. Ketan Padegaonkar 10/2/12
+1. Antti Puranen Reaktor Innovations 10/5/12
+1. Stephen Crawley 10/7/12
+1. Brad Bennet ZestFinance 10/8/12
+1. Alexander Tamoykin ZestFinance 10/8/12
+1. Lloyd Philbrook Firebelly Design 10/8/12
+1. Nate Beaty Firebelly Design 10/8/12
+1. John Skopis 10/8/12
+1. Susan Potter 10/8/12
+1. Jatinder Giri 10/10/12
+1. Joan Touzet Cloudant, Inc. 10/11/12
+1. Kyle Allan Riot Games 10/11/12
+1. Jay Pipes 10/12/12
+1. John Austin Page 10/15/12
+1. Chuck Ha 10/15/12
+1. David Dvorak Webtrends 10/15/12
+1. Dipen Lad 10/15/12
+1. Pascal Deschenes Nu Echo 10/16/12
+1. Matthieu Vachon Nu Echo 10/16/12
+1. Raymond Menard Nu Echo 10/16/12
+1. Jean-Francois Alix Nu Echo 10/16/12
+1. Mariano Cortesi 10/16/12
+1. Alexander Phan 10/16/12
+1. Jeff Siegel 10/16/12
+1. William Milton 10/17/12
+1. Mark Pimentel 10/18/12
+1. Mike Gifford OpenConcept 10/18/12
+1. Mike Mallett OpenConcept 10/18/12
+1. Brian Loomis 10/20/12
+1. Michael Saffitz Apptentive 10/20/12
+1. Andrew Wooster Apptentive 10/20/12
+1. Sky Kelsey Apptentive 10/20/12
+1. Benjamin Michael Atkin Document Swarm, LLC 10/20/12
+1. Andreas Gerauer 10/22/12
+1. Steven Deaton 10/22/12
+1. Cassiano Bertol Leal 10/23/12
+1. Matt Towers 10/23/12
+1. Mark Ayers 10/23/12
+1. Anthony Leto 10/23/12
+1. Marc Soda 10/24/12
+1. Jerome D Harrington, II 10/24/12
+1. Russell Stewart Egan 10/24/12
+1. Paul Thomas 10/24/12
+1. Chris Lundquist 10/24/12
+1. Anton Orel 10/25/12
+1. Marius Sturm 10/25/12
+1. Dimitri David Boelaert-Roche 10/25/12
+1. Matthew Serafin Horan 10/25/12
+1. Vojtech Hyza 10/25/12
+1. Steve Houser 10/26/12
+1. Dmitry Zamaruev 10/29/12
+1. James Hu 10/29/12
+1. Laust Rud Jacobsen 10/29/12
+1. Zo Obradovic 10/29/12
+1. Dale Kiefling 10/29/12
+1. Todd Fleisher 10/29/12
+1. Karl Freeman 10/30/12
+1. Johannes Becker 10/30/12
+1. Fred Sadaghiani Sift Science, Inc. 10/31/12
+1. Jeff Thompson 10/31/12
+1. Stanislav Bogatyrev 10/31/12
+1. Jonathan Peck FluxSauce 11/1/12
+1. Jeffrey Borg 11/1/12
+1. Guido Serra Rocket Internet GmbH 11/2/12
+1. Sebastian Grewe 11/3/12
+1. Chaoran Xie 11/3/12
+1. Julien Duponchelle 11/4/12
+1. Trae Robrock 11/5/12
+1. Nikita Borzykh 11/6/12
+1. Ilya Sher 11/6/12
+1. Michael Fischer 11/6/12
+1. Nathan Baxter 11/6/12
+1. Simon Belluzzo 11/6/12
+1. Ben Hartshorne 11/9/12
+1. Matt Whiteley Engine Yard 11/9/12
+1. Raul Naveiras 11/13/12
+1. Eugene Wood 11/13/12
+1. Javier Perez-Griffo Tapp 11/13/12
+1. Dang Nguyen 11/13/12
+1. Pablo Banos Tapp 11/13/12
+1. Christian Hofer Tapp 11/13/12
+1. Matthew Rogers 11/13/12
+1. Stephen Lauck 11/13/12
+1. Mark Van de Vyver Taqtiqa LLC 11/14/12
+1. Thomas Carroll 11/14/12
+1. Jon DeCamp Nordstrom, Inc 11/15/12
+1. Doug Ireton Nordstrom, Inc 11/15/12
+1. Kevin Moser Nordstrom, Inc 11/15/12
+1. Justin Schumacher Nordstrom, Inc 11/15/12
+1. Rob Cummings Nordstrom, Inc 11/15/12
+1. Brandon Burton 11/20/12
+1. Christopher Ferry 11/20/12
+1. Michael Hood 11/22/12
+1. Gavin Montague 11/23/12
+1. Michal Lomnicki 11/24/12
+1. Doc Walker 11/24/12
+1. Nicolas Szalay 11/26/12
+1. Terry Carr 11/26/12
+1. Michael Myers Daptiv Solutions LLC 11/26/12
+1. Shawn Neal Daptiv Solutions LLC 11/26/12
+1. Chris Bobo Daptiv Solutions LLC 11/26/12
+1. Ian Gantt Daptiv Solutions LLC 11/26/12
+1. Alan Gray Daptiv Solutions LLC 11/26/12
+1. Kishore Kumar S 11/26/12
+1. Vincent Leraitre 11/27/12
+1. Samuel Gerstein 11/27/12
+1. John T Skarbek 11/27/12
+1. Paul A Jungwirth 11/28/12
+1. Thomas Hodder Lime Pepper Ltd 11/28/12
+1. Warren Vosper Straydog Software, Inc. 11/29/12
+1. Joshua Reedy 11/30/12
+1. Mehmet Ali Akmanalp 11/30/12
+1. Panagiotis Papadomitsos 11/30/12
+1. Allan Espinosa 11/30/12
+1. Brian Pitts 12/1/12
+1. Elliot Kendall 12/3/12
+1. Nathan Mische 12/3/12
+1. Matthew Turney 12/3/12
+1. Jay Flowers 12/4/12
+1. Loic Antoine-Gombeaud 12/5/12
+1. Joe Rodriguez 12/5/12
+1. Kyle Scarmardo Fidelity Technology Group, LLC 12/6/12
+1. Jon Lenzer Fidelity Technology Group, LLC 12/6/12
+1. Chaoran Xie Fidelity Technology Group, LLC 12/6/12
+1. Shalon Wood Fidelity Technology Group, LLC 12/6/12
+1. David Crane 12/6/12
+1. Takumi IINO 12/9/12
+1. Tolleiv Nietsch 12/9/12
+1. Benoit Caron 12/9/12
+1. Mathieu Martin 12/10/12
+1. Yung Giang 12/11/12
+1. Fabian Ruff 12/11/12
+1. Takeshi KOMIYA 12/11/12
+1. Rafael Fonseca 12/12/12
+1. Justin Campbell 12/12/12
+1. Andrey Subbota 12/13/12
+1. Jacob Ritorto 12/13/12
+1. Pierre Ozoux 12/14/12
+1. Shoaib Mushtaq 12/16/12
+1. Arnold Krille bcs kommunikationslosungen 12/17/12
+1. Rainer Dietz bcs kommunikationslosungen 12/17/12
+1. Paul Diaconescu 12/17/12
+1. Jake Davis Simple 12/17/12
+1. Mike Ehlert Simple 12/17/12
+1. Kevin Bringard 12/19/12
+1. David Whittington 12/20/12
+1. Raphael Valyi 12/20/12
+1. Michael Klapper 12/23/12
+1. Eli Klein 12/24/12
+1. Andrew Lawrence Burns 12/26/12
+1. Kevin Keane North County Tech Center, LLC 12/26/12
+1. David Petzel 12/28/12
+1. Thomas Robison 12/28/12
+1. Keenan Brock 12/28/12
+1. Stefan Borsje 12/29/12
+1. Jon Galentine 12/29/12
+1. Kiesia Croucher 12/31/12
+1. Deeba Siddiqi 1/2/13
+1. Steven De Coeyer 1/2/13
+1. Yoni Yalovitsky Fewbytes 1/2/13
+1. Alex Kiernan 1/3/13
+1. Gilles Cornu 1/4/13
+1. Gavin Mogan 1/4/13
+1. Steven Lehrburger 1/4/13
+1. Jordi Llonch 1/6/13
+1. Nicolas Rycar 1/7/13
+1. Andrew McCloud 1/7/13
+1. Gregoire Seux Criteo 1/8/13
+1. Brian Scott Emergent One 1/9/13
+1. Mike Taczak Emergent One 1/9/13
+1. Javier Segura Martinez 1/9/13
+1. Warren Bain Ninefold Pty Limited 1/9/13
+1. Shaun Domingo Ninefold Pty Limited 1/9/13
+1. Toby Hede Ninefold Pty Limited 1/9/13
+1. Paul Handly DecisionDesk 1/13/13
+1. Eric Neuman DecisionDesk 1/13/13
+1. Will Olbrys DecisionDesk 1/13/13
+1. Thomas Bouve 1/14/13
+1. Kevin Reedy Belly Inc 1/15/13
+1. Craig Ulliott Belly Inc 1/15/13
+1. Jay OConnor Belly Inc 1/15/13
+1. Courtenay Gasking 1/16/13
+1. James Dabbs 1/16/13
+1. Jerry Cattell 1/16/13
+1. Jon Webb 1/17/13
+1. Hendrik Volkmer cloudbau Gmbh 1/18/13
+1. Thomas Kadauke cloudbau Gmbh 1/18/13
+1. Martin Bosner cloudbau Gmbh 1/18/13
+1. Christopher Laco 1/18/13
+1. Haggai Philip Zagury 1/19/13
+1. Eric Sigler 1/20/13
+1. Yves Vogl 1/21/13
+1. Yukihiko Sawanobori HiganWorks LLC 1/21/13
+1. Seth Larson 1/21/13
+1. Ben Langeld 1/21/13
+1. Dan Midwood 1/22/13
+1. Peter Pouliot 1/22/13
+1. Alexander Bondarev 1/23/13
+1. Ben Dean Ontario Systems 1/23/13
+1. Keith Shook Ontario Systems 1/23/13
+1. Lucas Heinlen Ontario Systems 1/23/13
+1. Kyle Michel Ontario Systems 1/23/13
+1. Brice Oliver Ontario Systems 1/23/13
+1. David Rogers Lytro, Inc. 1/23/13
+1. Alvin Lai Lytro, Inc. 1/23/13
+1. Anuj Biyani Lytro, Inc. 1/23/13
+1. Tiffany Russo Lytro, Inc. 1/23/13
+1. Craig Brunner Lytro, Inc. 1/23/13
+1. Mugur Marculescu Lytro, Inc. 1/23/13
+1. Tom Hanley Lytro, Inc. 1/23/13
+1. Thomas Massmann 1/25/13
+1. Ankit Shah 1/25/13
+1. Josh Mahowald 1/25/13
+1. Christopher Bandy 1/25/13
+1. Mal Graty 1/27/13
+1. Vaidas Jablonskis 1/27/13
+1. Simon McCartney 1/28/13
+1. Jake Davis 1/29/13
+1. Sean Kilgore 1/29/13
+1. Scott Lampert 1/29/13
+1. Michael Frick 1/29/13
+1. Kevin Duane 1/30/13
+1. Ryan Geyer 1/30/13
+1. George Hafiz 1/30/13
+1. Eric Pardee Atlas Digital, LLC 1/30/13
+1. Jaroslaw Zmudzinski Grupa Allegro Sp. z o.o. 1/31/13
+1. Alexey Polovinkin 2/1/13
+1. Malte Swart 2/2/13
+1. Jon Burgess 2/3/13
+1. Daniel Hahn 2/4/13
+1. Maxime Brugidou Criteo 2/4/13
+1. Gareth David Rushgrove 2/4/13
+1. Michael Conigliaro 2/4/13
+1. James Kessler 2/4/13
+1. Lukasz Jagiello 2/4/13
+1. Mischa Taylor 2/4/13
+1. Mervyn Hammer Workday Inc. 2/5/13
+1. David Radcliffe 2/5/13
+1. Alexander Titov 2/5/13
+1. Buntaro OKADA 2/5/13
+1. Alexey Kalinin 2/5/13
+1. Adam Cownoble 2/6/13
+1. Josh Behrends Webtrends 2/6/13
+1. Mark Shlimovich 2/6/13
+1. Jahn Bertsch 2/7/13
+1. Sergio Rodriguez 2/7/13
+1. Timur Batyrshin 2/8/13
+1. Samuel Cooper 2/8/13
+1. Ignacy Kasperowicz 2/8/13
+1. Ranjib Dey 2/8/13
+1. Kirill Kouznetsov 2/8/13
+1. Jordan Hagan 2/8/13
+1. Alexander Coles 2/9/13
+1. Michael Grosser 2/10/13
+1. Michael Goetz 2/11/13
+1. Patrick Humpal 2/11/13
+1. Nate Smith 2/13/13
+1. Martin Eigenbrodt 2/13/13
+1. Russell Cloran 2/13/13
+1. John Gabriel McArthur 2/13/13
+1. Jessica Bourne 2/13/13
+1. Darren Haken 2/14/13
+1. Rick Polk 2/14/13
+1. Eric Berg 2/14/13
+1. Andrew Williams Intoximeters 2/15/13
+1. Matthew Follett Intoximeters 2/15/13
+1. Brendan O'Donnell 2/16/13
+1. Igor Serebryany Airbnb 2/17/13
+1. Lukas Reinfurt 2/17/13
+1. Adam Gross 2/17/13
+1. Giorgio Valoti 2/19/13
+1. Nathan Beyer Cerner Corporation 2/19/13
+1. Patrik Stenmark Valtech AB 2/20/13
+1. Evgeny Zislis 2/20/13
+1. Luyi Wang 2/20/13
+1. Jason Schadel AWeber Communications 2/20/13
+1. David Kinzer 2/22/13
+1. Achim Rosenhagen 2/23/13
+1. Doug Cole 2/23/13
+1. Matthew Wright 2/25/13
+1. Jasper Lievisse Adriaanse 2/25/13
+1. Julien Vehent AWeber Communications 2/25/13
+1. Ryan Steele AWeber Communications 2/25/13
+1. Brian K. Jones AWeber Communications 2/25/13
+1. Benjamin Krein AWeber Communications 2/25/13
+1. Cliff Erson 2/26/13
+1. Booker Bense 2/27/13
+1. Charity Majors 2/27/13
+1. Jared Russell 2/27/13
+1. Iiro Uusitalo 2/27/13
+1. Ryan Walker Rackspace 2/28/13
+1. Todd Bushnell 2/28/13
+1. BK Box 2/28/13
+1. Scott Stout 3/1/13
+1. Steffen Gebert 3/3/13
+1. John Cheng 3/3/13
+1. Jeremy Olliver 3/3/13
+1. Alexander Papaspyrou adesso mobile solutions GmbH 3/4/13
+1. Stoyan Stoyanov adesso mobile solutions GmbH 3/4/13
+1. Andreas Thielen adesso mobile solutions GmbH 3/4/13
+1. Yves Vogl adesso mobile solutions GmbH 3/4/13
+1. Brett Richardson 3/5/13
+1. Kevin Nuckolls Banno, LLC 3/5/13
+1. Nic Grayson Banno, LLC 3/5/13
+1. Luke Amdor Banno, LLC 3/5/13
+1. Danny Lockard Banno, LLC 3/5/13
+1. Thomas Wallace 3/5/13
+1. Ptah Dunbar 3/6/13
+1. Jonathan Asghar 3/6/13
+1. Brandon Sanders AboutUs 3/7/13
+1. Aaron Brown 3/7/13
+1. Paul Oliver 3/7/13
+1. Alan Willis Riot Games 3/7/13
+1. Dimitrios Verraros 3/8/13
+1. Arangamanikkannan Manickam 3/8/13
+1. David Bresnick 3/8/13
+1. Brett Weaver 3/8/13
+1. Drew Flower 3/8/13
+1. Charles Gregory Willis 3/8/13
+1. Owain Perry 3/9/13
+1. Alexander Sakharchuk 3/9/13
+1. Ameir Abdeldayem 3/9/13
+1. Robert Choi 3/10/13
+1. Gemini Agalo-os 3/10/13
+1. Alexander Galato 3/11/13
+1. Gabriel Klein 3/11/13
+1. Eric Richardson 3/12/13
+1. Steven Barre 3/13/13
+1. Paul Rossman Google, Inc 3/14/13
+1. Riccardo Carlesso Google, Inc 3/14/13
+1. Benson Kalahar Google, Inc 3/14/13
+1. Rick Wright Google, Inc 3/14/13
+1. Eric Johnson Google, Inc 3/14/13
+1. Aaron Rice 3/15/13
+1. Radoslaw Gruchalski 3/15/13
+1. Matt Gleeson Atlassian 3/18/13
+1. Will DeHaan Atlassian 3/18/13
+1. Gabor Nagy 3/18/13
+1. Bryan Stearns 3/18/13
+1. Jose Diaz-Gonzalez 3/19/13
+1. Jean-Francois Theroux 3/19/13
+1. Christopher Stolfi 3/19/13
+1. Darrell Nash 3/19/13
+1. Sean Kane 3/20/13
+1. Patrick Leckey 3/20/13
+1. Michael Rose 3/20/13
+1. Pitr Vernigorov 3/20/13
+1. Capen Brinkley 3/20/13
+1. Tima Maslyuchenko 3/21/13
+1. Yvo van Doorn 3/21/13
+1. Tobias Wilken cloudControl GmbH 3/21/13
+1. Mateusz Korszun cloudControl GmbH 3/21/13
+1. Eric Chaves 3/21/13
+1. Peter Donald 3/21/13
+1. Remon Oldenbeuving 3/22/13
+1. Philip Cristiano 3/22/13
+1. Chris Streeter 3/24/13
+1. Kenneth Vetergaard 3/25/13
+1. Gert Kremer 3/25/13
+1. Peter de Rujiter Springest 3/25/13
+1. Maarten Hoogendoorn Springest 3/25/13
+1. Daniel Ryan 3/25/13
+1. Matthieu Launay Criteo 3/26/13
+1. Jean-Baptiste Note Criteo 3/26/13
+1. Daniel Koepke 3/26/13
+1. Neil Schelly Dyn, Inc. 3/26/13
+1. David Miller Dyn, Inc. 3/26/13
+1. Bill Young Dyn, Inc. 3/26/13
+1. Phillip Goldenburg 3/27/13
+1. Faiz Kazi 3/31/13
+1. James Tucker Google, Inc 4/1/13
+1. Marco Delaurenti Google, Inc 4/1/13
+1. Sebastien Roccaserra 4/4/13
+1. Chendil Kumar Manoharan 4/4/13
+1. Jeremy Mauro Criteo 4/5/13
+1. Joshua Levine 4/5/13
+1. Harley Alaniz Lookout, Inc. 4/6/13
+1. Hiroaki Nakamura 4/8/13
+1. Leif Madsen Thinking Phone Networks, Inc. 4/8/13
+1. Chris Sibbitt Thinking Phone Networks, Inc. 4/8/13
+1. Christian Brideau Thinking Phone Networks, Inc. 4/8/13
+1. Travis Hein Thinking Phone Networks, Inc. 4/8/13
+1. Ming Chan 4/8/13
+1. Jamie Alessio 4/9/13
+1. Daichi Kamemoto 4/10/13
+1. David Groulx 4/10/13
+1. TAKEUCHI Go 4/11/13
+1. Alex Dergachev Evolving Web Inc 4/11/13
+1. Suzanne Kennedy Evolving Web Inc 4/11/13
+1. Sander Botman 4/15/13
+1. Julio Arias 4/15/13
+1. Alexander Wenzowski 4/16/13
+1. Pete Bristow 4/16/13
+1. Thorsten Klein 4/16/13
+1. Qingkun Liu 4/17/13
+1. Jonathan Cobb Tout Industries 4/18/13
+1. Matt Lanier Tout Industries 4/18/13
+1. Felix Roeser Tout Industries 4/18/13
+1. Tom Hallett Tout Industries 4/18/13
+1. Sam Gipe Tout Industries 4/18/13
+1. Brandon Turner 4/20/13
+1. Mathias Lafeldt 4/20/13
+1. Matt Bower 4/21/13
+1. Zachary Patten Lookout, Inc. 4/22/13
+1. Jim Hopp Lookout, Inc. 4/22/13
+1. Zsolt Dollenstein 4/23/13
+1. Andrew Hollingsworth 4/24/13
+1. Benjamin Krueger 4/24/13
+1. Matt Thompson Rackspace 4/25/13
+1. Hugh Saunders Rackspace 4/25/13
+1. Harry Harrington Rackspace 4/25/13
+1. Andy McCrae Rackspace 4/25/13
+1. Chris Laco Rackspace 4/25/13
+1. Bett Campbell Rackspace 4/25/13
+1. Zack Feldstein Rackspace 4/25/13
+1. Drew Rothstein 4/26/13
+1. Gaetano Santonastaso 4/26/13
+1. Tom Molin 4/26/13
+1. James Thompson 4/26/13
+1. Adam Stegman 4/26/13
+1. Robert Rehberg 4/26/13
+1. Amy Marco 4/27/13
+1. Chris Fordham 4/28/13
+1. Paolo Negri 4/29/13
+1. Jeremy Katz 4/29/13
+1. Troy Ready 4/30/13
+1. Jameson Lee 4/30/13
+1. Mehdi Lahmam 5/1/13
+1. Chandrashekar Seenappa 5/1/13
+1. Sander van Harmelen Schuberg Philis 5/1/13
+1. Matthew Hooker Simple 5/1/13
+1. Robert Roose 5/1/13
+1. Peter Jihoon Kim Irrational Industries 5/1/13
+1. Daniel Dao Quang Ming Irrational Industries 5/1/13
+1. Arun K Thampi Irrational Industries 5/1/13
+1. Paul Paradise Socrata, Inc 5/1/13
+1. Chris Armstrong Socrata, Inc 5/1/13
+1. David Chadwick Gibbons 5/1/13
+1. Chulki Lee Aspera, Inc 5/1/13
+1. Christopher Markle Aspera, Inc 5/1/13
+1. Jason Rutherford 5/1/13
+1. Peter Norton 5/2/13
+1. Walter Dal Mut 5/2/13
+1. Eric Sorenson 5/2/13
+1. Derrick Bryant 5/3/13
+1. Avrohom Katz 5/3/13
+1. Robert Postill 5/3/13
+1. Gabe Mulley Hadapt, Inc 5/3/13
+1. Daniel Schauenberg 5/4/13
+1. James Turnbull 5/6/13
+1. Seren Thompson 5/7/13
+1. Solvi Pall Asgeirsson 5/7/13
+1. Dale Ragan Moncai 5/7/13
+1. Eric Blevins Moncai 5/7/13
+1. Kevin Landreth 5/8/13
+1. Ka-Wing Tam 5/10/13
+1. John Bellone Jr. 5/10/13
+1. Paolo Agostinetto 5/11/13
+1. Robert Coleman 5/11/13
+1. Ahmad Jemai 5/13/13
+1. Manuel Ryan 5/13/13
+1. Ben Somers 5/13/13
+1. Nate Fox 5/13/13
+1. Simon Coffey 5/14/13
+1. Andrea Bernardo Ciddio 5/14/13
+1. Maxim Doucet 5/14/13
+1. Martin Klein 5/14/13
+1. Jeremiah Wuenschel Yahoo Inc. 5/14/13
+1. Deven Panchal Yahoo Inc. 5/14/13
+1. Jeff Parrish Yahoo Inc. 5/14/13
+1. Venkat Venkataraju Yahoo Inc. 5/14/13
+1. Chris Wing Yahoo Inc. 5/14/13
+1. Ittai Shadmon Yahoo Inc. 5/14/13
+1. Itsik Figenblat Yahoo Inc. 5/14/13
+1. Matthew Mencel 5/14/13
+1. Olaf Heydorn 5/16/13
+1. Bryan Stenson 5/16/13
+1. Holger Protzek 5/16/13
+1. Nilesh Bairagi 5/16/13
+1. Matt Clark 5/16/13
+1. Jan Nikolai Trzeszkowski 5/17/13
+1. Bernhard K. Weisshuhn 5/17/13
+1. Chris Reid 5/17/13
+1. Morgan Blackthorne 5/20/13
+1. Ken Miles 5/20/13
+1. James "Jim" Rosser, IV Texas A&M University College of Architecture 5/20/13
+1. Derek Groh Texas A&M University College of Architecture 5/20/13
+1. Benjamin Liles Texas A&M University College of Architecture 5/20/13
+1. Kyle Morgan Rackspace 5/20/13
+1. Wilfred Hughes 5/21/13
+1. Jeff Anderson 5/21/13
+1. Brian Hatfield 5/21/13
+1. Guillermo Carrasco Hernandez 5/21/13
+1. James Sulinksi MoPub 5/21/13
+1. Haydn Dufrene MoPub 5/21/13
+1. Rob McQueen MoPub 5/21/13
+1. Chris Snook MoPub 5/21/13
+1. Christophe Arguel 5/22/13
+1. Sean Nolen 5/22/13
+1. Chetan Sarva 5/24/13
+1. Justin Ryan Onelogin, Inc 5/24/13
+1. Stephen Touset Onelogin, Inc 5/24/13
+1. Marcelo Serpa Onelogin, Inc 5/24/13
+1. Nelson Enzo Onelogin, Inc 5/24/13
+1. Elan Ruusamäe 5/24/13
+1. Marco Betti 5/26/13
+1. Jonathan Hitchcock Yola 5/27/13
+1. Stefano Rivera Yola 5/27/13
+1. Adrian Moisey Yola 5/28/13
+1. Doug Beck Yola 5/28/13
+1. John Tran 5/28/13
+1. Jesse Ahrens CopperEgg 5/28/13
+1. Ross Dickey CopperEgg 5/28/13
+1. Scott Johnson CopperEgg 5/28/13
+1. Eric Anderson CopperEgg 5/28/13
+1. Benjamin Bytheway 5/28/13
+1. Tehmasp Chaudhri 5/28/13
+1. Russell Teabeault 5/28/13
+1. Tim Ray 5/29/13
+1. Gavin Roy MeetMe, Inc 5/30/13
+1. Peter Eisentraut MeetMe, Inc 5/30/13
+1. Jennifer Fountain MeetMe, Inc 5/30/13
+1. Kenny Furguson MeetMe, Inc 5/30/13
+1. Michael Glaesemann MeetMe, Inc 5/30/13
+1. Edward Robinson 6/1/13
+1. Baldur Gudbjornsson 6/1/13
+1. Jeffrey Jones 6/1/13
+1. Louis-Philippe Perron 6/5/13
+1. Victor Sollerhed 6/5/13
+1. Alvin Yik-ning Liang 6/5/13
+1. Cassiano Morgado de Aquino 6/5/13
+1. Brett Graves 6/6/13
+1. Mattew Collinge 6/6/13
+1. Nick Silkey Rackspace 6/6/13
+1. Chris Stephan 6/6/13
+1. Peter Fern 6/6/13
+1. Kevin Bridges 6/6/13
+1. Peter Halliday 6/7/13
+1. Felix Bunemann 6/9/13
+1. Nanuk Krinner 6/10/13
+1. Robert Dyer 6/10/13
+1. Anthony Scalisi 6/11/13
+1. Ryan Hass 6/11/13
+1. Brad Beam 6/12/13
+1. Ean Rollings 6/13/13
+1. Ken Robertson 6/13/13
+1. Tony Chong 6/13/13
+1. Oliver Nicolaas Ponder 6/14/13
+1. Mikhail Kolesnik 6/16/13
+1. Sergey Khaladzinksi 6/16/13
+1. Tucker DeWitt 6/16/13
+1. Thomas Meeus 6/17/13
+1. Lin Lin 6/17/13
+1. Omar Vargas 6/17/13
+1. Domonkos Tomcsanyi Boadree Innovations Kft. 6/17/13
+1. Prashant Nadarajan 6/18/13
+1. Eohyung Lee 6/18/13
+1. David Albrecht 6/18/13
+1. Nicholas Downs 6/19/13
+1. Mike Devine 6/19/13
+1. Thomas Cate Rackspace 6/18/13
+1. Ryan Richard Rackspace 6/18/13
+1. Matthew Thode Rackspace 6/18/13
+1. Chris Aumann 6/20/13
+1. Eric Wunderlin 6/21/13
+1. Georgi Markov 6/21/13
+1. Sjoerd Mulder 6/21/13
+1. Benjamin Knauss 6/21/13
+1. Erik Gustavson Bitium, Inc 6/21/13
+1. Prashant Nadarajan Bitium, Inc 6/21/13
+1. Walter Schiessberg 6/24/13
+1. Vasily Mikhaylichenko 6/24/13
+1. William Anthony Rhodes Jr 6/24/13
+1. Adam Wayne 6/24/13
+1. Max Manders Cloudreach 6/24/13
+1. Justin Stallard 6/25/13
+1. Nelson Chen 6/26/13
+1. Eric Sproul OmniTI 6/19/13
+1. Andrew Macgregor 6/27/13
+1. Jeffrey Damick 6/26/13
+1. Daniel Williams 6/27/13
+1. Bruce Li 6/27/13
+1. Satoshi Akama 6/28/13
+1. Dave Stern 6/28/13
+1. David Andrew 6/28/13
+1. Anthony Burns 6/29/13
+1. Michael Ballantyne 6/28/13
+1. Ewan McDougall 7/1/13
+1. Matt Patterson 7/1/13
+1. Ivan Puzyrevskiy 7/2/13
+1. Stefano Tortarolo 7/3/13
+1. Christopher MacNaughton 7/3/13
+1. Skye Book 7/3/13
+1. Mark Butcher 7/4/13
+1. Nick Morgan Heart of Sales LLC DBA Ace of Sales 7/4/13
+1. Ryan Schlesinger Heart of Sales LLC DBA Ace of Sales 7/4/13
+1. Kevin Patrick Pullin II 7/5/13
+1. Colin Woodcock NetSrv Consulting Ltd 7/7/13
+1. Joshua Tobin 7/8/13
+1. James Cuzella 7/8/13
+1. Michael John Huot Jr. 7/9/13
+1. William Albenzi 7/9/13
+1. Matas Veitas 7/10/13
+1. NagaLakshmi N 7/10/13
+1. Evan Michael Kinney 7/11/13
+1. Adam Lane 7/11/13
+1. Rafael Colton 7/11/13
+1. Julien Phalip 7/11/13
+1. Matthew Savage 7/11/13
+1. Koseki Kengo 7/11/13
+1. Gregory Palmier 7/12/13
+1. Alain O'Dea 7/12/13
+1. Peter Hoellig PROS, Inc. a Delaware Corporation 7/12/13
+1. Vladimir Skubriev 7/12/13
+1. Ryan Stephens AURIN Project -Faculty of Architecture, Building and Planning 7/12/13
+1. Martin Tomko AURIN Project -Faculty of Architecture, Building and Planning 7/12/13
+1. Christopher Bayliss AURIN Project -Faculty of Architecture, Building and Planning 7/12/13
+1. Peter Ellingsen AURIN Project -Faculty of Architecture, Building and Planning 7/12/13
+1. Chris Pettit AURIN Project -Faculty of Architecture, Building and Planning 7/12/13
+1. Jörg Thalheim 7/12/13
+1. Zac Hallett 7/12/13
+1. Emanuele Zattin 7/11/13
+1. Daniel Steen 7/12/13
+1. Ronnie Taylor 7/13/13
+1. Danny Guinther 7/14/13
+1. Michael Vitale 7/16/13
+1. Nicholas Ethier 7/16/13
+1. Steve Poe Onlife Health Inc 7/17/13
+1. Craig Menning 7/17/13
+1. Antoni Baranski Roblox Inc. 7/17/13
+1. John Landahl 7/18/13
+1. Rudy Grigar 7/19/13
+1. Katsuma Ito 7/19/13
+1. Andrew Wyatt Onlife Health Inc 7/19/13
+1. Naoki AINOYA 7/21/13
+1. David Giesberg 7/21/13
+1. Luke Hoschke 7/21/13
+1. Myles Steinhauser 7/22/13
+1. Kyle Rames Rackspace 7/23/13
+1. Chris Snell Rackspace 7/23/13
+1. Jason Roelofs 7/23/13
+1. Hugo Trippaers 7/24/13
+1. Mark Friedgan 7/24/13
+1. Matthew Hopkins 7/24/13
+1. Eddie Zaneski 7/24/13
+1. Maxwell Robett Dietz 7/24/13
+1. Simon Robson 7/25/13
+1. Dan Bachelder 7/26/13
+1. Matthew Farmer 7/26/13
+1. Thomas Neal Cravey 7/26/13
+1. Ross Timson 7/29/13
+1. Donald Stufft 7/28/13
+1. Gilles Cornu 7/28/13
+1. Kenichi Saita 7/28/13
+1. Ivan Tanev 7/27/13
+1. Chris Gallimore 7/26/13
+1. Sonny Garcia 7/26/13
+1. Alexis Midon 7/26/13
+1. Brandon Henry 7/29/13
+1. Jordan Wesolowski 7/29/13
+1. Christopher Brinley 7/29/13
+1. Nimesh Subramanian Cerner 7/29/13
+1. Eric Hartmann 7/29/13
+1. Kevin Rochford 7/30/13
+1. Jon San Miguel 7/30/13
+1. Tommy Fotak 7/31/13
+1. Nicholas Hatch 8/1/13
+1. Raf Geens 8/6/13
+1. Thomas Bell 8/6/13
+1. Braden Wright 8/6/13
+1. Johnny Tan 8/6/13
+1. Yvonne Beumer Cloudreach 8/12/13
+1. Ben House 8/9/13
+1. Joe Fitzgerald 8/12/13
+1. Peter Hessler 8/13/13
+1. Nicholas Russell 8/13/13
+1. Brian Golf 8/13/13
+1. Adam Kunk 8/13/13
+1. Sandy Vanderbleek 8/13/13
+1. Lance French 8/13/13
+1. Jeff Hagadom 8/14/13
+1. George Miranda 8/16/13
+1. Evan Gilman 8/19/13
+1. Nenad Petronijevic 8/19/13
+1. Daniel Spilker CoreMedia AG 7/31/13
+1. Felix Simmendinger CoreMedia AG 7/31/13
+1. Eike Thienemann-Dehde CoreMedia AG 7/31/13
+1. Christopher Hass CoreMedia AG 7/31/13
+1. Daniel Zabel CoreMedia AG 7/31/13
+1. Ryan Munson Taos Mountain, Inc. 7/31/13
+1. Tim Fischbach 8/20/13
+1. Chance Zibolski 8/20/13
+1. Kazuki Akamine 8/20/13
+1. David Wittman 8/20/13
+1. Brian Whipple PROS, Inc. a Delaware Corporation 8/14/13
+1. Michael Jensen PROS, Inc. a Delaware Corporation 8/14/13
+1. Asanka Samaraweera PROS, Inc. a Delaware Corporation 8/14/13
+1. Christian Vozar Belly Inc 8/20/13
+1. Darby Frey Belly Inc 8/20/13
+1. Matthew Herscovitch Identive Group 8/20/13
+1. Mark Butcher Identive Group 8/20/13
+1. Luke Bradbury University of Derby 8/28/13
+1. Dan Webb University of Derby 8/28/13
+1. Alastair Firth 8/23/13
+1. Jesse Adams 8/28/13
+1. Matt Alexander 8/28/13
+1. Jason Vanderhoof 8/26/13
+1. Lianping Chen 8/26/13
+1. Christoph Bunte 8/26/13
+1. Yvonne Lam 8/28/13
+1. Mark Cornick TeamSnap 8/29/13
+1. Justin Clarke Social Ally Pty Ltd 8/29/13
+1. H Wade Minter TeamSnap 8/29/13
+1. Kyle Ries TeamSnap 8/29/13
+1. Phillip Hutchins 8/30/13
+1. Artem Kornienko 8/30/13
+1. Ulf Mansson Recorded Future 9/2/13
+1. Sam Crang 8/31/13
+1. Jorge Acosta Goszczynski 9/3/13
+1. Lysenko Kostiantyn 9/4/13
+1. Phil Sturgeon 9/4/13
+1. Kamil Bednarz 9/4/13
+1. Travis Petticrew 9/4/13
+1. Peter Walz 8/29/13
+1. Jeffrey Utter 9/4/13
+1. Martin Cozzi 9/4/13
+1. Andrew Thompson 9/4/13
+1. Thomas von Schwerdtner 9/4/13
+1. William Dierkes 9/4/13
+1. Robin Ricard 9/5/13
+1. Ben Longden 9/5/13
+1. Alex Denvir Protec Innovations Ltd. 9/5/13
+1. Martin Meredith Protec Innovations Ltd. 9/5/13
+1. Phil Thompson Protec Innovations Ltd. 9/5/13
+1. Alejandro Blanco 9/5/13
+1. Adrian Moisey 9/5/13
+1. Alex Zorin 9/5/13
+1. Robert Schulze 9/5/13
+1. Wei Liang 9/5/13
+1. Jon Torresdal 9/5/13
+1. Sergii Golovatiuk 9/6/13
+1. Mark O'Keefe 9/6/13
+1. Brint O'Heam 9/6/13
+1. Jim Myhrberg 9/7/13
+1. James FitzGibbon 9/8/13
+1. Isbaran Akcayir 9/9/13
+1. Sylvain Tisso Ecodev Sarl 9/9/13
+1. Fabien Udriot Ecodev Sarl 9/9/13
+1. Adrien Crivelli Ecodev Sarl 9/9/13
+1. Yoshanda Shin 9/10/13
+1. Christo De Lange 9/10/13
+1. Arthur Freyman 9/10/13
+1. Martin Walton 9/10/13
+1. Matthew Brennan 9/10/13
+1. Luis Ricardo Malheiros 9/11/13
+1. Amir Kadivar 9/11/13
+1. Davanum Srinivas 9/12/13
+1. Jesse Pretorius 9/12/13
+1. Denis Corol 9/12/13
+1. Yevgen Kovalienia 9/12/13
+1. Ben Hines 9/13/13
+1. Muneyuki Noguchi 9/14/13
+1. Myers Carpenter 9/16/13
+1. Mathieu Allaire 9/16/13
+1. Michael Stucki 9/17/13
+1. Kevin Webster 9/17/13
+1. Conor McDermottroe 9/17/13
+1. Naoya Nakazawa 9/17/13
+1. Mark Gibbons Nordstrom 9/17/13
+1. Matthew Moore 9/17/13
+1. Ingo Kampe kreuzwerker GmbH 9/18/13
+1. Robert Conrad kreuzwerker GmbH 9/18/13
+1. Daniel Meisen kreuzwerker GmbH 9/18/13
+1. Alexander Dall kreuzwerker GmbH 9/18/13
+1. Jan Nabbefeld kreuzwerker GmbH 9/18/13
+1. Joern Barthel kreuzwerker GmbH 9/18/13
+1. Harvey Bandana Nordstrom 9/18/13
+1. Ben Holley 9/18/13
+1. Yuji Takaesu 9/18/13
+1. Colin Burn-Murdoch 9/20/13
+1. Andrius Marcinkevicius 9/20/13
+1. Alan Bryan Central Desktop 9/18/13
+1. Craig Lewis Central Desktop 9/18/13
+1. Saku Laitinen Siili Solutions 9/19/13
+1. Denis Barishev Twiket LTD 9/23/13
+1. Sam Orlov Twiket LTD 9/23/13
+1. Jarek Gawor IBM 9/23/13
+1. Anthony Elder IBM 9/23/13
+1. Michael C Thompson IBM 9/23/13
+1. Jeremy Hughes IBM 9/23/13
+1. Igor Rodionov 9/23/13
+1. Gabor Garami 9/24/13
+1. Iulia Banghea 9/24/13
+1. Paul Dunnavant 9/24/13
+1. Alex Heneveld Cloudsoft Corp. 9/25/13
+1. Jordi Massaguer Pla 9/25/13
+1. Richard Downer Cloudsoft Corp. 9/25/13
+1. Roger Hu 9/25/13
+1. Dominic St-Jacques 9/25/13
+1. Mahmoud Abdelkader 9/26/13
+1. Takahiro Himura 9/26/13
+1. Aled Sage Cloudsoft Corp. 9/25/13
+1. Andrew Kennedy Cloudsoft Corp. 9/25/13
+1. Sam Corbett Cloudsoft Corp. 9/25/13
+1. Trevor Leybourne MYOB NZ Limited 9/26/13
+1. Greg Zapp MYOB NZ Limited 9/26/13
+1. Bo Ma MYOB NZ Limited 9/26/13
+1. Dmitry Lavrinenko 9/27/13
+1. Vitaly Shishlyannikov 9/27/13
+1. Jonathan Mickle 9/27/13
+1. Scott Hain Jr 9/27/13
+1. Ethan Fremen 9/29/13
+1. Daniel O'Conner 9/29/13
+1. Bill Wiens 9/30/13
+1. Jeroen Grusebroek Mollie B.V. 9/30/13
+1. Morton Jonuschat 9/30/13
+1. Bentrand Paquet 10/1/13
+1. Christoph Hartmann 10/1/13
+1. Okezie Eze 10/1/13
+1. Christopher Dwan 10/1/13
+1. Carl Schmidt Unbounce 10/1/13
+1. Aaron Oman Unbounce 10/1/13
+1. Chris Spicer Unbounce 10/1/13
+1. Jimmy Zheng Unbounce 10/1/13
+1. Josh Blancett 10/1/13
+1. Stephen Romney Shutl Ltd. 10/2/13
+1. James Wilford Shutl Ltd. 10/2/13
+1. Sam Phillips Shutl Ltd. 10/2/13
+1. Yomi Colledge Shutl Ltd. 10/2/13
+1. Marco Nenciarini 10/2/13
+1. Jake Herbst 10/2/13
+1. Kawahara Masashi 10/2/13
+1. Ilan Rabinovitch Ooyala, Inc. 10/3/13
+1. Garry Polley 10/3/13
+1. Akshay Karle 10/3/13
+1. Pascal Gelinas Nu Echo 10/3/13
+1. Salim Semaoune 10/3/13
+1. August Schwer 10/4/13
+1. Sam Adams 10/7/13
+1. Niels Kristensen 10/7/13
+1. Aliaksei Kliuchnikau 10/7/13
+1. Theofilos Papapanagiotou 10/7/13
+1. Mike Rossetti Our Film Festival (dba Fandor) 10/7/13
+1. Victor Lin 10/8/13
+1. Tyler Kellen 10/8/13
+1. Baba Buehler 10/8/13
+1. Matt Clifton 10/8/13
+1. Daniel Babel Ooyala, Inc. 10/9/13
+1. Jurgen Philippaerts Ooyala, Inc. 10/9/13
+1. Josh Toft Ooyala, Inc. 10/9/13
+1. Tobias Maier BauCloud GmbH 10/9/13
+1. Ryota Arai 10/9/13
+1. Kyle Kelley 10/10/13
+1. Jaroslav Barton 10/10/13
+1. Sam Pointer 10/10/13
+1. Sebastian Guevara 10/10/13
+1. Paul Welch Squaremouth Inc 10/10/13
+1. Peter Georgantas 10/10/13
+1. Karla Jacobsen 10/10/13
+1. Ryan S Brown 10/10/13
+1. Richard Manyanza 10/11/13
+1. Guilhem Lettron Optiflows 10/11/13
+1. Ludovic Havel Optiflows 10/11/13
+1. Jean Rouge 10/11/13
+1. Devon Jones 10/11/13
+1. Matthew Kasa 10/11/13
+1. James Moorhouse 10/12/13
+1. Christopher Grim 10/12/13
+1. Ryan Frantz 10/14/13
+1. Shrikant Patnaik General Sensing LTD 10/10/13
+1. Aaron Valade General Sensing LTD 10/10/13
+1. Chris Jerdonek 10/13/13
+1. EJ Ciramella Rapid7 10/14/13
+1. Brandon Turner Rapid7 10/14/13
+1. Chris Smtih Rapid7 10/14/13
+1. Ben Tomasini 10/14/13
+1. Evan Todd 10/15/13
+1. Alex Shadrin 10/15/13
+1. Mart Karu 10/15/13
+1. Russell Cardullo 10/15/13
+1. John Tran 10/15/13
+1. Alex Koch 10/15/13
+1. Jonathan Regeimbal 10/15/13
+1. James Walker 10/16/13
+1. Justin Dugger 10/16/13
+1. Dustin Collins 10/16/13
+1. Matthew Boedicker 10/17/13
+1. John Deatherage 10/17/13
+1. Aaron Jensen 10/17/13
+1. Olksandr Slynko 10/17/13
+1. Emanuele Rocca 10/18/13
+1. Antonio Fernandez Vara 10/18/13
+1. Mickhail Zholobov 10/18/13
+1. Daniel Wallace Rackspace 10/18/13
+1. Christian Fischer 10/18/13
+1. Silviu Dicu 10/18/13
+1. William Pietri 10/19/13
+1. Daniel Tracy 10/21/13
+1. Ashish Shinde 10/22/13
+1. Mathew Hoyle Deployable LTD 10/22/13
+1. Leonardo Leite 10/22/13
+1. Michael Dore 10/22/13
+1. Hannes Van De Vreken 10/22/13
+1. Mevan Samaratunga 10/22/13
+1. Adam Enger 10/22/13
+1. Peter Jönsson Klarna 10/23/13
+1. Carl Loa Odin Klarna 10/23/13
+1. Olle Lundberg Klarna 10/23/13
+1. Pat Downey 10/24/13
+1. Max Lincoln 10/24/13
+1. Pavel Brylov 10/24/13
+1. Sam Clements 10/25/13
+1. Gabriel Mazetto 10/25/13
+1. Cory Gunterman Nike, Inc. 10/25/13
+1. Justin Redd Nike, Inc. 10/25/13
+1. Dave Palomino Nike, Inc. 10/25/13
+1. Tom Luce Nike, Inc. 10/25/13
+1. Shawn Turpin Nike, Inc. 10/25/13
+1. Ed Tretyakov 10/27/13
+1. Frank Breedijk Schuberg Phillis B.V. 10/28/13
+1. Henry Finucane 10/30/13
+1. Thomas de Grenier de Latour 10/30/13
+1. Andrey Chernih 10/30/13
+1. Matt Wormley 10/30/13
+1. Maciej Galkiewicz 10/31/13
+1. Makiko Nomura 11/1/13
+1. Cheah Chu Yeow Irrational Industries, Inc. 11/1/13
+1. Christian Paredes Irrational Industries, Inc. 11/1/13
+1. Rafael Kolless 11/2/13
+1. Zsolt Takacs 11/2/13
+1. Tobias Schmidt SoundCloud Ltd. 11/5/13
+1. Frederick Jaeckel SoundCloud Ltd. 11/5/13
+1. Matthias Rampke SoundCloud Ltd. 11/5/13
+1. Daman Yang SoundCloud Ltd. 11/5/13
+1. Ben Kochie SoundCloud Ltd. 11/5/13
+1. Alexander Grosse SoundCloud Ltd. 11/5/13
+1. Allan Beaufour Project Florida 11/5/13
+1. Jow Crobak Project Florida 11/5/13
+1. Derek Groh 11/5/13
+1. David Shawley 11/5/13
+1. Jason Faulkner 11/5/13
+1. Cheryl Ainoa Intuit 11/6/13
+1. Thomas Bishop Intuit 11/6/13
+1. Jeffrey Mendoza 11/6/13
+1. Munirathnam Srikanth ComputeNext 11/6/13
+1. Sergio Patino 11/6/13
+1. Andrew Caldwell 11/6/13
+1. Alex Derzhi 11/7/13
+1. Olivier Biesmans 11/7/13
+1. Gabriel Rosendorf The Weather Companies 11/8/13
+1. Nathaniel Eliot 11/9/13
+1. Thibaut Notteboom 11/10/13
+1. Walter Huf 11/11/13
+1. David Larken Nolen 11/11/13
+1. Makana Greenwell 11/12/13
+1. Mathew Hartley 11/12/13
+1. Julie Rice PTC Inc 11/13/13
+1. Matt Welch PTC Inc 11/13/13
+1. Jonathan Bass PTC Inc 11/13/13
+1. Joe Rocklin 11/14/13
+1. Zaininnari 11/14/13
+1. Jean Mertz 11/18/13
+1. Gleb Borisov 11/19/13
+1. Curtis Stewart 11/19/13
+1. Jim Park RamTank Inc 11/19/13
+1. Pierre Ynard Criteo 11/19/13
+1. Sergey Balbeko 11/20/13
+1. Igor Serko 11/20/13
+1. Jason Giedymin 11/20/13
+1. Luca Pradovera 11/20/13
+1. Jason Giedymin 11/20/13
+1. Shaun Rowe 11/21/13
+1. Chad Cloes Intuit 11/21/13
+1. Rick Mendes Intuit 11/21/13
+1. Grant Hoffman Intuit 11/21/13
+1. Capen Brinkley Intuit 11/21/13
+1. Kevin Young Intuit 11/21/13
+1. Walter Askew IV 11/22/13
+1. Spencer Smith 11/23/13
+1. Spencer Smith 11/23/13
+1. Connor Goodwolf 11/23/13
+1. Seiji Komatsu 11/24/13
+1. Steve Domin GoCardless 11/24/13
+1. Milos Gajdos GoCardless 11/24/13
+1. Harry Marr GoCardless 11/24/13
+1. Komatsu Seiji 11/25/13
+1. Gokulnath Manakkattil 11/26/13
+1. Joel Moss 11/27/13
+1. Drew J. Sonne 11/30/13
+1. Sascha Mollering ZANOX AG 11/30/13
+1. Boris Komraz 12/1/13
+1. Mark O'Connor 12/1/13
+1. Ivan Larionov 12/2/13
+1. Pierre Carrier 12/2/13
+1. Joe A. Kemp ARINC 12/3/13
+1. Douglas Mendizabal 12/3/13
+1. Tejay Cardon Lockheed Martin Corporation 12/3/13
+1. David Deal Lockheed Martin Corporation 12/3/13
+1. Jason Loveland Lockheed Martin Corporation 12/3/13
+1. Friedrich Clausen 12/4/13
+1. Paul Kehrer 12/4/13
+1. Stephan Renatus 12/5/13
+1. Abhijit Hiremagalur 12/5/13
+1. Wojciech Oledzki 12/5/13
+1. Johannes Plunien 12/7/13
+1. Benjamin Demaree 12/8/13
+1. Friedel Ziegelmayer 12/13/13
+1. Jason Vervlied 12/13/13
+1. Fabian Lee 12/15/13
+1. Tino Breddin 12/16/13
+1. Cameron Cope Brightcove 12/16/13
+1. Jason Perry Brightcove 12/16/13
+1. Eric Moakley Brightcove 12/16/13
+1. Joshua Spiewak Brightcove 12/16/13
+1. John Schectman Brightcove 12/16/13
+1. Keegan Holley 12/16/13
+1. James La Spada 12/17/13
+1. Jesué Sousa Cunha Junior 12/17/13
+1. Dan Rathbone 12/17/13
+1. Jay Geeseman 12/19/13
+1. David Bernick 12/20/13
+1. Primož Verdnik 12/20/13
+1. Yavor Nikolov 12/26/13
+1. Joseph C. Stump Sprint.ly, Inc 12/27/13
+1. Justin T. Abrahms Sprint.ly, Inc 12/27/13
+1. Theodore Chuong Nordsieck 12/29/13
+1. Thomas Noonan II 12/30/13
+1. Coman Ioan Andrei 12/30/13
+1. Steven Geerts Schuberg Phillis B.V. 1/2/14
+1. Scott Russell 1/3/14
+1. Lothar Wieske 1/3/14
+1. Paul Czarkowski 1/3/14
+1. Ramil Lim 1/3/14
+1. Jeff Byrnes 1/3/14
+1. Christopher James Saylor 1/4/14
+1. Gary Cao 1/6/14
+1. Christopher William Pernicano 1/6/14
+1. Emmanuel Idi 1/6/14
+1. Reid Beels 1/7/14
+1. Anthony LoBono 1/8/14
+1. Barthélemy Vessemont 1/10/14
+1. Michael Holtzman 1/10/14
+1. Tristan O'Neil Cramer Development 1/10/14
+1. Brian Cobb Cramer Development 1/10/14
+1. Brett Chalupa Cramer Development 1/10/14
+1. Dan Volkens Cramer Development 1/10/14
+1. Ryan Keairns Cramer Development 1/10/14
+1. Nikhil Benesch 1/12/14
+1. Christian Höltje 1/13/14
+1. Alexander C Corvin 1/17/14
+1. Samuel Chambers 1/18/14
+1. Cheah Chu Yeow 1/18/14
+1. Kazuki Saito 1/18/14
+1. Pete Richards 1/19/14
+1. Jimmy McCrory 1/19/14
+1. Olivier Dolbeau 1/20/14
+1. Andrew Brown BlackBerry, Inc. 1/20/14
+1. Phil Oliva BlackBerry, Inc. 1/20/14
+1. Dave Urschatz BlackBerry, Inc. 1/20/14
+1. Ishtiaq Ahmed 1/25/14
+1. Caleb Land 1/26/14
+1. Charles B Johnson 1/26/14
+1. Diego Rodriguez 1/27/14
+1. Nitin Mohan 1/27/14
+1. Szymon Szypulski 1/29/14
+1. Jaime Gil de Sagredo 1/29/14
+1. Jose Luis Ferrer Riera 1/29/14
+1. Yury Velikanau 1/29/14
+1. Jeroen Jacobs 1/30/14
+1. W. Hart Hoover Rackspace 2/3/14
+1. Jerry Richardson Disruptive Ventures, Inc 2/4/14
+1. Brian Dwyer 2/4/14
+1. Aaron O'Mullan FriendCode, Inc 2/5/14
+1. Jean-Baptiste Dalido 2/6/14
+1. Juri Timoshin 2/6/14
+1. Pascal Laporte 2/6/14
+1. Steven Cummings Cerner Innovation Inc 2/6/14
+1. Pascal Laporte 2/6/14
+1. Mick Brooks 2/7/14
+1. Aurélien Noce 2/7/14
+1. Charlie Huggard Cerner Innovation Inc 2/11/14
+1. Matthias Arnason Engine Yard 2/12/14
+1. Bryan Taylor 2/12/14
+1. Michael Dillion 2/17/14
+1. Seth Kingry 2/18/14
+1. Wesley David DeCesare Crux Hosted Services 2/18/14
+1. Kent Shultz 2/18/14
+1. Adam Durana 2/21/14
+1. Jacob McCann 2/21/14
+1. Andriy Tyurnikov 2/21/14
+1. Anton Koldaev 2/21/14
+1. Matthew Rathbone 2/21/14
+1. Egor Medvedev 2/23/14
+1. Eric Tucker Blue Spurs 2/24/14
+1. Tomas Gutierrez 2/24/14
+1. Jordan Burke 2/25/14
+1. Zvi Effron 2/25/14
+1. Pranay Manwatkar 2/26/14
+1. Kaspars Mickevics 2/26/14
+1. Roman Gorodeckij 2/27/14
+1. Matthew Baxa 2/27/14
+1. Maxime Caumartin 2/27/14
+1. Brandon Raabe 2/28/14
+1. Alan Grosskurth 2/28/14
+1. Nathan Milford 2/28/14
+1. Jacob Vosmaer GitLab.com 3/1/14
+1. Job van der Voort GitLab.com 3/1/14
+1. Marin Jankovski GitLab.com 3/1/14
+1. Martin Glaß 3/1/14
+1. Sergey Sergeev 3/1/14
+1. Marshall Ian Farmer 3/2/14
+1. Markus Schabel 3/3/14
+1. Torben Knerr 3/4/14
+1. Pavel Sadikov 3/5/14
+1. David King 3/7/14
+1. Charles Guenther Yelp 3/7/14
+1. Kris Wehner Yelp 3/7/14
+1. Brian Fletcher Workday 3/10/14
+1. Brad Pokorny IBM 3/10/14
+1. John Warren IBM 3/10/14
+1. Lance Bragstad IBM 3/10/14
+1. Luis Garcia IBM 3/10/14
+1. Mark Vanderwiel IBM 3/10/14
+1. Mathew Odden IBM 3/10/14
+1. Andrew Coulton 3/11/14
+1. Andrew Ordiales 3/11/14
+1. Will Hattingh 3/12/14
+1. Eohyung Lee 3/13/14
+1. Matthew Zito BMC Software Inc 3/13/14
+1. Nick Galbreath 3/13/14
+1. Thomas Duckering 3/14/14
+1. Stanley Halka 3/14/14
+1. Michael Morris 3/14/14
+1. Gavin Montague itison 3/14/14
+1. John Daniels itison 3/14/14
+1. Matthias Endler 3/17/14
+1. Greg Albrecht OnBeep, Inc. 3/19/14
+1. Andy Issacson OnBeep, Inc. 3/19/14
+1. Ben Graver OnBeep, Inc. 3/19/14
+1. Jim Qin OnBeep, Inc. 3/19/14
+1. Carlos Vinueza OnBeep, Inc. 3/19/14
+1. Benson Miller Level 11 Consulting 3/19/14
+1. Nik Ormseth Level 11 Consulting 3/19/14
+1. James Francis Level 11 Consulting 3/19/14
+1. Kevin Rivers Level 11 Consulting 3/19/14
+1. Michael Dellanoce 3/20/14
+1. Joey Line 3/21/14
+1. Nick Lopez 3/22/14
+1. Jason Byck 3/23/14
+1. Ian Neubert 3/25/14
+1. Brandon Taylor Groves 3/25/14
+1. Sean Walberg 3/25/14
+1. Matthijs Wijers 3/26/14
+1. Tensibai Zhaoying 3/26/14
+1. Michael Chletso 3/27/14
+1. Joseph Korkames 3/27/14
+1. Matthew Juszczak 3/27/14
+1. Hongbin Lu 3/27/14
+1. Ryan Lewon 3/28/14
+1. Tiru Srikantha 3/29/14
+1. Calvin Worsnup 3/31/14
+1. Andres More 4/1/14
+1. Joe Richards 4/1/14
+1. Mikael Henriksson 4/2/14
+1. Benjamin Dalton LeMasurier 4/2/14
+1. Dirk Moermans 4/3/14
+1. Pavel Yudin 4/4/14
+1. Ed Neville Linaro Limited 4/4/14
+1. Andrew McDermott Linaro Limited 4/4/14
+1. Ron Nandy Linaro Limited 4/4/14
+1. Florian Holzhauer 4/4/14
+1. Joshua Yotty 4/4/14
+1. Narendra V Dharmavarapu 4/4/14
+1. Brian Wilson Leake 4/6/14
+1. John Northrup 4/7/14
+1. Yoichi Isozaki 4/7/14
+1. Jordan Evans 4/8/14
+1. Oliver Kohl 4/9/14
+1. Craig Monson 4/10/14
+1. Rob Brown 4/10/14
+1. Alexander Myasnikov 4/11/14
+1. Matthew Hodgkins 4/12/14
+1. Aaron Quint 4/12/14
+1. Jaewoo Kim 4/17/14
+1. Vasiliy Tolstov 4/17/14
+1. Ryan Moe 4/18/14
+1. G. Panula 4/21/14
+1. Chris Antenesse 4/21/14
+1. Lloyd Chan 4/22/14
+1. Satoshi Tanaka 4/22/14
+1. Tim Heckman 4/24/14
+1. Trevor Lauder 4/25/14
+1. Nathan Haneysmith Nordstrom 4/25/14
+1. Aaron Lane 4/26/14
+1. Bao Nguyen 4/27/14
+1. Salvatore Poliandro III 4/28/14
+1. Eric Zhoe 4/29/14
+1. Alex Kahn 4/29/14
+1. Brendan Murtagh 4/29/14
+1. Tyler Cipriani 4/29/14
+1. Syunsuke Komma WESEEK 4/29/14
+1. Yuki Takei WESEEK 4/29/14
+1. Trevor Bramwell 5/1/14
+1. Robert Tarrall 5/1/14
+1. Josh Reichardt 5/1/14
+1. Trevor Lauder Intuit 5/1/14
+1. Jake Plimack 5/2/14
+1. Brian D Clark 5/3/14
+1. Roman Chukh 5/4/14
+1. Nick Montgomery 5/4/14
+1. Patrick Moore 5/5/14
+1. Edmund Dipple 5/6/14
+1. Kyle Boorky 5/6/14
+1. Olivier Larivain 5/6/14
+1. Aaron Valade 5/7/14
+1. Jonathan Serafini 5/7/14
+1. Jason Nelson Rackspace 5/8/14
+1. Alexander Meng 5/8/14
+1. Kyle McGovern Cerner Innovation Inc 5/8/14
+1. Jesse Washburn 5/8/14
+1. Ian Blenke 5/9/14
+1. Jochen Seeber 5/9/14
+1. Florin Stan 5/9/14
+1. Bearnard Hibbins 5/12/14
+1. Amruta Krishna Cerner Innovation Inc 5/13/14
+1. Daniel Zautner 5/13/14
+1. Andrew DuFour 5/13/14
+1. David Gil Oliva 5/19/14
+1. Emmanuel Sciara 5/20/14
+1. Francois Visconte 5/21/14
+1. Cyril Scetbon 5/21/14
+1. Doug Wilson CustomInk 4/4/14
+1. Meherez Alachheb 5/22/14
+1. Ash Wilson Rackspace 5/22/14
+1. Alexey Velikiy 5/21/14
+1. Anand Suresh 5/24/14
+1. Christoph Krämer 5/26/14
+1. Marcus Nilsson 5/27/14
+1. Eric Black 5/27/14
+1. Michiel Sikkes 5/29/14
+1. Miguel Landaeta 5/29/14
+1. Claude Ballew Jr 5/29/14
+1. Carlos Macasaet 5/29/14
+1. Steve Jansen 6/3/14
+1. Jake Champlin 6/4/14
+1. Alistair Stead Iniqa UK, Ltd 6/4/14
+1. Fahd Sultan 6/4/14
+1. Martin Smith III Rackspace 6/4/14
+1. Klaas Jan Wierenga 6/5/14
+1. Michael Bumann 6/6/14
+1. Grant Hudgens 6/6/14
+1. Rob Redpath World Wide Web Hosting, LLC 6/6/14
+1. Benjamin Ahrens 6/9/14
+1. Alessio Franceschelli 6/10/14
+1. Joseph Bowman 6/11/14
+1. William Cody Crawford 6/11/14
+1. Ryan Trauntvein 6/12/14
+1. Adam Lavin 6/14/14
+1. Brett Cave Jemstep 6/13/14
+1. Matt Wrock 6/16/14
+1. William Clark 6/17/14
+1. Karsten McMinn 6/17/14
+1. Alexander Simonov 6/17/14
+1. James Coleman 6/18/14
+1. Charles Ruhl 6/18/14
+1. Pushkar Subhash Raste 6/19/14
+1. John Coleman 6/20/14
+1. Joshua Rutherford 6/20/14
+1. Elijah Buck 6/21/14
+1. Nikalai Stakanov 6/22/14
+1. Blair Hamilton 6/22/14
+1. Jeffrey Goldschrafe 6/24/14
+1. Vijay Bheemineni 6/25/14
+1. Joshua Benjamin 6/25/14
+1. Stafford Brunk 6/25/14
+1. Sumit Gupta 6/26/14
+1. Jan Mara 6/27/14
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f8618ad381..cc416537ab 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -128,6 +128,9 @@ If you are familiar with Chef and know the component that is causing you a probl
Github project. All of our Open Source Software can be found in our
[Github organization](https://github.com/opscode/).
+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/opscode/chef/issues)
and we will make sure it gets filed against the appropriate project.
@@ -173,7 +176,7 @@ Contributions go through a review process to improve code quality and avoid regr
Our primary shipping vehicle is operating system specific packages that includes
all the requirements of Chef. We call these [Omnibus packages](https://github.com/opscode/omnibus-ruby)
-We also release our software as gems to [Rubygems](http://rubygems.org/) but we strongly
+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.
diff --git a/DOC_CHANGES.md b/DOC_CHANGES.md
index 6b58871418..cae29adb80 100644
--- a/DOC_CHANGES.md
+++ b/DOC_CHANGES.md
@@ -5,3 +5,76 @@ Example Doc Change:
### Headline for the required change
Description of the required change.
-->
+
+
+### File-like resources now accept a `verify` attribute
+
+The file, template, cookbook_file, and remote_file resources now all
+accept a `verify` attribute. This file accepts a string or a block,
+similar to `only_if`. A full specification can be found in RFC 027:
+
+https://github.com/opscode/chef-rfc/blob/master/rfc027-file-content-verification.md
+
+### Chef now handles URI Schemes in a case insensitive manner
+
+Previously, when a URI scheme contained all uppercase letters, Chef would reject the URI as invalid. In compliance with RFC3986, Chef now treats URI schemes in a case insensitive manner. This applies to all resources which accept URIs such as remote_file etc.
+
+### Experimental Audit Mode Feature
+
+There is a new command_line flag provided for `chef-client`: `--audit-mode`. This accepts 1 of 3 arguments:
+
+* `disabled` (default) - Audits are disabled and the phase is skipped. This is the default while Audit mode is an
+experimental feature.
+* `enabled` - Audits are enabled and will be performed after the converge phase.
+* `audit-only` - Audits are enabled and convergence is disabled. Only audits will be performed.
+
+This can also be configured in your node's client.rb with the key `audit_mode` and a value of `:disabled`, `:enabled` or `:audit_only`.
+
+### Chef Why Run Mode Ignores Audit Phase
+
+Because most users enable `why_run` mode to determine what resources convergence will update on their system, the audit
+phase is not executed. There is no way to get both `why_run` output and audit output in 1 single command. To get
+audit output without performing convergence use the `--audit-mode` flag.
+
+#### Editors note 1
+
+The `--audit-mode` flag should be a link to the documentation for that flag
+
+#### Editors node 2
+
+This probably only needs to be a bullet point added to http://docs.getchef.com/nodes.html#about-why-run-mode under the
+`certain assumptions` section
+
+## Drop SSL Warnings
+Now that the default for SSL checking is on, no more warning is emitted when SSL
+checking is off.
+
+## Multi-package Support
+The `package` provider has been extended to support multiple packages. This
+support is new and and not all subproviders yet support it. Full support for
+`apt` and `yum` has been implemented.
+
+## Add compile_time option to chef_gem
+
+This option defaults to true, which is deprecated, and setting this to false
+will stop chef_gem from automatically installing at compile_time. False is
+the recommended setting as long as the gem is only used in provider code (a
+best practice) and not used directly in recipe code.
+
+## Yum Package provider now supports version requirements
+
+A documented feature of the yum_package provider was the ability to specify a version requirement such as ` = 1.0.1.el5` in the resource name.
+However, this did not actually work. It has now been fixed, and additionally version requirements are now supported in the `version` attribute
+of yum_package as well.
+
+## Validatorless bootstraps
+
+Validation keys are now optional. If the validation key is simply deleted and does not exist, then knife bootstrap will use the
+user's key to create a client for the node and create the node object and bootstrap the host. Validation keys can continue to be
+used, particularly for autoscaling, but even for that use case a dedicated user for autoscaling would be preferable to the shared
+validation key.
+
+## Bootstrap will create chef-vault items
+
+The --bootstrap-vault-item, --bootstrap-vault-json, and --bootstrap-vault-file arguments have been added to knife bootstrap providing
+three alternative ways to set chef vault items when bootstrapping a host.
diff --git a/MAINTAINERS.md b/MAINTAINERS.md
new file mode 100644
index 0000000000..5c8d8faea1
--- /dev/null
+++ b/MAINTAINERS.md
@@ -0,0 +1,129 @@
+# Maintainers
+
+This file lists how the Chef project is maintained. When making changes to the system, this
+file tells you who needs to review your patch - you need a simple majority of maintainers
+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
+a maintainer, lieutenant, or the project lead.
+
+# Project Lead
+
+[Adam Jacob](http://github.com/adamhjk)
+
+# Components
+
+## Chef Core
+
+Handles the core parts of the Chef DSL, base resource and provider
+infrastructure, and the Chef applications. Includes anything not covered by
+another component.
+
+### Lieutenant
+
+### Maintainers
+
+* [Jon Cowie](http://github.com/jonlives)
+* [Phil Dibowitz](https://github.com/jaymzh)
+* [Lamont Granquist](http://github.com/lamont-granquist)
+* [Tyler Ball](https://github.com/tyler-ball)
+* [Daniel DeLeo](https://github.com/danielsdeleo)
+* [Claire McQuin](https://github.com/mcquin)
+* [Jay Mundrawala](http://github.com/jdmundrawala)
+* [Bryan McLellan](http://github.com/btm)
+* [Ranjib Dey](http://github.com/ranjib)
+* [AJ Christensen](https://github.com/fujin)
+
+## Dev Tools
+
+Chef Zero, Knife, Chef Apply and Chef Shell.
+
+### Lieutenant
+
+### Maintainers
+
+* [Steven Danna](https://github.com/stevendanna/)
+* [Joshua Timberman](https://github.com/jtimberman)
+* [Lamont Granquist](http://github.com/lamont-granquist)
+* [Daniel DeLeo](https://github.com/danielsdeleo)
+
+## Test Tools
+
+### ChefSpec
+
+#### Lieutenant
+
+[Seth Vargo](https://github.com/sethvargo)
+
+#### Maintainers
+
+* [Joshua Timberman](https://github.com/jtimberman)
+* [Lamont Granquist](http://github.com/lamont-granquist)
+* [Ranjib Dey](http://github.com/ranjib)
+
+## Platform Specific Components
+
+The specific components of Chef related to a given platform - including (but not limited to) resources, providers, and the core DSL.
+
+## Enterprise Linux
+
+### Lieutenant
+
+### Maintainers
+
+* [Jon Cowie](http://github.com/jonlives)
+* [Lamont Granquist](http://github.com/lamont-granquist)
+
+## Ubuntu
+
+### Lieutenant
+
+### Maintainers
+
+* [Lamont Granquist](http://github.com/lamont-granquist)
+* [Ranjib Dey](http://github.com/ranjib)
+
+## Windows
+
+### Lieutenant
+
+* [Bryan McLellan](http://github.com/btm)
+
+### Maintainers
+* [Steven Murawski](http://github.com/smurawski)
+* [Jay Mundrawala](http://github.com/jdmundrawala)
+
+## Solaris
+
+### Lieutenant
+
+### Maintainers
+
+* [Lamont Granquist](http://github.com/lamont-granquist)
+
+## AIX
+
+### Lieutenant
+
+### Maintainers
+
+* [Lamont Granquist](http://github.com/lamont-granquist)
+
+## Mac OS X
+
+### Lieutenant
+
+### Maintainers
+
+* [Joshua Timberman](https://github.com/jtimberman)
+* [Tyler Ball](https://github.com/tyler-ball)
+
+## FreeBSD
+
+### Lieutenant
+
+* [Aaron Kalin](https://github.com/martinisoft)
+
+### Maintainers
+
diff --git a/README.md b/README.md
index 48e49b9d66..3b1c7190fb 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,13 @@
-# Chef [![Code Climate](https://codeclimate.com/github/opscode/chef.png)](https://codeclimate.com/github/opscode/chef)
+# Chef
+[![Code Climate](https://codeclimate.com/github/opscode/chef.png)](https://codeclimate.com/github/opscode/chef)
+[![Build Status Master](https://travis-ci.org/chef/chef.svg?branch=master)](https://travis-ci.org/chef/chef)
+[![Build Status Master](https://ci.appveyor.com/api/projects/status/github/chef/chef?branch=master&svg=true&passingText=master%20-%20Ok&pendingText=master%20-%20Pending&failingText=master%20-%20Failing)](https://ci.appveyor.com/project/Chef/chef/branch/master)
-Want to try Chef? Get started with [learnchef](https://learnchef.opscode.com)
+Want to try Chef? Get started with [learnchef](https://learn.chef.io)
-* Documentation: [http://docs.opscode.com](http://docs.opscode.com)
-* Source: [http://github.com/opscode/chef/tree/master](http://github.com/opscode/chef/tree/master)
-* Tickets/Issues: [https://github.com/opscode/chef/issues](https://github.com/opscode/chef/issues)
+* 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
* Mailing list: [http://lists.opscode.com](http://lists.opscode.com)
@@ -14,15 +17,15 @@ entire infrastructure.
This README focuses on developers who want to modify Chef source code.
If you just want to use Chef, check out these resources:
-* [learnchef](https://learnchef.opscode.com): Getting started guide
-* [http://docs.opscode.com](http://docs.opscode.com): Comprehensive User Docs
-* [Installer Downloads](http://www.getchef.com/chef/install/): Install Chef as a complete package
+* [learnchef](https://learn.chef.io): Getting started guide
+* [http://docs.chef.io](http://docs.chef.io): Comprehensive User Docs
+* [Installer Downloads](https://www.chef.io/download-chef-client/): Install Chef as a complete package
## Installing From Git
**NOTE:** Unless you have a specific reason to install from source (to
try a new feature, contribute a patch, or run chef on an OS for which no
-package is available), you should head to the [installer page](http://www.getchef.com/chef/install/)
+package is available), you should head to the [installer page](https://www.chef.io/download-chef-client/)
to get a prebuilt package.
### Prerequisites
@@ -31,7 +34,7 @@ Install these via your platform's preferred method (apt, yum, ports,
emerge, etc.):
* git
-* C compiler, header files, etc. On Ubuntu/debian, use the
+* C compiler, header files, etc. On Ubuntu/Debian, use the
`build-essential` package.
* ruby 2.0.0 or later
* rubygems
@@ -42,7 +45,7 @@ emerge, etc.):
Then get the source and install it:
# Clone this repo
- git clone https://github.com/opscode/chef.git
+ git clone https://github.com/chef/chef.git
# cd into the source tree
cd chef
@@ -61,18 +64,34 @@ Then get the source and install it:
Before working on the code, if you plan to contribute your changes, you need to
read the
-[Chef Contributions document](http://docs.opscode.com/community_contributions.html).
+[Chef Contributions document](http://docs.chef.io/community_contributions.html).
-You will also need to set up the repository with the appropriate branches. We
-document the process on the
-[Working with Git](http://wiki.opscode.com/display/chef/Working+with+git) page
-of the Chef wiki.
+The general development process is:
+
+1. Fork this repo and clone it to your workstation
+2. Create a feature branch for your change
+3. Write code and tests
+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.
+## Reporting Issues
+
+Issues can be reported by using [GitHub issues](https://github.com/chef/chef/issues).
+
+Full details on how to report issues can be found in the [CONTRIBUTING](https://github.com/chef/chef/blob/master/CONTRIBUTING.md#-chef-issue-tracking) doc.
+
+Note that this repository is primarily for reporting chef-client issues.
+For reporting issues against other Chef projects, please look up the appropriate repository
+to report issues against in the Chef docs in the
+[community contributions section](https://docs.chef.io/community_contributions.html#issues-and-bug-reports).
+If you can't detemine the appropriate place to report an issue, then please open it
+against the repository you think best fits and it will be directed to the appropriate project.
+
## Testing
We use RSpec for unit/spec tests. It is not necessary to start the development
@@ -87,14 +106,19 @@ environment to run the specs--they are completely standalone.
# Run a Subset of Tests
bundle exec rspec spec/PATH/TO/DIR
+When you submit a pull request, we will automatically run the functional and unit
+tests in spec/functional/ and spec/unit/ respectively. These will be run on Ubuntu
+through Travis CI, and on Windows through AppVeyor. The status of these runs will
+be displayed with your pull request.
+
# License
Chef - A configuration management system
| | |
|:---------------------|:-----------------------------------------|
-| **Author:** | Adam Jacob (<adam@opscode.com>)
-| **Copyright:** | Copyright (c) 2008-2014 Chef Software, Inc.
+| **Author:** | Adam Jacob (<adam@chef.io>)
+| **Copyright:** | Copyright (c) 2008-2015 Chef Software, Inc.
| **License:** | Apache License, Version 2.0
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 70ed044a19..4d92eee671 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -1,456 +1,147 @@
-# Chef Client Release Notes 12.0.0:
+# Chef Client Release Notes 12.1.0:
# Internal API Changes in this Release
-These changes do not impact any cookbook code, but may impact tools that
-use the code base as a library. Authors of tools that rely on Chef
-internals should review these changes carefully and update their
-applications.
+## Experimental Audit Mode Feature
-## Changes to CookbookUpload
+This is a new feature intended to provide _infrastructure audits_. Chef already allows you to configure your infrastructure
+with code, but there are some use cases that are not covered by resource convergence. What if you want to check that
+the application Chef just installed is functioning correctly? If it provides a status page an audit can check this
+and validate that the application has database connectivity.
-`Chef::CookbookUpload.new` previously took a path as the second
-argument, but due to internal changes, this parameter was not used, and
-it has been removed. See: https://github.com/opscode/chef/commit/12c9bed3a5a7ab86ff78cb660d96f8b77ad6395d
+Audits are performed by leveraging [Serverspec](http://serverspec.org/) and [RSpec](https://relishapp.com/rspec) on the
+node. As such the syntax is very similar to a normal RSpec spec.
-## Changes to FileVendor
-
-`Chef::Cookbook::FileVendor` was previously configured by passing a
-block to the `on_create` method; it is now configured by calling either
-`fetch_from_remote` or `fetch_from_disk`. See: https://github.com/opscode/chef/commit/3b2b4de8e7f0d55524f2a0ccaf3e1aa9f2d371eb
-
-# End-User Changes
-
-## Chef 12 Attribute Changes
-
-The Chef 12 Attribute RFC 23 (https://github.com/opscode/chef-rfc/blob/master/rfc023-chef-12-attributes-changes.md) has been merged into
-Chef. This adds the ability to remove precedence levels (or all levels) of attributes in recipes code, or to
-force setting an attribute precedence level. The major backwards incompatible change to call out in this RFC is that
-`node.force_default!` and `node.force_override!` have changed from accessors to setters, and any cookbook code that used these functions
-(extremely uncommon) simply needs to drop the exclamation point off of the method in order to use the accessor.
-
-## Knife Prefers `config.rb` to `knife.rb`.
-
-Knife will now look for `config.rb` in preference to `knife.rb` for its
-configuration file. The syntax and configuration options available in
-`config.rb` are identical to `knife.rb`. Also, the search path for
-configuration files is unchanged.
-
-At this time, it is _recommended_ that users use `config.rb` instead of
-`knife.rb`, but `knife.rb` is not deprecated; no warning will be emitted
-when using `knife.rb`. Once third-party application developers have had
-sufficient time to adapt to the change, `knife.rb` will become
-deprecated and config.rb will be preferred.
-
-## Boostrap Changes
-
-Chef Client 12 introduces a set of changes to `knife bootstrap`. Here is the list of changes:
-
-* Unused / untested bootstrap templates that install Chef Client from rubygems are removed. The recommended installation path for Chef Client is to use the omnibus packages. `chef-full` template (which is the default) installs Chef Client using omnibus packages on all the supported platforms.
-* `--distro` & `--template-file` options are deprecated in Chef 12 in favor of `--boostrap-template` option. This option can take a boostrap template name (e.g. 'chef-full') or the full path to a bootstrap template.
-* Chef now configures `:ssl_verify_mode` & `:verify_api_cert` config options on the node that is being bootstrapped. This setting can be controlled by `:node_ssl_verify_mode` & `:node_verify_api_cert` CLI options. If these are not specified the configured value will be inferred from knife config.
-
-## Solaris Mount Provider
-
-The Solaris provider now supports specifying the fsck_device attribute (which defaults to '-' for backwards compat).
-
-## Version Constraints in value_for_platform
-
-The `value_for_platform` helper can now take version constraints like `>=` and `~>`. This is particularly useful for users
-of RHEL 7 where the version numbers now look like `7.0.<buildnumber>`, so that they can do:
+### Syntax
```ruby
-value_for_platform(
- "redhat" => {
- "~> 7.0" => "version 7.x.y"
- ">= 8.0" => "version 8.0.0 and greater"
- }
-}
-```
+control_group "Database Audit" do
-Note that if two version constraints match it is considered ambiguous and will raise an Exception. An exact match, however, will
-always take precedence over a version constraint.
+ control "postgres package" do
+ it "should not be installed" do
+ expect(package("postgresql")).to_not be_installed
+ end
+ end
-## Git SCM provider now support environment attribute
+ let(:p) { port(111) }
+ control p do
+ it "has nothing listening" do
+ expect(p).to_not be_listening
+ end
+ end
-You can now pass in a hash of environment variables into the git provider:
-
-```ruby
-git "/opt/mysources/couch" do
- repository "git://git.apache.org/couchdb.git"
- revision "master"
- environment { 'VAR' => 'whatever' }
- action :sync
end
```
-The git provider already automatically sets `ENV['HOME']` and `ENV['GIT_SSH']` but those can both be overridden
-by passing them into the environment hash if the defaults are not appropriate.
-
-## DSCL user provider now supports Mac OS X 10.7 and above.
-
-DSCL user provider in Chef has supported setting passwords only on Mac OS X 10.6. In this release, Mac OS X versions 10.7 and above are now supported. Support for Mac OS X 10.6 is dropped from the dscl provider since this version is EOLed by Apple.
-
-In order to support configuring passwords for the users using shadow hashes two new attributes `salt` & `iterations` are added to the user resource. These attributes are required to make the new [SALTED-SHA512-PBKDF2](http://en.wikipedia.org/wiki/PBKDF2) style shadow hashes used in Mac OS X versions 10.8 and above.
-
-User resource on Mac supports setting password both using plain-text password or using the shadow hash. You can simply set the `password` attribute to the plain text password to configure the password for the user. However this is not ideal since including plain text passwords in cookbooks (even if they are private) is not a good idea. In order to set passwords using shadow hash you can follow the instructions below based on your Mac OS X version.
-
-## Mac OS X default package provider is now Homebrew
-
-Per [Chef RFC 016](https://github.com/opscode/chef-rfc/blob/master/rfc016-homebrew-osx-package-provider.md), the default provider for the `package` resource on Mac OS X is now [Homebrew](http://brew.sh). The [homebrew cookbook's](https://supermarket.getchef.com/cookbooks/homebrew) default recipe, or some other method is still required for getting homebrew installed on the system. The cookbook won't be strictly required just to install packages from homebrew on OS X, though. To use this, simply use the `package` resource, or the `homebrew_package` shortcut resource:
-
-```ruby
-package 'emacs'
-```
-
-Or,
+Using the example above I will break down the components of an Audit:
-```ruby
-homebrew_package 'emacs'
-```
+* `control_group` - This named block contains all the audits to be performed during the audit phase. During Chef convergence
+ the audits will be collected and ran in a separate phase at the end of the Chef run. Any `control_group` block defined in
+ a recipe that is ran on the node will be performed.
+* `control` - This keyword describes a section of audits to perform. The name here should either be a string describing
+the system under test, or a [Serverspec resource](http://serverspec.org/resource_types.html).
+* `it` - Inside this block you can use [RSpec expectations](https://relishapp.com/rspec/rspec-expectations/docs) to
+write the audits. You can use the Serverspec resources here or regular ruby code. Any raised errors will fail the
+audit.
-The macports provider will still be available, and can be used with the shortcut resource, or by using the `provider` attribute:
+### Output and error handling
-```ruby
-macports_package 'emacs'
-```
-
-Or,
+Output from the audit run will appear in your `Chef::Config[:log_location]`. If an audit fails then Chef will raise
+an error and exit with a non-zero status.
-```ruby
-package 'emacs' do
- provider Chef::Provider::Package::Macports
-end
-```
+### Further reading
-### Providing `homebrew_user`
+More information about the audit mode can be found in its
+[RFC](https://github.com/opscode/chef-rfc/blob/master/rfc035-audit-mode.md)
-Homebrew recommends being ran as a non-root user, whereas Chef recommends being ran with root privileges. The
-`homebrew_package` provider has logic to try and determine which user to install Homebrew packages as.
+# End-User Changes
-By default, the `homebrew_package` provider will try to execute the homebrew command as the owner of the `/usr/local/bin/brew`
-executable. If that executable does not exist, Chef will try to find it by executing `which brew`. If that cannot be
-found, Chef then errors. The Homebrew recommendation is the default install, which will place the executable at
-`/usr/local/bin/brew` owned by a non-root user.
+## OpenBSD Package provider was added
-You can circumvent this by providing the `homebrew_package` a `homebrew_user` attribute, like:
+The package resource on OpenBSD is wired up to use the new OpenBSD package provider to install via pkg_add on OpenBSD systems.
-```ruby
-# provided as a uid
-homebrew_package 'emacs' do
- homebrew_user 1001
-end
+## Case Insensitive URI Handling
-# provided as a string
-homebrew_package 'vim' do
- homebrew_user 'user1'
-end
-```
+Previously, when a URI scheme contained all uppercase letters, Chef
+would reject the URI as invalid. In compliance with RFC3986, Chef now
+treats URI schemes in a case insensitive manner.
-Chef will then execute the Homebrew command as that user. The `homebrew_user` attribute can only be provided to the
-`homebrew_package` resource, not the `package` resource.
+## File Content Verification (RFC 027)
-## DSCL user provider now supports Mac OS X 10.7 and above.
+Per RFC 027, the file and file-like resources now accept a `verify`
+attribute. This attribute accepts a string(shell command) or a ruby
+block (similar to `only_if`) which can be used to verify the contents
+of a rendered template before deploying it to disk.
-DSCL user provider in Chef has supported setting passwords only on Mac OS X 10.6. In this release, Mac OS X versions 10.7 and above are now supported. Support for Mac OS X 10.6 is dropped from the dscl provider since this version is EOLed by Apple.
+## Drop SSL Warnings
+Now that the default for SSL checking is on, no more warning is emitted when SSL
+checking is off.
-In order to support configuring passwords for the users using shadow hashes two new attributes `salt` & `iterations` are added to the user resource. These attributes are required to make the new [SALTED-SHA512-PBKDF2](http://en.wikipedia.org/wiki/PBKDF2) style shadow hashes used in Mac OS X versions 10.8 and above.
+## Multi-package Support
+The `package` provider has been extended to support multiple packages. This
+support is new and and not all subproviders yet support it. Full support for
+`apt` and `yum` has been implemented.
-User resource on Mac supports setting password both using plain-text password or using the shadow hash. You can simply set the `password` attribute to the plain text password to configure the password for the user. However this is not ideal since including plain text passwords in cookbooks (even if they are private) is not a good idea. In order to set passwords using shadow hash you can follow the instructions below based on your Mac OS X version.
+## chef_gem deprecation of installation at compile time
-### Mac OS X 10.7
+A `compile_time` flag has been added to the chef_gem resource to control if it is installed at compile_time or not. The prior behavior has been that this
+resource forces itself to install at compile_time which is problematic since if the gem is native it forces build_essentials and other dependent libraries
+to have to be installed at compile_time in an escalating war of forcing compile time execution. This default was engineered before it was understood that a better
+approach was to lazily require gems inside of provider code which only ran at converge time and that requiring gems in recipe code was bad practice.
-10.7 calculates the password hash using **SALTED-SHA512**. Stored shadow hash length is 68 bytes; first 4 bytes being salt and the next 64 bytes being the shadow hash itself. You can use below code in order to calculate password hashes to be used in `password` attribute on Mac OS X 10.7:
+The default behavior has not changed, but every chef_gem resource will now emit out a warning:
```
-password = "my_awesome_password"
-salt = OpenSSL::Random.random_bytes(4)
-encoded_password = OpenSSL::Digest::SHA512.hexdigest(salt + password)
-shadow_hash = salt.unpack('H*').first + encoded_password
-
-# You can use this value in your recipes as below:
-
-user "my_awesome_user" do
- password "c9b3bd....d843" # Length: 136
-end
+[2015-02-06T13:13:48-08:00] WARN: chef_gem[aws-sdk] chef_gem compile_time installation is deprecated
+[2015-02-06T13:13:48-08:00] WARN: chef_gem[aws-sdk] Please set `compile_time false` on the resource to use the new behavior.
+[2015-02-06T13:13:48-08:00] WARN: chef_gem[aws-sdk] or set `compile_time true` on the resource if compile_time behavior is required.
```
-### Mac OS X 10.8 and above
-10.7 calculates the password hash using **SALTED-SHA512-PBKDF2**. Stored shadow hash length is 128 bytes. In addition to the shadow hash value, `salt` (32 bytes) and `iterations` (integer) is stored on the system. You can use below code in order to calculate password hashes on Mac OS X 10.8 and above:
+The preferred way to fix this is to make every chef_gem resource explicit about compile_time installation (keeping in mind the best-practice to default to false
+unless there is a reason):
-```
-password = "my_awesome_password"
-salt = OpenSSL::Random.random_bytes(32)
-iterations = 25000 # Any value above 20k should be fine.
-
-shadow_hash = OpenSSL::PKCS5::pbkdf2_hmac(
- password,
- salt,
- iterations,
- 128,
- OpenSSL::Digest::SHA512.new
-).unpack('H*').first
-salt_value = salt.unpack('H*').first
-
-# You can use this value in your recipes as below:
-
-user "my_awesome_user" do
- password "cbd1a....fc843" # Length: 256
- salt "bd1a....fc83" # Length: 64
- iterations 25000
+```ruby
+chef_gem 'aws-sdk' do
+ compile_time false
end
```
-## `name` Attribute is Required in Metadata
-
-Previously, the `name` attribute in metadata had no effect on the name
-of an uploaded cookbook, instead the name was always inferred from the
-directory basename of the cookbook. The `name` attribute is now
-respected when determining the name of a cookbook. Furthermore, the
-`name` attribute is required when loading/uploading cookbooks.
-
-## http_request resource no longer appends query string
-
-Previously the http_request GET and HEAD requests appended a hard-coded "?message=resource_name"
-query parameter that could not be overridden. That feature has been dropped. Cookbooks that
-actually relied on that should manually add the message query string to the URL they pass to
-the resource.
-
-## Added Chef::Mixin::ShellOut methods to Recipe DSL
-
-Added the ability to use shell_out, shell_out! and shell_out_with_systems_locale in the Recipe
-DSL without needing to explicitly extend/include the mixin.
-
-## Cookbook Synchronizer Cleans Deleted Files
-
-At the start of the Chef client run any files which are in active cookbooks, but are no longer in the
-manifest for the cookbook will be deleted from the cookbook file cache.
-
-## When given an override run list Chef does not clean the file_cache
-
-In order to avoid redownloading the file_cache for all the cookbooks and files that are skipped when an
-override run list is used, when an override run list is set the file cache is not cleaned at all.
-
-## Dropped Support For Ruby 1.8 and 1.9
-
-Ruby 1.8.7, 1.9.1, 1.9.2 and 1.9.3 are no longer supported.
-
-## Changed no_lazy_load config default to True
-
-Previously the default behavior of chef-client was lazily synchronize cookbook files and templates as
-they were actually used. With this setting being true, all the files and templates in a cookbook will
-be synchronized at the beginning of the chef-client run. This avoids the problem where time-sensitive
-URLs in the cookbook manifest may timeout before the `cookbook_file` or `template` resource is actually
-converged. Many users find the lazy behavior confusing as well and expect that the cookbook should
-be fully synchronized at the start.
-
-Some users who distribute large files via cookbooks may see performance issues with this turned on. They
-should disable the setting and go back to the old lazy behavior, or else refactor how they are doing
-file distribution (using `remote_file` to download artifacts from S3 or a similar service is usually a
-better approach, or individual large artifacts could be encapsulated into individual different cookbooks).
-
-## Changed file_staging_uses_destdir config default to True
-
-Staging into the system's tempdir (usually /tmp or /var/tmp) rather than the destination directory can
-cause issues with permissions or available space. It can also become problematic when doing cross-devices
-renames which turn move operations into copy operations (using mv uses a new inode on Unix which avoids
-ETXTBSY exceptions, while cp reuses the inode and can raise that error). Staging the tempfile for the
-Chef file providers into the destination directory solve these problems for users. Windows ACLs on the
-directory will also be inherited correctly.
-
-## Removed Rest-Client dependency
-
-- cookbooks that previously were able to use rest-client directly will now need to install it via `chef_gem "rest-client"`.
-- cookbooks that were broken because of the version of rest-client that chef used will now be able to track and install whatever
- version that they depend on.
-
-## Chef local mode port ranges
-
-- to avoid crashes, by default, Chef will now scan a port range and take the first available port from 8889-9999.
-- to change this behavior, you can pass --chef-zero-port=PORT_RANGE (for example, 10,20,30 or 10000-20000) or modify Chef::Config.chef_zero.port to be a port string, an enumerable of ports, or a single port number.
-
-## Knife now logs to stderr
-
-Informational messages from knife are now sent to stderr, allowing you to pipe the output of knife to other commands without having to filter these messages out.
-
-## Enhance `data_bag_item` to interact with encrypted data bag items
-
-The `data_bag_item` dsl method can be used to load encrypted data bag items when an additional `secret` String parameter is included.
-If no `secret` is provided but the data bag item is encrypted, `Chef::Config[:encrypted_data_bag_secret]` will be checked.
-
-## 'group' provider on OSX properly uses 'dscl' to determine existing groups
-
-On OSX, the 'group' provider would use 'etc' to determine existing groups,
-but 'dscl' to add groups, causing broken idempotency if something existed
-in /etc/group. The provider now uses 'dscl' for both idempotenty checks and
-modifications.
-
-## Windows Service Startup Type
-
-When a Windows service is running and Chef stops it, the startup type will change from automatic to manual. A bug previously existed
-that prevented you from changing the startup type to disabled from manual. Using the enable and disable actions will now correctly set
-the service startup type to automatic and disabled, respectively. A new `windows_service` resource has been added that allows you to
-specify the startup type as manual:
+There is also a Chef::Config[:chef_gem_compile_time] flag which has been added. If this is set to true (not recommended) then chef will only emit a single
+warning at the top of the chef-client run:
```
-windows_service "BITS" do
- action :configure_startup
- startup_type :manual
-end
-```
-
-You must use the windows_service resource to utilize the `:configure_startup` action and `startup_type` attribute. The service resource
-does not support them.
-
-## Client-side key generation enabled by default
-When creating a new client via the validation_client account, Chef 11 servers allow the client to generate a key pair locally
-and send the public key to the server, enhancing scalability. This was disabled by default, since client registration would not
-work properly if the remote server implemented only the Chef 10 API.
-
-## CookbookSiteStreamingUploader now uses ssl_verify_mode config option
-The CookbookSiteStreamingUploader now obeys the setting of ssl_verify_mode in the client config. Was previously ignoring the
-config setting and always set to VERIFY_NONE.
-
-## Result filtering on `search` API.
-`search` can take an optional `:filter_result`, which returns search data in the form specified
-by the given Hash. This works analogously to the partial_search method from the [partial_search cookbook](https://supermarket.getchef.com/cookbooks/partial_search),
-with `:filter_result` replacing `:keys`. You can also filter `knife search` results by supplying the `--filter-result`
-or `-f` option and a comma-separated string representation of the filter hash.
-
-## Unforked chef-client interval runs are disabled.
-We no longer allow unforked interval runs of `chef-client`. CLI arguments with flag combinations `--interval SEC --no-fork` or
-`--daemonize --no-fork` will fail immediately. Configuration options `interval` and `daemonize` will also fail with
-error when `client_fork false` is set.
-
-## Interval sleep occurs before converge
-When running chef-client or chef-solo at intervals, the application will perform splay and interval sleep
-before converging chef. (In previous releases, splay sleep occurred first, then convergance, then interval sleep).
-
-## `--dry-run` option for knife cookbook site share
-"knife cookbook site share" command now accepts a new command line option `--dry-run`. When this option is specified, command
- will display the files that are about to be uploaded to the Supermarket.
-
-## New cookbook metadata attributes for Supermarket
-Cookbook metadata now accepts `source_url` and `issues_url` that should point to the source code of the cookbook and
- the issue tracker of the cookbook. These attributes are being used by Supermarket.
-
-## CHEF RFC-017 - File Specificity Overhaul
-RFC-017 has two great advantages:
-1. It makes it easy to create cookbooks by removing the need for `default/` folder when adding templates and cookbook files.
-2. It enables the configuring a custom lookup logic when Chef is attempting to find cookbook files.
-
-You can read more about this RFC [here](https://github.com/opscode/chef-rfc/blob/master/rfc017-file-specificity.md).
-
-## JSON output for `knife status`
-`knife status` command now supports two additional output formats:
-
-1. `--medium`: Includes normal attributes in the output and presents the output as JSON.
-1. `--long`: Includes all attributes in the output and presents the output as JSON.
-
-## AIX Service Provider Support
-
-Chef 12 now supports managing services on AIX, using both the SRC (Subsystem Resource Controller) as well as the BSD-style init system. SRC is the default; the BSD-style provider can be selected using `Chef::Provider::Service::AixInit`.
-
-The SRC service provider will manage services as well as service groups. However, because SRC has no standard mechanism for starting services on system boot, `action :enable` and `action :disable` are not supported for SRC services. You may use the `execute` resource to invoke `mkitab`, for example, to add lines to `/etc/inittab` with the right parameters.
-
-## `guard_interpreter` attribute for `powershell_script` defaults to `:powershell_script`
-The default `guard_interpreter` attribute for the `powershell_script` resource is `:powershell_script`. This means that the
-64-bit version of the PowerShell shell will be used to evaluate strings supplied to the `not_if` or `only_if` attributes of the
-resource. Prior to this release, the default value was `:default`, which used the 32-bit version of the `cmd.exe` shell to evaluate the guard.
-
-If you are using guard expressions with the `powershell_script` resource in your recipes, you should override the
-`guard_interpreter` attribute to restore the behavior of guards for this resource in Chef 11:
-
-```ruby
-# The not_if will be evaluated with 64-bit PowerShell by default,
-# So override it to :default if your guard assumes 32-bit cmd.exe
-powershell_script 'make_safe_backup' do
- guard_interpreter :default # Chef 11 behavior
- code 'cp ~/data/nodes.json $env:systemroot/system32/data/nodes.bak'
-
- # cmd.exe (batch) guard below behaves differently in 32-bit vs. 64-bit processes
- not_if 'if NOT EXIST %SYSTEMROOT%\\system32\\data\\nodes.bak exit /b 1'
-end
+[2015-02-06T13:27:35-08:00] WARN: setting chef_gem_compile_time to true is deprecated
```
-If the code in your guard expression does not rely on the `cmd.exe` interpreter, e.g. it simply executes a process that should
-return an exit code such as `findstr datafile sentinelvalue`, and does not rely on being executed from a 32-bit process, then it
-should function identically when executed from the PowerShell shell and it is not necessary to override the attribute
-to`:default` to restore Chef 11 behavior.
-
-Note that with this change guards for the `powershell_script` resource will also inherit some attributes like `:architecture`, `:cwd`,
-`:environment`, and `:path`.
-
-## `guard_interpreter` attribute for `batch` resource defaults to `:batch`
-
-The default `guard_interpreter` attribute for the `batch` resource is now `:batch`. This means that the
-64-bit version of the `cmd.exe` shell will be used to evaluate strings supplied to the `not_if` or `only_if` attributes of the
-resource. Prior to this release, the default value was `:default`, which used the 32-bit version of the `cmd.exe` shell to evaluate the guard.
+It will behave like Chef 10 and Chef 11 and will default chef_gem to compile_time installations and will suppress
+subsequent warnings in the chef-client run.
-Note that with this change guards for the `batch` resource will also inherit some attributes like `:architecture`, `:cwd`,
-`:environment`, and `:path`.
+If this setting is changed to 'false' then it will adopt Chef-13 style behavior and will default all chef_gem installs to not run at compile_time by default. This
+may break existing cookbooks.
-Unless the code you supply to guard attributes (`only_if` and `not_if`) has logic that requires that the 32-bit version of
-`cmd.exe` be used to evaluate the guard or you need to avoid the inheritance behavior of guard options, that code should function identically in this release of Chef and Chef 11 releases.
+* All existing cookbooks which require compile_time true MUST be updated to be explicit about this setting.
+* To be considered high quality, cookbooks which require compile_time true MUST be rewritten to avoid this setting.
+* All existing cookbooks which do not require compile_time true SHOULD be updated to be explicit about this setting.
-If an assumption of a 32-bit process for guard evaluation exists in your code, you can obtain the equivalent of Chef 11's 32-bit
-process behavior by supplying an architecture attribute to the guard as follows:
+For cookbooks that need to maintain backwards compatibility a `respond_to?` check should be used:
-```ruby
-# The not_if will be evaluated with 64-bit cmd.exe by default,
-# so you can verride it with the :architecture guard option to
-# make it 32-bit as it is in Chef 11
-batch 'make_safe_backup' do
- code 'copy %USERPROFILE%\\data\\nodes.json %SYSTEMROOT%\\system32\\data\\nodes.bak'
-
- # cmd.exe (batch) guard code below behaves differently in 32-bit vs. 64-bit processes
- not_if 'if NOT EXIST %SYSTEMROOT%\\system32\\data\\nodes.bak exit /b 1', :architecture => :i386
-end
```
-
-If in addition to the 32-bit process assumption you also need to avoid the inheritance behavior, you can revert completely to
-the Chef 11's 32-bit process, no inheritance behavior by supplying `:default` for the `guard_interpreter` as follows:
-
-```ruby
-# The not_if will be evaluated with 64-bit cmd.exe by default,
-# so override it to :default if your guard assumes 32-bit cmd.exe
-batch 'make_safe_backup' do
- guard_interpreter :default # Revert to Chef 11 behavior
- code 'copy %USERPROFILE%\\data\\nodes.json %SYSTEMROOT%\\system32\\data\\nodes.bak'
-
- # cmd.exe (batch) guard code below behaves differently in 32-bit vs. 64-bit processes
- not_if 'if NOT EXIST %SYSTEMROOT%\\system32\\data\\nodes.bak exit /b 1'
+chef_gem 'aws-sdk' do
+ compile_time false if respond_to?(:compile_time)
end
```
-## Chef Client logs events to Windows Event Log on Windows
-
-Chef 12 will log a small set of events to Windows Event Log. This feature is enabled by default, and can be disabled by the new config option `disable_event_logger`.
-
-Events by default will be logged to the "Application" event log on Windows. Chef will log event when:
-* Run starts
-* Run completes
-* Run fails
-
-Information about these events can be found in `Chef::EventDispatch::Base`.
-
-## Resource and Provider Resolution changes
+## Knife Bootstrap Validatorless Bootstraps and Chef Vault integration
-Resource resolution and provider resolution has been made more dynamic in Chef-12. The `provides` syntax on the
-Chef::Resource DSL (which has existed for 4 years) has been expanded to use platform_family and os and has been applied
-to most resources. This does early switching at compile time between different resources based on the node data returned
-from ohai. The effect is that previously the package resource on a CentOS machine invoked via `package "foo"` would be
-an instance of Chef::Resource::Package but would use the Chef::Provider::Package::Yum provider. After the changes to
-the resources the resource will be an instance of Chef::Resource::YumPackage and will do the correct validation for
-the yum package provider.
+The knife bootstrap command now supports validatorless bootstraps. This can be enabled via deleting the validation key.
+When the validation key is not present, knife bootstrap will use the user key in order to create a client for the node
+being bootstrapped. It will also then create a node object and set the environment, run_list, initial attributes, etc (avoiding
+the problem of the first chef-client failing and not saving the node's run_list correctly).
-For the service resource it uses late validation via the Chef::ProviderResolver and will dynamically select which
-service provider to use at package converge time right before the service provider actions are invoked. This means
-that if Chef is used to install systemd (or alternatively to remove it) then the ProviderResolver will be invoked
-and will be able to determine the proper provider to start the service. It also allows for multiple providers to
-be invoked for a resource on a case-by-case basis. The old static one-to-one Chef::Platform provider mapping was
-inflexible since it cannot handle the case where an admin installs or removes a subsystem from a distro, and cannot
-handle the case where there may be multiple providers that handle different kinds of services (e.g. Upstart, SysV,
-etc). This fixes the Ubuntu 14.04 service resource problems, and can handle arbitrarily complicated future distro
-and administrative preferences dynamically.
+Also knife vault integration has been added so that knife bootstrap can use the client key to add chef vault items to
+the node, reducing the number of steps necessary to bootstrap a node with chef vault.
+There is no support for validatorless bootstraps when the node object has been precreated by the user beforehand, as part
+of the process any old node or client will be deleted when doing validatorless bootstraps. The old process with the validation
+key still works for this use case. The setting of the run_list, environment and json attributes first via knife bootstrap
+should mitigate some of the need to precreate the node object by hand first.
diff --git a/appveyor.yml b/appveyor.yml
index d5751e0054..4efdeadf84 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: "12-stable-{build}"
+version: "master-{build}"
os: Windows Server 2012
platform:
@@ -29,4 +29,5 @@ build_script:
- bundle install
test_script:
+ - SET SPEC_OPTS=--format progress
- bundle exec rake spec
diff --git a/bin/shef b/bin/shef
deleted file mode 100755
index 0862198e53..0000000000
--- a/bin/shef
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env ruby
-#
-# ./chef-shell - Run the Chef REPL (Shell)
-#
-# Author:: Daniel DeLeo (<dan@kallistec.com>)
-# Copyright:: Copyright (c) 2009
-# 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.
-
-begin
- require "rubygems"
-rescue LoadError
-end
-
-require "irb"
-require "irb/completion"
-require 'irb/ext/save-history'
-
-$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
-
-require "chef/shell"
-
-Chef::Log.warn("DEPRECATED: The 'shef' program is renamed to 'chef-shell'")
-Shell.start
diff --git a/chef-x86-mingw32.gemspec b/chef-x86-mingw32.gemspec
index a35ec5d63c..0364e07827 100644
--- a/chef-x86-mingw32.gemspec
+++ b/chef-x86-mingw32.gemspec
@@ -18,4 +18,6 @@ gemspec.add_dependency "win32-eventlog", "0.6.1"
gemspec.extensions << "ext/win32-eventlog/Rakefile"
gemspec.files += %w(ext/win32-eventlog/Rakefile ext/win32-eventlog/chef-log.man)
+gemspec.executables += %w( chef-service-manager chef-windows-service )
+
gemspec
diff --git a/chef.gemspec b/chef.gemspec
index 38b3b2193e..d32e0005d6 100644
--- a/chef.gemspec
+++ b/chef.gemspec
@@ -30,26 +30,24 @@ 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", "~> 3.2"
+ s.add_dependency "chef-zero", "~> 4.0"
s.add_dependency "pry", "~> 0.9"
s.add_dependency 'plist', '~> 3.1.0'
+ # 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.2" }
+ s.add_dependency "rspec_junit_formatter", "~> 0.2.0"
+ s.add_dependency "serverspec", "~> 2.7"
+ s.add_dependency "specinfra", "~> 2.10"
+
s.add_development_dependency "rack"
# Rake 10.2 drops Ruby 1.8 support
s.add_development_dependency "rake", "~> 10.1.0"
- # rspec_junit_formatter 0.2.0 drops ruby 1.8.7 support
- s.add_development_dependency "rspec_junit_formatter", "~> 0.1.0"
-
- %w(rspec-core rspec-expectations rspec-mocks).each { |gem| s.add_development_dependency gem, "~> 2.14.0" }
-
s.bindir = "bin"
- # chef-service-manager is a windows only executable.
- # However gemspec doesn't give us a way to have this executable only
- # on windows. So we're including this in all platforms.
- s.executables = %w( chef-client chef-solo knife chef-shell shef chef-apply chef-service-manager chef-windows-service )
+ s.executables = %w( chef-client chef-solo knife chef-shell chef-apply )
s.require_path = 'lib'
s.files = %w(Rakefile LICENSE README.md CONTRIBUTING.md) + Dir.glob("{distro,lib,tasks,spec}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
diff --git a/distro/common/html/_sources/ctl_chef_client.txt b/distro/common/html/_sources/ctl_chef_client.txt
index 99b0037154..f0af14e090 100644
--- a/distro/common/html/_sources/ctl_chef_client.txt
+++ b/distro/common/html/_sources/ctl_chef_client.txt
@@ -10,7 +10,7 @@ chef-client
Options
=====================================================
-.. include:: ../../includes_ctl_chef_client/includes_ctl_chef_client_11-8_options.rst
+.. include:: ../../release_chef_12-0/includes_ctl_chef_client_options.rst
Run with Elevated Privileges
=====================================================
diff --git a/distro/common/html/_sources/ctl_chef_server.txt b/distro/common/html/_sources/ctl_chef_server.txt
index bc55662531..a7f6ce81e7 100644
--- a/distro/common/html/_sources/ctl_chef_server.txt
+++ b/distro/common/html/_sources/ctl_chef_server.txt
@@ -1,5 +1,5 @@
=====================================================
-chef-server-ctl
+|chef server ctl| (executable)
=====================================================
.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server.rst
@@ -28,31 +28,25 @@ install
=====================================================
.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_install.rst
-.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_install_table.rst
-
-master-recover
-=====================================================
-.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_master_recover.rst
-
-org-associate
-=====================================================
-.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_associate.rst
-
**Syntax**
-.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_associate_syntax.rst
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_install_syntax.rst
-**Examples**
-
-.. code-block:: bash
-
- $ chef-server-ctl org-associate prod john_smith
+**Options**
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_install_options.rst
-.. code-block:: bash
+Use Downloads
+-----------------------------------------------------
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_install_features_download.rst
- $ chef-server-ctl org-associate preprod testmaster
+Use Local Packages
+-----------------------------------------------------
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_install_features_manual.rst
+master-recover
+=====================================================
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_master_recover.rst
org-create
=====================================================
@@ -82,7 +76,6 @@ org-create
$ chef-server-ctl org-create dev Development -f /tmp/id-dev.key
-
org-delete
=====================================================
.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_delete.rst
@@ -102,46 +95,71 @@ org-delete
$ chef-server-ctl org-delete pedant-testing-org
+org-list
+=====================================================
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_list.rst
+
+**Syntax**
+
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_list_syntax.rst
-org-disassociate
+**Options**
+
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_list_options.rst
+
+org-show
+=====================================================
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_show.rst
+
+**Syntax**
+
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_show_syntax.rst
+
+org-user-add
=====================================================
-.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_disassociate.rst
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_user_add.rst
**Syntax**
-.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_disassociate_syntax.rst
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_user_add_syntax.rst
+
+**Options**
+
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_user_add_options.rst
**Examples**
.. code-block:: bash
- $ chef-server-ctl org-disassociate prod john_smith
+ $ chef-server-ctl org-user-add prod john_smith
+
+.. code-block:: bash
+ $ chef-server-ctl org-user-add preprod testmaster
.. code-block:: bash
- $ chef-server-ctl org-disassociate prod testmaster
+ $ chef-server-ctl org-user-add dev grantmc --admin
-org-list
+org-user-remove
=====================================================
-.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_list.rst
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_user_remove.rst
**Syntax**
-.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_list_syntax.rst
+.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_user_remove_syntax.rst
-**Options**
+**Examples**
-.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_list_options.rst
+.. code-block:: bash
-org-show
-=====================================================
-.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_show.rst
+ $ chef-server-ctl org-user-remove prod john_smith
-**Syntax**
+.. code-block:: bash
+
+ $ chef-server-ctl org-user-remove prod testmaster
-.. include:: ../../includes_ctl_chef_server/includes_ctl_chef_server_org_show_syntax.rst
password
=====================================================
diff --git a/distro/common/html/_sources/ctl_chef_solo.txt b/distro/common/html/_sources/ctl_chef_solo.txt
index a80c8bad3c..99f7b919de 100644
--- a/distro/common/html/_sources/ctl_chef_solo.txt
+++ b/distro/common/html/_sources/ctl_chef_solo.txt
@@ -8,7 +8,7 @@ chef-solo
Options
=====================================================
-.. include:: ../../includes_ctl_chef_solo/includes_ctl_chef_solo_options.rst
+.. include:: ../../release_chef_12-0/includes_ctl_chef_solo_options.rst
Examples
=====================================================
diff --git a/distro/common/html/_sources/knife_bootstrap.txt b/distro/common/html/_sources/knife_bootstrap.txt
index ee275b58f5..29af753b23 100644
--- a/distro/common/html/_sources/knife_bootstrap.txt
+++ b/distro/common/html/_sources/knife_bootstrap.txt
@@ -16,7 +16,7 @@ Options
=====================================================
.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
-.. include:: ../../includes_knife/includes_knife_bootstrap_options.rst
+.. include:: ../../release_chef_12-0/includes_knife_bootstrap_options.rst
Custom Templates
=====================================================
diff --git a/distro/common/html/_sources/knife_cookbook_site.txt b/distro/common/html/_sources/knife_cookbook_site.txt
index 92fadaa819..d1b03f2fa0 100644
--- a/distro/common/html/_sources/knife_cookbook_site.txt
+++ b/distro/common/html/_sources/knife_cookbook_site.txt
@@ -98,7 +98,7 @@ Syntax
Options
-----------------------------------------------------
-.. include:: ../../includes_knife/includes_knife_site_cookbook_share_options.rst
+.. include:: ../../release_chef_12-0/includes_knife_site_cookbook_share_options.rst
Examples
-----------------------------------------------------
diff --git a/distro/common/html/_sources/knife_data_bag.txt b/distro/common/html/_sources/knife_data_bag.txt
index 32888e6f8b..369baab2b7 100644
--- a/distro/common/html/_sources/knife_data_bag.txt
+++ b/distro/common/html/_sources/knife_data_bag.txt
@@ -20,7 +20,7 @@ Syntax
Options
-----------------------------------------------------
-.. include:: ../../includes_knife/includes_knife_data_bag_create_options.rst
+.. include:: ../../release_chef_12-0/includes_knife_data_bag_create_options.rst
Examples
-----------------------------------------------------
@@ -64,7 +64,7 @@ Syntax
Options
-----------------------------------------------------
-.. include:: ../../includes_knife/includes_knife_data_bag_edit_options.rst
+.. include:: ../../release_chef_12-0/includes_knife_data_bag_edit_options.rst
Examples
-----------------------------------------------------
@@ -88,7 +88,7 @@ Syntax
Options
-----------------------------------------------------
-.. include:: ../../includes_knife/includes_knife_data_bag_from_file_options.rst
+.. include:: ../../release_chef_12-0/includes_knife_data_bag_from_file_options.rst
Examples
-----------------------------------------------------
@@ -133,7 +133,7 @@ Syntax
Options
-----------------------------------------------------
-.. include:: ../../includes_knife/includes_knife_data_bag_show_options.rst
+.. include:: ../../release_chef_12-0/includes_knife_data_bag_show_options.rst
Examples
-----------------------------------------------------
diff --git a/distro/common/html/_sources/knife_status.txt b/distro/common/html/_sources/knife_status.txt
index 194b985f67..7f00826b96 100644
--- a/distro/common/html/_sources/knife_status.txt
+++ b/distro/common/html/_sources/knife_status.txt
@@ -12,7 +12,7 @@ Options
=====================================================
.. note:: Review the list of :doc:`common options </knife_common_options>` available to this (and all) |knife| subcommands and plugins.
-.. include:: ../../includes_knife/includes_knife_status_options.rst
+.. include:: ../../release_chef_12-0/includes_knife_status_options.rst
Examples
=====================================================
diff --git a/distro/common/html/_static/searchtools.js b/distro/common/html/_static/searchtools.js
index 6e1f06bd1b..fec94539f9 100644
--- a/distro/common/html/_static/searchtools.js
+++ b/distro/common/html/_static/searchtools.js
@@ -594,7 +594,7 @@ var Search = {
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
- * words. the first one is used to find the occurance, the
+ * words. the first one is used to find the occurrence, the
* latter for highlighting it.
*/
makeSearchSummary : function(text, keywords, hlwords) {
diff --git a/distro/common/html/ctl_chef_client.html b/distro/common/html/ctl_chef_client.html
index 7bb43d6878..dbdca11487 100644
--- a/distro/common/html/ctl_chef_client.html
+++ b/distro/common/html/ctl_chef_client.html
@@ -71,10 +71,8 @@
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">-A</span></tt>, <tt class="docutils literal"><span class="pre">--fatal-windows-admin-check</span></tt></dt>
<dd>Use to cause a chef-client run to fail when the chef-client does not have administrator privileges in Microsoft Windows.</dd>
-<dt><tt class="docutils literal"><span class="pre">-c</span> <span class="pre">CONFIG</span></tt>, <tt class="docutils literal"><span class="pre">--config</span> <span class="pre">CONFIG</span></tt></dt>
-<dd>The configuration file to use.</dd>
<dt><tt class="docutils literal"><span class="pre">--chef-zero-port</span> <span class="pre">PORT</span></tt></dt>
-<dd>The port on which chef-zero will listen.</dd>
+<dd>The port on which chef-zero will listen. If a port is not specified&#8212;individually, as range of ports, or from the <tt class="docutils literal"><span class="pre">chef_zero.port</span></tt> setting in the client.rb file&#8212;the chef-client will scan for ports between 8889-9999 and will pick the first port that is available.</dd>
<dt><tt class="docutils literal"><span class="pre">-F</span> <span class="pre">FORMAT</span></tt>, <tt class="docutils literal"><span class="pre">--format</span> <span class="pre">FORMAT</span></tt></dt>
<dd><p class="first">The output format: <tt class="docutils literal"><span class="pre">doc</span></tt> (default) or <tt class="docutils literal"><span class="pre">min</span></tt>.</p>
<p>Use <tt class="docutils literal"><span class="pre">doc</span></tt> to print the progress of the chef-client run using full strings that display a summary of updates as they occur.</p>
@@ -90,9 +88,53 @@
<dt><tt class="docutils literal"><span class="pre">-h</span></tt>, <tt class="docutils literal"><span class="pre">--help</span></tt></dt>
<dd>Shows help for the command.</dd>
<dt><tt class="docutils literal"><span class="pre">-i</span> <span class="pre">SECONDS</span></tt>, <tt class="docutils literal"><span class="pre">--interval</span> <span class="pre">SECONDS</span></tt></dt>
-<dd>The frequency (in seconds) at which the chef-client runs. Default value: <tt class="docutils literal"><span class="pre">1800</span></tt>.</dd>
+<dd>The frequency (in seconds) at which the chef-client runs. When the chef-client is run at intervals, <tt class="docutils literal"><span class="pre">--splay</span></tt> and <tt class="docutils literal"><span class="pre">--interval</span></tt> values are applied before the chef-client run. Default value: <tt class="docutils literal"><span class="pre">1800</span></tt>.</dd>
<dt><tt class="docutils literal"><span class="pre">-j</span> <span class="pre">PATH</span></tt>, <tt class="docutils literal"><span class="pre">--json-attributes</span> <span class="pre">PATH</span></tt></dt>
-<dd>The path to a file that contains JSON data.</dd>
+<dd><p class="first">The path to a file that contains JSON data.</p>
+<p>Use this option to define a <tt class="docutils literal"><span class="pre">run_list</span></tt> object. For example, a JSON file similar to:</p>
+<div class="highlight-javascript"><div class="highlight"><pre><span class="s2">&quot;run_list&quot;</span><span class="o">:</span> <span class="p">[</span>
+ <span class="s2">&quot;recipe[base]&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;recipe[foo]&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;recipe[bar]&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;role[webserver]&quot;</span>
+<span class="p">],</span>
+</pre></div>
+</div>
+<p>may be used by running <tt class="docutils literal"><span class="pre">chef-client</span> <span class="pre">-j</span> <span class="pre">path/to/file.json</span></tt>.</p>
+<p>In certain situations this option may be used to update <tt class="docutils literal"><span class="pre">normal</span></tt> attributes.</p>
+<div class="last admonition warning">
+<p class="first admonition-title">Warning</p>
+<p>Any other attribute type that is contained in this JSON file will be treated as a <tt class="docutils literal"><span class="pre">normal</span></tt> attribute. For example, attempting to update <tt class="docutils literal"><span class="pre">override</span></tt> attributes using the <tt class="docutils literal"><span class="pre">-j</span></tt> option:</p>
+<div class="highlight-javascript"><div class="highlight"><pre><span class="p">{</span>
+ <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;dev-99&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;Install some stuff&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;override_attributes&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;apptastic&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;enable_apptastic&quot;</span><span class="o">:</span> <span class="s2">&quot;false&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;apptastic_tier_name&quot;</span><span class="o">:</span> <span class="s2">&quot;dev-99.bomb.com&quot;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>will result in a node object similar to:</p>
+<div class="last highlight-javascript"><div class="highlight"><pre><span class="p">{</span>
+ <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;maybe-dev-99&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;normal&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;dev-99&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;Install some stuff&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;override_attributes&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;apptastic&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;enable_apptastic&quot;</span><span class="o">:</span> <span class="s2">&quot;false&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;apptastic_tier_name&quot;</span><span class="o">:</span> <span class="s2">&quot;dev-99.bomb.com&quot;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+</div>
+</dd>
<dt><tt class="docutils literal"><span class="pre">-k</span> <span class="pre">KEY_FILE</span></tt>, <tt class="docutils literal"><span class="pre">--client_key</span> <span class="pre">KEY_FILE</span></tt></dt>
<dd>The location of the file which contains the client key. Default value: <tt class="docutils literal"><span class="pre">/etc/chef/client.pem</span></tt>.</dd>
<dt><tt class="docutils literal"><span class="pre">-K</span> <span class="pre">KEY_FILE</span></tt>, <tt class="docutils literal"><span class="pre">--validation_key</span> <span class="pre">KEY_FILE</span></tt></dt>
@@ -106,15 +148,21 @@
<dt><tt class="docutils literal"><span class="pre">-N</span> <span class="pre">NODE_NAME</span></tt>, <tt class="docutils literal"><span class="pre">--node-name</span> <span class="pre">NODE_NAME</span></tt></dt>
<dd>The name of the node.</dd>
<dt><tt class="docutils literal"><span class="pre">-o</span> <span class="pre">RUN_LIST_ITEM</span></tt>, <tt class="docutils literal"><span class="pre">--override-runlist</span> <span class="pre">RUN_LIST_ITEM</span></tt></dt>
-<dd>Replace the current run list with the specified items.</dd>
+<dd>Replace the current run list with the specified items. This option will not clear the list of cookbooks (and related files) that is cached on the node.</dd>
<dt><tt class="docutils literal"><span class="pre">--once</span></tt></dt>
<dd>Use to run the chef-client only once and to cancel <tt class="docutils literal"><span class="pre">interval</span></tt> and <tt class="docutils literal"><span class="pre">splay</span></tt> options.</dd>
<dt><tt class="docutils literal"><span class="pre">-P</span> <span class="pre">PID_FILE</span></tt>, <tt class="docutils literal"><span class="pre">--pid</span> <span class="pre">PID_FILE</span></tt></dt>
<dd>The location in which a process identification number (pid) is saved. An executable, when started as a daemon, will write the pid to the specified file. Default value: <tt class="docutils literal"><span class="pre">/tmp/name-of-executable.pid</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-r</span> <span class="pre">RUN_LIST_ITEM</span></tt>, <tt class="docutils literal"><span class="pre">--runlist</span> <span class="pre">RUN_LIST_ITEM</span></tt></dt>
+<dd>Use to permanently replace the current run-list with the specified run-list items.</dd>
<dt><tt class="docutils literal"><span class="pre">-R</span></tt>, <tt class="docutils literal"><span class="pre">--enable-reporting</span></tt></dt>
<dd>Use to enable Chef reporting, which performs data collection during a chef-client run.</dd>
+<dt><tt class="docutils literal"><span class="pre">RECIPE_FILE</span></tt></dt>
+<dd>The path to a recipe. For example, if a recipe file is in the current directory, use <tt class="docutils literal"><span class="pre">recipe_file.rb</span></tt>. This is typically used with the <tt class="docutils literal"><span class="pre">--local-mode</span></tt> option.</dd>
+<dt><tt class="docutils literal"><span class="pre">--run-lock-timeout</span> <span class="pre">SECONDS</span></tt></dt>
+<dd>The amount of time (in seconds) to wait for a chef-client run to finish. Default value: not set (indefinite). Set to <tt class="docutils literal"><span class="pre">0</span></tt> to cause a second chef-client to exit immediately.</dd>
<dt><tt class="docutils literal"><span class="pre">-s</span> <span class="pre">SECONDS</span></tt>, <tt class="docutils literal"><span class="pre">--splay</span> <span class="pre">SECONDS</span></tt></dt>
-<dd>A number (in seconds) to add to the <tt class="docutils literal"><span class="pre">interval</span></tt> that is used to determine the frequency of chef-client runs. This number can help prevent server load when there are many clients running at the same time.</dd>
+<dd>A number (in seconds) to add to the <tt class="docutils literal"><span class="pre">interval</span></tt> that is used to determine the frequency of chef-client runs. This number can help prevent server load when there are many clients running at the same time. When the chef-client is run at intervals, <tt class="docutils literal"><span class="pre">--splay</span></tt> and <tt class="docutils literal"><span class="pre">--interval</span></tt> values are applied before the chef-client run.</dd>
<dt><tt class="docutils literal"><span class="pre">-S</span> <span class="pre">CHEF_SERVER_URL</span></tt>, <tt class="docutils literal"><span class="pre">--server</span> <span class="pre">CHEF_SERVER_URL</span></tt></dt>
<dd>The URL for the Chef server.</dd>
<dt><tt class="docutils literal"><span class="pre">-u</span> <span class="pre">USER</span></tt>, <tt class="docutils literal"><span class="pre">--user</span> <span class="pre">USER</span></tt></dt>
diff --git a/distro/common/html/ctl_chef_server.html b/distro/common/html/ctl_chef_server.html
index 8c68c21cd0..c5bc97af08 100644
--- a/distro/common/html/ctl_chef_server.html
+++ b/distro/common/html/ctl_chef_server.html
@@ -6,7 +6,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>chef-server-ctl &mdash; chef-client Man Pages</title>
+ <title>chef-server-ctl (executable) &mdash; chef-client Man Pages</title>
<link rel="stylesheet" href="_static/guide.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
@@ -39,8 +39,8 @@
<div class="body">
- <div class="section" id="chef-server-ctl">
-<h1>chef-server-ctl<a class="headerlink" href="#chef-server-ctl" title="Permalink to this headline">¶</a></h1>
+ <div class="section" id="chef-server-ctl-executable">
+<h1>chef-server-ctl (executable)<a class="headerlink" href="#chef-server-ctl-executable" title="Permalink to this headline">¶</a></h1>
<p>The Chef server includes a command-line utility named chef-server-ctl. This command-line tool is used to start and stop individual services, reconfigure the Chef server, run chef-pedant, and then tail Chef server log files.</p>
<div class="section" id="backup-recover">
<h2>backup-recover<a class="headerlink" href="#backup-recover" title="Permalink to this headline">¶</a></h2>
@@ -132,11 +132,21 @@
<div class="section" id="install">
<h2>install<a class="headerlink" href="#install" title="Permalink to this headline">¶</a></h2>
<p>The <tt class="docutils literal"><span class="pre">install</span></tt> subcommand is used to install premium features of the Chef server: Chef management console, Chef analytics, chef-client run reporting, high availability configurations, Chef push jobs, and Chef server replication.</p>
+<p><strong>Syntax</strong></p>
<p>This subcommand has the following syntax:</p>
-<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl install name_of_premium_feature
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl install name_of_premium_feature <span class="o">(</span>options<span class="o">)</span>
</pre></div>
</div>
<p>where <tt class="docutils literal"><span class="pre">name_of_premium_feature</span></tt> represents the command line value associated with the premium feature:</p>
+<p><strong>Options</strong></p>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">--path</span> <span class="pre">PATH</span></tt></dt>
+<dd>Use to specify the location of a package. This option is not required when packages are downloaded from <a class="reference external" href="https://packagecloud.io/">https://packagecloud.io/</a>.</dd>
+</dl>
+<div class="section" id="use-downloads">
+<h3>Use Downloads<a class="headerlink" href="#use-downloads" title="Permalink to this headline">¶</a></h3>
+<p>The <tt class="docutils literal"><span class="pre">install</span></tt> subcommand downloads packages from <a class="reference external" href="https://packagecloud.io/">https://packagecloud.io/</a> by default. For systems that are not behind a firewall (and have connectivity to <a class="reference external" href="https://packagecloud.io/">https://packagecloud.io/</a>), these packages can be installed as described below.</p>
<table border="1" class="docutils">
<colgroup>
<col width="20%" />
@@ -150,12 +160,16 @@
<tbody valign="top">
<tr class="row-even"><td>Chef Manage</td>
<td><p class="first">Use Chef management console to manage data bags, attributes, run-lists, roles, environments, and cookbooks from a web user interface.</p>
-<p>Run:</p>
+<p>(Front end machines only.) Run:</p>
<div class="highlight-ruby"><div class="highlight"><pre>$ chef-server-ctl install opscode-manage
</pre></div>
</div>
+<p>then:</p>
+<div class="highlight-ruby"><div class="highlight"><pre>$ opscode-manage-ctl reconfigure
+</pre></div>
+</div>
<p>and then:</p>
-<div class="last highlight-ruby"><div class="highlight"><pre>$ opscode-manage-ctl reconfigure
+<div class="last highlight-ruby"><div class="highlight"><pre>$ chef-server-ctl reconfigure
</pre></div>
</div>
</td>
@@ -166,8 +180,12 @@
<div class="highlight-ruby"><div class="highlight"><pre>$ chef-server-ctl install opscode-push-jobs-server
</pre></div>
</div>
+<p>then:</p>
+<div class="highlight-ruby"><div class="highlight"><pre>$ opscode-push-jobs-server-ctl reconfigure
+</pre></div>
+</div>
<p>and then:</p>
-<div class="last highlight-ruby"><div class="highlight"><pre>$ opscode-push-jobs-server-ctl reconfigure
+<div class="last highlight-ruby"><div class="highlight"><pre>$ chef-server-ctl reconfigure
</pre></div>
</div>
</td>
@@ -190,12 +208,16 @@
</tr>
<tr class="row-odd"><td>Reporting</td>
<td><p class="first">Use Chef reporting to keep track of what happens during every chef-client runs across all of the infrastructure being managed by Chef. Run Chef reporting with Chef management console to view reports from a web user interface.</p>
-<p>Run:</p>
+<p>(Front end machines only.) Run:</p>
<div class="highlight-ruby"><div class="highlight"><pre>$ chef-server-ctl install opscode-reporting
</pre></div>
</div>
+<p>then:</p>
+<div class="highlight-ruby"><div class="highlight"><pre>$ opscode-reporting-ctl reconfigure
+</pre></div>
+</div>
<p>and then:</p>
-<div class="last highlight-ruby"><div class="highlight"><pre>$ opscode-reporting-ctl reconfigure
+<div class="last highlight-ruby"><div class="highlight"><pre>$ chef-server-ctl reconfigure
</pre></div>
</div>
</td>
@@ -203,27 +225,23 @@
</tbody>
</table>
</div>
-<div class="section" id="master-recover">
-<h2>master-recover<a class="headerlink" href="#master-recover" title="Permalink to this headline">¶</a></h2>
-<p>The <tt class="docutils literal"><span class="pre">master-recover</span></tt> subcommand is used to force the Chef server to attempt to become the master server. This command is typically run in tandem with the <tt class="docutils literal"><span class="pre">backup-recover</span></tt> subcommand on the back-end peer, unless the back-end peer is no longer available.</p>
-<p>This subcommand has the following syntax:</p>
-<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl master-recover
+<div class="section" id="use-local-packages">
+<h3>Use Local Packages<a class="headerlink" href="#use-local-packages" title="Permalink to this headline">¶</a></h3>
+<p>The <tt class="docutils literal"><span class="pre">install</span></tt> subcommand downloads packages from <a class="reference external" href="https://packagecloud.io/">https://packagecloud.io/</a> by default. For systems that are behind a firewall (and do not have connectivity to <a class="reference external" href="https://packagecloud.io/">https://packagecloud.io/</a>), these packages can be installed manually. First download the package that is appropriate for the platform and save it to a local path. Then run the <tt class="docutils literal"><span class="pre">install</span></tt> command using the <tt class="docutils literal"><span class="pre">--path</span></tt> option to specify the location for the package:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl install NAME_OF_PACKAGE --path /path/to/package
</pre></div>
</div>
-</div>
-<div class="section" id="org-associate">
-<h2>org-associate<a class="headerlink" href="#org-associate" title="Permalink to this headline">¶</a></h2>
-<p>The <tt class="docutils literal"><span class="pre">org-associate</span></tt> subcommand is used to associate a user to an organization.</p>
-<p><strong>Syntax</strong></p>
-<p>This subcommand has the following syntax:</p>
-<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-associate ORG_NAME USER_NAME
+<p>For example:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl install opscode-manage-1.6.2-1.el6.x86_64 --path /home/vagrant
</pre></div>
</div>
-<p><strong>Examples</strong></p>
-<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-associate prod john_smith
-</pre></div>
</div>
-<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-associate preprod testmaster
+</div>
+<div class="section" id="master-recover">
+<h2>master-recover<a class="headerlink" href="#master-recover" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">master-recover</span></tt> subcommand is used to force the Chef server to attempt to become the master server. This command is typically run in tandem with the <tt class="docutils literal"><span class="pre">backup-recover</span></tt> subcommand on the back-end peer, unless the back-end peer is no longer available.</p>
+<p>This subcommand has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl master-recover
</pre></div>
</div>
</div>
@@ -270,22 +288,6 @@
</pre></div>
</div>
</div>
-<div class="section" id="org-disassociate">
-<h2>org-disassociate<a class="headerlink" href="#org-disassociate" title="Permalink to this headline">¶</a></h2>
-<p>The <tt class="docutils literal"><span class="pre">org-disassociate</span></tt> subcommand is used to disassociate a user from an organization.</p>
-<p><strong>Syntax</strong></p>
-<p>This subcommand has the following syntax:</p>
-<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-disassociate ORG_NAME USER_NAME
-</pre></div>
-</div>
-<p><strong>Examples</strong></p>
-<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-disassociate prod john_smith
-</pre></div>
-</div>
-<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-disassociate prod testmaster
-</pre></div>
-</div>
-</div>
<div class="section" id="org-list">
<h2>org-list<a class="headerlink" href="#org-list" title="Permalink to this headline">¶</a></h2>
<p>The <tt class="docutils literal"><span class="pre">org-list</span></tt> subcommand is used to list all of the organizations currently present on the Chef server.</p>
@@ -312,6 +314,47 @@
</pre></div>
</div>
</div>
+<div class="section" id="org-user-add">
+<h2>org-user-add<a class="headerlink" href="#org-user-add" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">org-user-add</span></tt> subcommand is used to add a user to an organization.</p>
+<p><strong>Syntax</strong></p>
+<p>This subcommand has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-user-add ORG_NAME USER_NAME <span class="o">(</span>options<span class="o">)</span>
+</pre></div>
+</div>
+<p><strong>Options</strong></p>
+<p>This subcommand has the following options:</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">--admin</span></tt></dt>
+<dd>Use to add the user to the <tt class="docutils literal"><span class="pre">admins</span></tt> group.</dd>
+</dl>
+<p><strong>Examples</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-user-add prod john_smith
+</pre></div>
+</div>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-user-add preprod testmaster
+</pre></div>
+</div>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-user-add dev grantmc --admin
+</pre></div>
+</div>
+</div>
+<div class="section" id="org-user-remove">
+<h2>org-user-remove<a class="headerlink" href="#org-user-remove" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">org-user-remove</span></tt> subcommand is used to remove a user from an organization.</p>
+<p><strong>Syntax</strong></p>
+<p>This subcommand has the following syntax:</p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-user-remove ORG_NAME USER_NAME
+</pre></div>
+</div>
+<p><strong>Examples</strong></p>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-user-remove prod john_smith
+</pre></div>
+</div>
+<div class="highlight-bash"><div class="highlight"><pre><span class="nv">$ </span>chef-server-ctl org-user-remove prod testmaster
+</pre></div>
+</div>
+</div>
<div class="section" id="password">
<h2>password<a class="headerlink" href="#password" title="Permalink to this headline">¶</a></h2>
<div class="admonition warning">
diff --git a/distro/common/html/ctl_chef_shell.html b/distro/common/html/ctl_chef_shell.html
index b3ae1742f8..e655ec9146 100644
--- a/distro/common/html/ctl_chef_shell.html
+++ b/distro/common/html/ctl_chef_shell.html
@@ -88,7 +88,51 @@
<dt><tt class="docutils literal"><span class="pre">-h</span></tt>, <tt class="docutils literal"><span class="pre">--help</span></tt></dt>
<dd>Shows help for the command.</dd>
<dt><tt class="docutils literal"><span class="pre">-j</span> <span class="pre">PATH</span></tt>, <tt class="docutils literal"><span class="pre">--json-attributes</span> <span class="pre">PATH</span></tt></dt>
-<dd>The path to a file that contains JSON data.</dd>
+<dd><p class="first">The path to a file that contains JSON data.</p>
+<p>Use this option to define a <tt class="docutils literal"><span class="pre">run_list</span></tt> object. For example, a JSON file similar to:</p>
+<div class="highlight-javascript"><div class="highlight"><pre><span class="s2">&quot;run_list&quot;</span><span class="o">:</span> <span class="p">[</span>
+ <span class="s2">&quot;recipe[base]&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;recipe[foo]&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;recipe[bar]&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;role[webserver]&quot;</span>
+<span class="p">],</span>
+</pre></div>
+</div>
+<p>may be used by running <tt class="docutils literal"><span class="pre">chef-client</span> <span class="pre">-j</span> <span class="pre">path/to/file.json</span></tt>.</p>
+<p>In certain situations this option may be used to update <tt class="docutils literal"><span class="pre">normal</span></tt> attributes.</p>
+<div class="last admonition warning">
+<p class="first admonition-title">Warning</p>
+<p>Any other attribute type that is contained in this JSON file will be treated as a <tt class="docutils literal"><span class="pre">normal</span></tt> attribute. For example, attempting to update <tt class="docutils literal"><span class="pre">override</span></tt> attributes using the <tt class="docutils literal"><span class="pre">-j</span></tt> option:</p>
+<div class="highlight-javascript"><div class="highlight"><pre><span class="p">{</span>
+ <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;dev-99&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;Install some stuff&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;override_attributes&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;apptastic&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;enable_apptastic&quot;</span><span class="o">:</span> <span class="s2">&quot;false&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;apptastic_tier_name&quot;</span><span class="o">:</span> <span class="s2">&quot;dev-99.bomb.com&quot;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>will result in a node object similar to:</p>
+<div class="last highlight-javascript"><div class="highlight"><pre><span class="p">{</span>
+ <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;maybe-dev-99&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;normal&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;dev-99&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;Install some stuff&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;override_attributes&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;apptastic&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;enable_apptastic&quot;</span><span class="o">:</span> <span class="s2">&quot;false&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;apptastic_tier_name&quot;</span><span class="o">:</span> <span class="s2">&quot;dev-99.bomb.com&quot;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+</div>
+</dd>
<dt><tt class="docutils literal"><span class="pre">-l</span> <span class="pre">LEVEL</span></tt>, <tt class="docutils literal"><span class="pre">--log-level</span> <span class="pre">LEVEL</span></tt></dt>
<dd>The level of logging that will be stored in a log file.</dd>
<dt><tt class="docutils literal"><span class="pre">-s</span></tt>, <tt class="docutils literal"><span class="pre">--solo</span></tt></dt>
diff --git a/distro/common/html/ctl_chef_solo.html b/distro/common/html/ctl_chef_solo.html
index f32136e7c4..2382fed80a 100644
--- a/distro/common/html/ctl_chef_solo.html
+++ b/distro/common/html/ctl_chef_solo.html
@@ -66,11 +66,13 @@
<dt><tt class="docutils literal"><span class="pre">-c</span> <span class="pre">CONFIG</span></tt>, <tt class="docutils literal"><span class="pre">--config</span> <span class="pre">CONFIG</span></tt></dt>
<dd>The configuration file to use.</dd>
<dt><tt class="docutils literal"><span class="pre">-d</span></tt>, <tt class="docutils literal"><span class="pre">--daemonize</span></tt></dt>
-<dd>Use to run the executable as a daemon. This option is only available on machines that run in UNIX or Linux environments. For machines that are running Microsoft Windows that require similar functionality, use the <tt class="docutils literal"><span class="pre">chef-client::service</span></tt> recipe in the <tt class="docutils literal"><span class="pre">chef-client</span></tt> cookbook: <a class="reference external" href="http://community.opscode.com/cookbooks/chef-client">http://community.opscode.com/cookbooks/chef-client</a>. This will install a chef-client service under Microsoft Windows using the Windows Service Wrapper.</dd>
+<dd><p class="first">Use to run the executable as a daemon. This option may not be used in the same command with the <tt class="docutils literal"><span class="pre">--[no-]fork</span></tt> option.</p>
+<p class="last">This option is only available on machines that run in UNIX or Linux environments. For machines that are running Microsoft Windows that require similar functionality, use the <tt class="docutils literal"><span class="pre">chef-client::service</span></tt> recipe in the <tt class="docutils literal"><span class="pre">chef-client</span></tt> cookbook: <a class="reference external" href="http://community.opscode.com/cookbooks/chef-client">http://community.opscode.com/cookbooks/chef-client</a>. This will install a chef-client service under Microsoft Windows using the Windows Service Wrapper.</p>
+</dd>
<dt><tt class="docutils literal"><span class="pre">-E</span> <span class="pre">ENVIRONMENT_NAME</span></tt>, <tt class="docutils literal"><span class="pre">--environment</span> <span class="pre">ENVIRONMENT_NAME</span></tt></dt>
<dd>The name of the environment.</dd>
<dt><tt class="docutils literal"><span class="pre">-f</span></tt>, <tt class="docutils literal"><span class="pre">--[no-]fork</span></tt></dt>
-<dd>Use to contain the chef-client run in a secondary process with dedicated RAM. When the chef-client run is complete the RAM will be returned to the master process. This option helps ensure that a chef-client will use a steady amount of RAM over time because the master process will not run recipes. This option will also help prevent memory leaks (such as those that can be introduced by the code contained within a poorly designed cookbook). Use <tt class="docutils literal"><span class="pre">--no-fork</span></tt> to disable running the chef-client in fork node. Default value: <tt class="docutils literal"><span class="pre">--fork</span></tt>.</dd>
+<dd>Use to contain the chef-client run in a secondary process with dedicated RAM. When the chef-client run is complete the RAM will be returned to the master process. This option helps ensure that a chef-client will use a steady amount of RAM over time because the master process will not run recipes. This option will also help prevent memory leaks (such as those that can be introduced by the code contained within a poorly designed cookbook). Use <tt class="docutils literal"><span class="pre">--no-fork</span></tt> to disable running the chef-client in fork node. Default value: <tt class="docutils literal"><span class="pre">--fork</span></tt>. This option may not be used in the same command with the <tt class="docutils literal"><span class="pre">--daemonize</span></tt> and <tt class="docutils literal"><span class="pre">--interval</span></tt> options.</dd>
<dt><tt class="docutils literal"><span class="pre">-F</span> <span class="pre">FORMAT</span></tt>, <tt class="docutils literal"><span class="pre">--format</span> <span class="pre">FORMAT</span></tt></dt>
<dd><p class="first">The output format: <tt class="docutils literal"><span class="pre">doc</span></tt> (default) or <tt class="docutils literal"><span class="pre">min</span></tt>.</p>
<p>Use <tt class="docutils literal"><span class="pre">doc</span></tt> to print the progress of the chef-client run using full strings that display a summary of updates as they occur.</p>
@@ -86,9 +88,53 @@
<dt><tt class="docutils literal"><span class="pre">-h</span></tt>, <tt class="docutils literal"><span class="pre">--help</span></tt></dt>
<dd>Shows help for the command.</dd>
<dt><tt class="docutils literal"><span class="pre">-i</span> <span class="pre">SECONDS</span></tt>, <tt class="docutils literal"><span class="pre">--interval</span> <span class="pre">SECONDS</span></tt></dt>
-<dd>The frequency (in seconds) at which the chef-client runs.</dd>
+<dd>The frequency (in seconds) at which the chef-client runs. When the chef-client is run at intervals, <tt class="docutils literal"><span class="pre">--splay</span></tt> and <tt class="docutils literal"><span class="pre">--interval</span></tt> values are applied before the chef-client run. This option may not be used in the same command with the <tt class="docutils literal"><span class="pre">--[no-]fork</span></tt> option.</dd>
<dt><tt class="docutils literal"><span class="pre">-j</span> <span class="pre">PATH</span></tt>, <tt class="docutils literal"><span class="pre">--json-attributes</span> <span class="pre">PATH</span></tt></dt>
-<dd>The path to a file that contains JSON data. Use this option to override <tt class="docutils literal"><span class="pre">normal</span></tt> attributes set elsewhere.</dd>
+<dd><p class="first">The path to a file that contains JSON data.</p>
+<p>Use this option to define a <tt class="docutils literal"><span class="pre">run_list</span></tt> object. For example, a JSON file similar to:</p>
+<div class="highlight-javascript"><div class="highlight"><pre><span class="s2">&quot;run_list&quot;</span><span class="o">:</span> <span class="p">[</span>
+ <span class="s2">&quot;recipe[base]&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;recipe[foo]&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;recipe[bar]&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;role[webserver]&quot;</span>
+<span class="p">],</span>
+</pre></div>
+</div>
+<p>may be used by running <tt class="docutils literal"><span class="pre">chef-client</span> <span class="pre">-j</span> <span class="pre">path/to/file.json</span></tt>.</p>
+<p>In certain situations this option may be used to update <tt class="docutils literal"><span class="pre">normal</span></tt> attributes.</p>
+<div class="last admonition warning">
+<p class="first admonition-title">Warning</p>
+<p>Any other attribute type that is contained in this JSON file will be treated as a <tt class="docutils literal"><span class="pre">normal</span></tt> attribute. For example, attempting to update <tt class="docutils literal"><span class="pre">override</span></tt> attributes using the <tt class="docutils literal"><span class="pre">-j</span></tt> option:</p>
+<div class="highlight-javascript"><div class="highlight"><pre><span class="p">{</span>
+ <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;dev-99&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;Install some stuff&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;override_attributes&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;apptastic&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;enable_apptastic&quot;</span><span class="o">:</span> <span class="s2">&quot;false&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;apptastic_tier_name&quot;</span><span class="o">:</span> <span class="s2">&quot;dev-99.bomb.com&quot;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>will result in a node object similar to:</p>
+<div class="last highlight-javascript"><div class="highlight"><pre><span class="p">{</span>
+ <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;maybe-dev-99&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;normal&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="s2">&quot;dev-99&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;description&quot;</span><span class="o">:</span> <span class="s2">&quot;Install some stuff&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;override_attributes&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;apptastic&quot;</span><span class="o">:</span> <span class="p">{</span>
+ <span class="s2">&quot;enable_apptastic&quot;</span><span class="o">:</span> <span class="s2">&quot;false&quot;</span><span class="p">,</span>
+ <span class="s2">&quot;apptastic_tier_name&quot;</span><span class="o">:</span> <span class="s2">&quot;dev-99.bomb.com&quot;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+</div>
+</dd>
<dt><tt class="docutils literal"><span class="pre">-l</span> <span class="pre">LEVEL</span></tt>, <tt class="docutils literal"><span class="pre">--log_level</span> <span class="pre">LEVEL</span></tt></dt>
<dd>The level of logging that will be stored in a log file.</dd>
<dt><tt class="docutils literal"><span class="pre">-L</span> <span class="pre">LOGLOCATION</span></tt>, <tt class="docutils literal"><span class="pre">--logfile</span> <span class="pre">c</span></tt></dt>
@@ -104,7 +150,7 @@
<dt><tt class="docutils literal"><span class="pre">--run-lock-timeout</span> <span class="pre">SECONDS</span></tt></dt>
<dd>The amount of time (in seconds) to wait for a chef-client run to finish. Default value: not set (indefinite). Set to <tt class="docutils literal"><span class="pre">0</span></tt> to cause a second chef-client to exit immediately.</dd>
<dt><tt class="docutils literal"><span class="pre">-s</span> <span class="pre">SECONDS</span></tt>, <tt class="docutils literal"><span class="pre">--splay</span> <span class="pre">SECONDS</span></tt></dt>
-<dd>A number (in seconds) to add to the <tt class="docutils literal"><span class="pre">interval</span></tt> that is used to determine the frequency of chef-client runs. This number can help prevent server load when there are many clients running at the same time.</dd>
+<dd>A number (in seconds) to add to the <tt class="docutils literal"><span class="pre">interval</span></tt> that is used to determine the frequency of chef-client runs. This number can help prevent server load when there are many clients running at the same time. When the chef-client is run at intervals, <tt class="docutils literal"><span class="pre">--splay</span></tt> and <tt class="docutils literal"><span class="pre">--interval</span></tt> values are applied before the chef-client run.</dd>
<dt><tt class="docutils literal"><span class="pre">-u</span> <span class="pre">USER</span></tt>, <tt class="docutils literal"><span class="pre">--user</span> <span class="pre">USER</span></tt></dt>
<dd>The user that owns a process. This is required when starting any executable as a daemon.</dd>
<dt><tt class="docutils literal"><span class="pre">-v</span></tt>, <tt class="docutils literal"><span class="pre">--version</span></tt></dt>
diff --git a/distro/common/html/index.html b/distro/common/html/index.html
index 370c34f5f5..2742b07e03 100644
--- a/distro/common/html/index.html
+++ b/distro/common/html/index.html
@@ -44,7 +44,7 @@
<p>The following command line interfaces are available in the chef-client:</p>
<ul class="simple">
<li><a class="reference internal" href="ctl_chef_client.html"><em>chef-client</em></a></li>
-<li><a class="reference internal" href="ctl_chef_server.html"><em>chef-server-ctl</em></a></li>
+<li><a class="reference internal" href="ctl_chef_server.html"><em>chef-server-ctl (executable)</em></a></li>
<li><a class="reference internal" href="ctl_chef_shell.html"><em>chef-shell</em></a></li>
<li><a class="reference internal" href="ctl_chef_solo.html"><em>chef-solo</em></a></li>
<li><a class="reference internal" href="knife.html"><em>knife</em></a></li>
@@ -128,7 +128,7 @@
<td>The <strong>knife node</strong> subcommand is used to manage the nodes that exist on a Chef server.</td>
</tr>
<tr class="row-even"><td><a class="reference internal" href="knife_raw.html"><em>knife raw</em></a></td>
-<td>The <strong>knife raw</strong> subcommand is used to send a REST request to a specified path using the Chef server API.</td>
+<td>The <strong>knife raw</strong> subcommand is used to send a REST request to an endpoint in the Chef server API.</td>
</tr>
<tr class="row-odd"><td><a class="reference internal" href="knife_recipe_list.html"><em>knife recipe list</em></a></td>
<td>The <strong>knife recipe list</strong> subcommand is used to view all of the recipes that are on a Chef server. A regular expression can be used to limit the results to recipes that match a specific pattern. The regular expression must be within quotes and not be surrounded by forward slashes (/).</td>
diff --git a/distro/common/html/knife.html b/distro/common/html/knife.html
index 140edc125b..5a081702fc 100644
--- a/distro/common/html/knife.html
+++ b/distro/common/html/knife.html
@@ -118,7 +118,7 @@
<td>The <strong>knife node</strong> subcommand is used to manage the nodes that exist on a Chef server.</td>
</tr>
<tr class="row-even"><td><a class="reference internal" href="knife_raw.html"><em>knife raw</em></a></td>
-<td>The <strong>knife raw</strong> subcommand is used to send a REST request to a specified path using the Chef server API.</td>
+<td>The <strong>knife raw</strong> subcommand is used to send a REST request to an endpoint in the Chef server API.</td>
</tr>
<tr class="row-odd"><td><a class="reference internal" href="knife_recipe_list.html"><em>knife recipe list</em></a></td>
<td>The <strong>knife recipe list</strong> subcommand is used to view all of the recipes that are on a Chef server. A regular expression can be used to limit the results to recipes that match a specific pattern. The regular expression must be within quotes and not be surrounded by forward slashes (/).</td>
diff --git a/distro/common/html/knife_bootstrap.html b/distro/common/html/knife_bootstrap.html
index ea1a1cf153..5e3d70404f 100644
--- a/distro/common/html/knife_bootstrap.html
+++ b/distro/common/html/knife_bootstrap.html
@@ -83,19 +83,31 @@
<dd>The version of the chef-client to install.</dd>
<dt><tt class="docutils literal"><span class="pre">--bootstrap-wget-options</span> <span class="pre">OPTIONS</span></tt></dt>
<dd>Use to specify arbitrary options to be added to the bootstrap command when using GNU Wget. This option may not be used in the same command with <tt class="docutils literal"><span class="pre">--bootstrap-install-command</span></tt>.</dd>
-<dt><tt class="docutils literal"><span class="pre">-d</span> <span class="pre">DISTRO</span></tt>, <tt class="docutils literal"><span class="pre">--distro</span> <span class="pre">DISTRO</span></tt></dt>
-<dd><p class="first">The template file to be used during a bootstrap operation. The following distributions are supported: <tt class="docutils literal"><span class="pre">chef-full</span></tt> (the default bootstrap), <tt class="docutils literal"><span class="pre">centos5-gems</span></tt>, <tt class="docutils literal"><span class="pre">fedora13-gems</span></tt>, <tt class="docutils literal"><span class="pre">ubuntu10.04-gems</span></tt>, <tt class="docutils literal"><span class="pre">ubuntu10.04-apt</span></tt>, <tt class="docutils literal"><span class="pre">ubuntu12.04-gems</span></tt>, and the name of a custom bootstrap template file. When this option is used, knife will search for the template file in the following order: the <tt class="docutils literal"><span class="pre">bootstrap/</span></tt> folder in the current working directory, the <tt class="docutils literal"><span class="pre">bootstrap/</span></tt> folder in the chef-repo, the <tt class="docutils literal"><span class="pre">bootstrap/</span></tt> folder in the <tt class="docutils literal"><span class="pre">~/.chef/</span></tt> directory, or a default bootstrap file. Do not use the <tt class="docutils literal"><span class="pre">--template-file</span></tt> option when <tt class="docutils literal"><span class="pre">--distro</span></tt> is specified.</p>
-<div class="last admonition warning">
-<p class="first admonition-title">Warning</p>
-<p class="last">The default bootstrap operation uses the omnibus installer, which means the default template file (<tt class="docutils literal"><span class="pre">chef-full</span></tt>) should work on all supported platforms. It is recommended to use custom bootstrap templates only when the omnibus installer cannot be used. The <tt class="docutils literal"><span class="pre">.erb</span></tt> file extension is added automatically and should not be passed as part of the bootstrap command.</p>
-</div>
-</dd>
<dt><tt class="docutils literal"><span class="pre">-E</span> <span class="pre">ENVIRONMENT</span></tt>, <tt class="docutils literal"><span class="pre">--environment</span> <span class="pre">ENVIRONMENT</span></tt></dt>
<dd>The name of the environment. When this option is added to a command, the command will run only against the named environment.</dd>
<dt><tt class="docutils literal"><span class="pre">-G</span> <span class="pre">GATEWAY</span></tt>, <tt class="docutils literal"><span class="pre">--ssh-gateway</span> <span class="pre">GATEWAY</span></tt></dt>
<dd>The SSH tunnel or gateway that is used to run a bootstrap action on a machine that is not accessible from the workstation.</dd>
<dt><tt class="docutils literal"><span class="pre">--hint</span> <span class="pre">HINT_NAME[=HINT_FILE]</span></tt></dt>
-<dd>An Ohai hint to be set on the target of the bootstrap. The hint is contained in a file and is formatted as JSON: <tt class="docutils literal"><span class="pre">{&quot;attribute&quot;:&quot;value&quot;,&quot;attribute&quot;:&quot;value&quot;...}</span></tt>. <tt class="docutils literal"><span class="pre">HINT_NAME</span></tt> is the name of the hint and <tt class="docutils literal"><span class="pre">HINT_FILE</span></tt> is the name of the hint file located at <tt class="docutils literal"><span class="pre">/etc/chef/ohai/hints/HINT_FILE.json</span></tt>. Use multiple <tt class="docutils literal"><span class="pre">--hint</span></tt> options in the command to specify multiple hints.</dd>
+<dd><p class="first">Use to specify an Ohai hint to be set on the target node.</p>
+<p>Ohai hints are used to tell Ohai something about the system that it is running on that it would not be able to discover itself. An Ohai hint exists if a JSON file exists in the hint directory with the same name as the hint. For example, calling <tt class="docutils literal"><span class="pre">hint?('antartica')</span></tt> in an Ohai plugin would return an empty hash if the file <tt class="docutils literal"><span class="pre">antartica.json</span></tt> existed in the hints directory, and return nil if the file does not exist.</p>
+<p>If the hint file contains JSON content, it will be returned as a hash from the call to <tt class="docutils literal"><span class="pre">hint?</span></tt>.</p>
+<div class="highlight-javascript"><div class="highlight"><pre><span class="p">{</span>
+ <span class="s2">&quot;snow&quot;</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
+ <span class="s2">&quot;penguins&quot;</span><span class="o">:</span> <span class="s2">&quot;many&quot;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<div class="highlight-ruby"><div class="highlight"><pre><span class="n">arctic_hint</span> <span class="o">=</span> <span class="n">hint?</span><span class="p">(</span><span class="s1">&#39;antartica&#39;</span><span class="p">)</span>
+<span class="k">if</span> <span class="n">arctic_hint</span><span class="o">[</span><span class="s1">&#39;snow&#39;</span><span class="o">]</span>
+ <span class="s2">&quot;There are </span><span class="si">#{</span><span class="n">arctic_hint</span><span class="o">[</span><span class="s1">&#39;penguins&#39;</span><span class="o">]</span><span class="si">}</span><span class="s2"> penguins here.&quot;</span>
+<span class="k">else</span>
+ <span class="s2">&quot;There is no snow here, and penguins like snow.&quot;</span>
+<span class="k">end</span>
+</pre></div>
+</div>
+<p>The default directory in which hint files are located is <tt class="docutils literal"><span class="pre">/etc/chef/ohai/hints/</span></tt>. Use the <tt class="docutils literal"><span class="pre">Ohai::Config[:hints_path]</span></tt> setting in the client.rb file to customize this location.</p>
+<p class="last"><tt class="docutils literal"><span class="pre">HINT_FILE</span></tt> is the name of the JSON file. <tt class="docutils literal"><span class="pre">HINT_NAME</span></tt> is the name of a hint in a JSON file. Use multiple <tt class="docutils literal"><span class="pre">--hint</span></tt> options to specify multiple hints.</p>
+</dd>
<dt><tt class="docutils literal"><span class="pre">-i</span> <span class="pre">IDENTITY_FILE</span></tt>, <tt class="docutils literal"><span class="pre">--identity-file</span> <span class="pre">IDENTITY_FILE</span></tt></dt>
<dd>The SSH identity file used for authentication. Key-based authentication is recommended.</dd>
<dt><tt class="docutils literal"><span class="pre">-j</span> <span class="pre">JSON_ATTRIBS</span></tt>, <tt class="docutils literal"><span class="pre">--json-attributes</span> <span class="pre">JSON_ATTRIBS</span></tt></dt>
@@ -104,6 +116,14 @@
<dd>The name of the node.</dd>
<dt><tt class="docutils literal"><span class="pre">--[no-]host-key-verify</span></tt></dt>
<dd>Use <tt class="docutils literal"><span class="pre">--no-host-key-verify</span></tt> to disable host key verification. Default setting: <tt class="docutils literal"><span class="pre">--host-key-verify</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">--[no-]node-verify-api-cert</span></tt></dt>
+<dd>Use <tt class="docutils literal"><span class="pre">verify_api_cert</span></tt> to only do SSL validation of the Chef server connection; may be needed if the chef-client needs to talk to other services that have broken SSL certificates. If this option is not specified, the setting for <tt class="docutils literal"><span class="pre">verify_api_cert</span></tt> in the configuration file is applied.</dd>
+<dt><tt class="docutils literal"><span class="pre">--node-ssl-verify-mode</span> <span class="pre">PEER_OR_NONE</span></tt></dt>
+<dd><p class="first">The verify mode for HTTPS requests.</p>
+<p>Use <tt class="docutils literal"><span class="pre">:verify_none</span></tt> to do no validation of SSL certificates.</p>
+<p>Use <tt class="docutils literal"><span class="pre">:verify_peer</span></tt> to do validation of all SSL certificates, including the Chef server connections, S3 connections, and any HTTPS <strong>remote_file</strong> resource URLs used in the chef-client run. This is the recommended setting.</p>
+<p class="last">If this option is not specified, the setting for <tt class="docutils literal"><span class="pre">ssl_verify_mode</span></tt> in the configuration file is applied.</p>
+</dd>
<dt><tt class="docutils literal"><span class="pre">-p</span> <span class="pre">PORT</span></tt>, <tt class="docutils literal"><span class="pre">--ssh-port</span> <span class="pre">PORT</span></tt></dt>
<dd>The SSH port.</dd>
<dt><tt class="docutils literal"><span class="pre">-P</span> <span class="pre">PASSWORD</span></tt>, <tt class="docutils literal"><span class="pre">--ssh-password</span> <span class="pre">PASSWORD</span></tt></dt>
@@ -118,8 +138,8 @@
<dd>The path to the file that contains the encryption key.</dd>
<dt><tt class="docutils literal"><span class="pre">--sudo</span></tt></dt>
<dd>Use to execute a bootstrap operation with sudo.</dd>
-<dt><tt class="docutils literal"><span class="pre">--template-file</span> <span class="pre">TEMPLATE</span></tt></dt>
-<dd>The path to a template file that will be used during a bootstrap operation. Do not use the <tt class="docutils literal"><span class="pre">--distro</span></tt> option when <tt class="docutils literal"><span class="pre">--template-file</span></tt> is specified.</dd>
+<dt><tt class="docutils literal"><span class="pre">-t</span> <span class="pre">TEMPLATE</span></tt>, <tt class="docutils literal"><span class="pre">--bootstrap-template</span> <span class="pre">TEMPLATE</span></tt></dt>
+<dd>Use to specify the bootstrap template to use. This may specify the name of a bootstrap template&#8212;<tt class="docutils literal"><span class="pre">chef-full</span></tt>, for example&#8212;or it may specify the full path to an Embedded Ruby (ERB) template that defines a custom bootstrap. Default value: <tt class="docutils literal"><span class="pre">chef-full</span></tt>, which installs the chef-client using the omnibus installer on all supported platforms.</dd>
<dt><tt class="docutils literal"><span class="pre">--use-sudo-password</span></tt></dt>
<dd>Use to perform a bootstrap operation with sudo; specify the password with the <tt class="docutils literal"><span class="pre">-P</span></tt> (or <tt class="docutils literal"><span class="pre">--ssh-password</span></tt>) option.</dd>
<dt><tt class="docutils literal"><span class="pre">-V</span> <span class="pre">-V</span></tt></dt>
diff --git a/distro/common/html/knife_cookbook_site.html b/distro/common/html/knife_cookbook_site.html
index 72bb03582d..8815961629 100644
--- a/distro/common/html/knife_cookbook_site.html
+++ b/distro/common/html/knife_cookbook_site.html
@@ -263,6 +263,8 @@ kickstart:
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">CATEGORY</span></tt></dt>
<dd>The cookbook category: <tt class="docutils literal"><span class="pre">&quot;Databases&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;Web</span> <span class="pre">Servers&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;Process</span> <span class="pre">Management&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;Monitoring</span> <span class="pre">&amp;</span> <span class="pre">Trending&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;Programming</span> <span class="pre">Languages&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;Package</span> <span class="pre">Management&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;Applications&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;Networking&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;Operating</span> <span class="pre">Systems</span> <span class="pre">&amp;</span> <span class="pre">Virtualization&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;Utilities&quot;</span></tt>, or <tt class="docutils literal"><span class="pre">&quot;Other&quot;</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">-n</span></tt>, <tt class="docutils literal"><span class="pre">--dry-run</span></tt></dt>
+<dd>Use to take no action and only print out results. Default: <tt class="docutils literal"><span class="pre">false</span></tt>.</dd>
<dt><tt class="docutils literal"><span class="pre">-o</span> <span class="pre">PATH:PATH</span></tt>, <tt class="docutils literal"><span class="pre">--cookbook-path</span> <span class="pre">PATH:PATH</span></tt></dt>
<dd>The directory in which cookbooks are created. This can be a colon-separated path.</dd>
</dl>
diff --git a/distro/common/html/knife_data_bag.html b/distro/common/html/knife_data_bag.html
index d56fc589ad..a7a297be95 100644
--- a/distro/common/html/knife_data_bag.html
+++ b/distro/common/html/knife_data_bag.html
@@ -65,7 +65,7 @@
<dt><tt class="docutils literal"><span class="pre">DATA_BAG_ITEM</span></tt></dt>
<dd>The name of a specific item within a data bag.</dd>
<dt><tt class="docutils literal"><span class="pre">--secret</span> <span class="pre">SECRET</span></tt></dt>
-<dd>The encryption key that is used for values contained within a data bag item.</dd>
+<dd>The encryption key that is used for values contained within a data bag item. If <tt class="docutils literal"><span class="pre">secret</span></tt> is not specified, the chef-client will look for a secret at the path specified by the <tt class="docutils literal"><span class="pre">encrypted_data_bag_secret</span></tt> setting in the client.rb file.</dd>
<dt><tt class="docutils literal"><span class="pre">--secret-file</span> <span class="pre">FILE</span></tt></dt>
<dd>The path to the file that contains the encryption key.</dd>
</dl>
@@ -138,7 +138,7 @@
<dt><tt class="docutils literal"><span class="pre">DATA_BAG_ITEM</span></tt></dt>
<dd>The name of a specific item within a data bag.</dd>
<dt><tt class="docutils literal"><span class="pre">--secret</span> <span class="pre">SECRET</span></tt></dt>
-<dd>The encryption key that is used for values contained within a data bag item.</dd>
+<dd>The encryption key that is used for values contained within a data bag item. If <tt class="docutils literal"><span class="pre">secret</span></tt> is not specified, the chef-client will look for a secret at the path specified by the <tt class="docutils literal"><span class="pre">encrypted_data_bag_secret</span></tt> setting in the client.rb file.</dd>
<dt><tt class="docutils literal"><span class="pre">--secret-file</span> <span class="pre">FILE</span></tt></dt>
<dd>The path to the file that contains the encryption key.</dd>
</dl>
@@ -219,7 +219,7 @@
<dt><tt class="docutils literal"><span class="pre">-a</span></tt>, <tt class="docutils literal"><span class="pre">--all</span></tt></dt>
<dd>Use to upload all data bags found at the specified path.</dd>
<dt><tt class="docutils literal"><span class="pre">--secret</span> <span class="pre">SECRET</span></tt></dt>
-<dd>The encryption key that is used for values contained within a data bag item.</dd>
+<dd>The encryption key that is used for values contained within a data bag item. If <tt class="docutils literal"><span class="pre">secret</span></tt> is not specified, the chef-client will look for a secret at the path specified by the <tt class="docutils literal"><span class="pre">encrypted_data_bag_secret</span></tt> setting in the client.rb file.</dd>
<dt><tt class="docutils literal"><span class="pre">--secret-file</span> <span class="pre">FILE</span></tt></dt>
<dd>The path to the file that contains the encryption key.</dd>
</dl>
@@ -287,7 +287,7 @@
<dt><tt class="docutils literal"><span class="pre">DATA_BAG_ITEM</span></tt></dt>
<dd>The name of a specific item within a data bag.</dd>
<dt><tt class="docutils literal"><span class="pre">--secret</span> <span class="pre">SECRET</span></tt></dt>
-<dd>The encryption key that is used for values contained within a data bag item.</dd>
+<dd>The encryption key that is used for values contained within a data bag item. If <tt class="docutils literal"><span class="pre">secret</span></tt> is not specified, the chef-client will look for a secret at the path specified by the <tt class="docutils literal"><span class="pre">encrypted_data_bag_secret</span></tt> setting in the client.rb file.</dd>
<dt><tt class="docutils literal"><span class="pre">--secret-file</span> <span class="pre">FILE</span></tt></dt>
<dd>The path to the file that contains the encryption key.</dd>
</dl>
diff --git a/distro/common/html/knife_node.html b/distro/common/html/knife_node.html
index 755f8ee418..a3d7a51d1c 100644
--- a/distro/common/html/knife_node.html
+++ b/distro/common/html/knife_node.html
@@ -367,9 +367,9 @@ rs-123456
<dt><tt class="docutils literal"><span class="pre">-a</span> <span class="pre">ATTR</span></tt>, <tt class="docutils literal"><span class="pre">--attribute</span> <span class="pre">ATTR</span></tt></dt>
<dd>The attribute (or attributes) to show.</dd>
<dt><tt class="docutils literal"><span class="pre">-l</span></tt>, <tt class="docutils literal"><span class="pre">--long</span></tt></dt>
-<dd>Display long output when searching nodes while using the default summary format.</dd>
+<dd>Use to display all attributes in the output and to show the output as JSON.</dd>
<dt><tt class="docutils literal"><span class="pre">-m</span></tt>, <tt class="docutils literal"><span class="pre">--medium</span></tt></dt>
-<dd>Display more, but not all, of a node&#8217;s data when searching using the default summary format.</dd>
+<dd>Use to display normal attributes in the output and to show the output as JSON.</dd>
<dt><tt class="docutils literal"><span class="pre">-r</span></tt>, <tt class="docutils literal"><span class="pre">--run-list</span></tt></dt>
<dd>Use to show only the run-list.</dd>
</dl>
diff --git a/distro/common/html/knife_raw.html b/distro/common/html/knife_raw.html
index b199acae95..e661e9a84a 100644
--- a/distro/common/html/knife_raw.html
+++ b/distro/common/html/knife_raw.html
@@ -41,7 +41,7 @@
<div class="section" id="knife-raw">
<h1>knife raw<a class="headerlink" href="#knife-raw" title="Permalink to this headline">¶</a></h1>
-<p>The <strong>knife raw</strong> subcommand is used to send a REST request to a specified path using the Chef server API.</p>
+<p>The <strong>knife raw</strong> subcommand is used to send a REST request to an endpoint in the Chef server API.</p>
<div class="section" id="syntax">
<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
<p>This subcommand has the following syntax:</p>
diff --git a/distro/common/html/knife_role.html b/distro/common/html/knife_role.html
index 8f7fb52ceb..844de48d37 100644
--- a/distro/common/html/knife_role.html
+++ b/distro/common/html/knife_role.html
@@ -41,7 +41,7 @@
<div class="section" id="knife-role">
<h1>knife role<a class="headerlink" href="#knife-role" title="Permalink to this headline">¶</a></h1>
-<p>A role is a way to define certain patterns and processes that exist across nodes in an organization as belonging to a single job function. Each role consists of zero (or more) attributes and a run list. Each node can have zero (or more) roles assigned to it. When a role is run against a node, the configuration details of that node are compared against the attributes of the role, and then the contents of that role&#8217;s run list are applied to the node&#8217;s configuration details. When a chef-client runs, it merges its own attributes and run lists with those contained within each assigned role.</p>
+<p>A role is a way to define certain patterns and processes that exist across nodes in an organization as belonging to a single job function. Each role consists of zero (or more) attributes and a run-list. Each node can have zero (or more) roles assigned to it. When a role is run against a node, the configuration details of that node are compared against the attributes of the role, and then the contents of that role&#8217;s run-list are applied to the node&#8217;s configuration details. When a chef-client runs, it merges its own attributes and run-lists with those contained within each assigned role.</p>
<p>The <strong>knife role</strong> subcommand is used to manage the roles that are associated with one or more nodes on a Chef server.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
diff --git a/distro/common/html/knife_search.html b/distro/common/html/knife_search.html
index 2444c4845f..c5006d155e 100644
--- a/distro/common/html/knife_search.html
+++ b/distro/common/html/knife_search.html
@@ -41,7 +41,7 @@
<div class="section" id="knife-search">
<h1>knife search<a class="headerlink" href="#knife-search" title="Permalink to this headline">¶</a></h1>
-<p>Search indexes allow queries to be made for any type of data that is indexed by the Chef server, including data bags (and data bag items), environments, nodes, and roles. A defined query syntax is used to support search patterns like exact, wildcard, range, and fuzzy. A search is a full-text query that can be done from several locations, including from within a recipe, by using the <tt class="docutils literal"><span class="pre">search</span></tt> subcommand in knife, or by using the <tt class="docutils literal"><span class="pre">/search</span></tt> or <tt class="docutils literal"><span class="pre">/search/INDEX</span></tt> endpoints in the Chef server API. The search engine is based on Apache Solr and is run from the Chef server.</p>
+<p>Search indexes allow queries to be made for any type of data that is indexed by the Chef server, including data bags (and data bag items), environments, nodes, and roles. A defined query syntax is used to support search patterns like exact, wildcard, range, and fuzzy. A search is a full-text query that can be done from several locations, including from within a recipe, by using the <tt class="docutils literal"><span class="pre">search</span></tt> subcommand in knife, the <tt class="docutils literal"><span class="pre">search</span></tt> method in the Recipe DSL, and by using the <tt class="docutils literal"><span class="pre">/search</span></tt> or <tt class="docutils literal"><span class="pre">/search/INDEX</span></tt> endpoints in the Chef server API. The search engine is based on Apache Solr and is run from the Chef server.</p>
<p>The <strong>knife search</strong> subcommand is used run a search query for information that is indexed on a Chef server.</p>
<div class="section" id="syntax">
<h2>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h2>
@@ -97,9 +97,9 @@ win2k8-dev
<dt><tt class="docutils literal"><span class="pre">INDEX</span></tt></dt>
<dd>The name of the index to be queried: <tt class="docutils literal"><span class="pre">client</span></tt>, <tt class="docutils literal"><span class="pre">environment</span></tt>, <tt class="docutils literal"><span class="pre">node</span></tt>, <tt class="docutils literal"><span class="pre">role</span></tt>, or <tt class="docutils literal"><span class="pre">DATA_BAG_NAME</span></tt>. Default index: <tt class="docutils literal"><span class="pre">node</span></tt>.</dd>
<dt><tt class="docutils literal"><span class="pre">-l</span></tt>, <tt class="docutils literal"><span class="pre">--long</span></tt></dt>
-<dd>Display long output when searching nodes while using the default summary format.</dd>
+<dd>Use to display all attributes in the output and to show the output as JSON.</dd>
<dt><tt class="docutils literal"><span class="pre">-m</span></tt>, <tt class="docutils literal"><span class="pre">--medium</span></tt></dt>
-<dd>Display more, but not all, of a node&#8217;s data when searching using the default summary format.</dd>
+<dd>Use to display normal attributes in the output and to show the output as JSON.</dd>
<dt><tt class="docutils literal"><span class="pre">-o</span> <span class="pre">SORT</span></tt>, <tt class="docutils literal"><span class="pre">--sort</span> <span class="pre">SORT</span></tt></dt>
<dd>The order in which search results will be sorted.</dd>
<dt><tt class="docutils literal"><span class="pre">-q</span> <span class="pre">SEARCH_QUERY</span></tt>, <tt class="docutils literal"><span class="pre">--query</span> <span class="pre">SEARCH_QUERY</span></tt></dt>
diff --git a/distro/common/html/knife_status.html b/distro/common/html/knife_status.html
index 488a2914f3..8273f11601 100644
--- a/distro/common/html/knife_status.html
+++ b/distro/common/html/knife_status.html
@@ -61,6 +61,10 @@
<dd>The search query used to identify a a list of items on a Chef server. This option uses the same syntax as the <tt class="docutils literal"><span class="pre">search</span></tt> sub-command.</dd>
<dt><tt class="docutils literal"><span class="pre">-H</span></tt>, <tt class="docutils literal"><span class="pre">--hide-healthy</span></tt></dt>
<dd>Use to hide nodes on which a chef-client run has occurred within the previous hour.</dd>
+<dt><tt class="docutils literal"><span class="pre">-l</span></tt>, <tt class="docutils literal"><span class="pre">--long</span></tt></dt>
+<dd>Use to display all attributes in the output and to show the output as JSON.</dd>
+<dt><tt class="docutils literal"><span class="pre">-m</span></tt>, <tt class="docutils literal"><span class="pre">--medium</span></tt></dt>
+<dd>Use to display normal attributes in the output and to show the output as JSON.</dd>
<dt><tt class="docutils literal"><span class="pre">-r</span> <span class="pre">RUN_LIST</span></tt>, <tt class="docutils literal"><span class="pre">--run-list</span> <span class="pre">RUN_LIST</span></tt></dt>
<dd>A comma-separated list of roles and/or recipes to be applied.</dd>
<dt><tt class="docutils literal"><span class="pre">-s</span></tt>, <tt class="docutils literal"><span class="pre">--sort-reverse</span></tt></dt>
diff --git a/distro/common/html/searchindex.js b/distro/common/html/searchindex.js
index a0f7c322e8..956e91c737 100644
--- a/distro/common/html/searchindex.js
+++ b/distro/common/html/searchindex.js
@@ -1 +1 @@
-Search.setIndex({envversion:42,terms:{kickstart:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chisamor:12,poorli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],four:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prefix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dirnam:26,rsyslog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oldest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],accur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],service_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],umask:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],descript:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_typ:[0,14,31,32,4,7,36,19],under:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],slowest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],replica:18,digit:18,everi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_maintain:5,upstream:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],affect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],month:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],csshx:[33,30,17],raw_data:36,cmd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],upload:[13,19,2,34,18,9,10,27,20,29],rabbitmq:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rabbitmqctl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],verif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],x86_64:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],proxy_url:29,hord:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],application_java:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hint_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],direct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],consequ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],second:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aggreg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ips_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],start_chef:29,even:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],supervis:18,hide:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],asid:27,children:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"new":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],net:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],topolog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],metadata:[13,19,2,34,18,9,10,27,20,29],default_attribut:[4,0],kilobyt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],run_list_item:[32,9,34],never:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],macports_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],here:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],num_vers:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],recipe_nam:[32,0],host_head:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],path:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],interpret:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hosted_everyth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dry:[6,35,28],erl_cal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rubocop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],url_or_uri:[30,17],chefspec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],databagitem:36,runlist:[9,34],brought:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],substr:26,unix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],printf:1,hipchat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],txt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],describ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],would:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bundler:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],call:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],asset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],recommend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],indiana:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],type:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],until:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fastcgi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],relat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],server_url:27,notic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],warn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oc_bifrost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exce:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],relai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],killal:34,hold:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],must:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gecod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],join:1,henri:18,orgnam:[26,19,29],setup:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],work:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],bluebox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],raid1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],erb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fnmatch:31,root:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],could:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ss6p92l_sca:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],overrid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],give:[34,1],smtp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],elrepo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],indic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],want:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],keep:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],end:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],quot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],eni:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vagrant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],how:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],env:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],verifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],config:34,updat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],after:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lab:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],befor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unmount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],windows_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],arch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],parallel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],demonstr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],request_path:14,attempt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],client_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opaqu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bootstrap:[13,34,18,9,27,20],credenti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exclud:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alias:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],maintain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],environ:[13,19,27,21,22,2,31,5,6,34,36,25,18,9,10,11,20,29],danno:7,enter:[12,21,34,0,14,1,32,33,15,31,4,5,6,7,37,35,26,36,19],order:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],softwar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],over:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],becaus:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vari:[29,18],cli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],generic_execut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],denver:37,better:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],persist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],erlang:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],split:1,them:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],woken:34,thei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],proce:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rackspaceknif:5,"40g":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],choic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],changelog:31,conflict:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],timeout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],each:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],debug:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],search_queri:[33,15,30,17,5],eacc:34,side:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mean:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],voxel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],log_loc:29,extract:[6,9,20,13],linod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],network:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reg_sz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],god:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],newli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],content:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rewrit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],devops_prod1:37,billing_admin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dsc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prioriti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],http_request:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],putti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gunicorn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],written:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ntp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],situat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],free:1,fred:36,qword:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],node1:32,kit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"1_0_0":5,"1_0_1":5,"1_0_2":5,"1_0_3":5,reconfigur:34,sigkil:18,reg_dword_big_endian:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],whateverthedefaultmightb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openssh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openssl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],filter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],iso:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],temporari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],user:34,pristin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rang:[12,15],render:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chefignor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],independ:[26,18],capac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],restrict:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hook:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hkey_classes_root:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alreadi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wrapper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],netfx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],primari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],role1:0,rewritten:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tinydn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],easili:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],top:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sometim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mercuri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],master:34,too:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],amqp_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],john:18,listen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cloudform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],iptabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],consol:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"8wjyvhy9fhcegaareg":36,namespac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tool:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],erchef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0a58cf8":15,yield:26,"10g":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bookshelf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sha1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],max_arg:28,auxw:34,target:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],provid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tree:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zero:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],project:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],matter:26,gnupg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],entri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],minut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],provis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],behavior:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ram:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mine:29,unicast:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],raw:[1,2,4,5,6,8,9,10,11,13,16,18,29,20,21,22,25,27,19,31,32,34,36],pessimist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],seed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],application_rubi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chefservicefeatur:29,blue:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],though:32,usernam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],glob:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],object:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],regular:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],s001:34,specifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],letter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],breakpoint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],don:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],doc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],metal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dog:36,doe:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_licens:26,wildcard:[21,15,25],teck:7,unchang:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],runit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opposit:[6,13,35,20,18],whitelist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],random:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ruby_block:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],syntax:[13,34,18,9,27,20],radio:7,identifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],make:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],celeri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],absolut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],layout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0a58e134":15,holder:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],configur:[13,19,34,18,9,10,27,20,29],apach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lwrp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ldap:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],folder:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oct:33,likewis:5,stop:34,compli:18,amazon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],servermanagercmd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],report:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],youtub:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],method:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],runa:34,reload:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zabbix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],no_proxy_url_or_ip:29,groupinstal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],num:[33,30,17],mandatori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],result:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],respons:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],key_fil:34,mdadm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],best:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rsa_kei:19,awar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],said:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],databas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],multiinst:26,sigint:18,solr4:18,irb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],irc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],approach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],databag:14,attribut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],extend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],were:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],extens:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],policyfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],toler:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],advertis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],kitchen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],protect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],easi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],met:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],howev:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],against:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fedora13:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],logic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],countri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],login:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],com:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rehash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],publishset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trunk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],loader:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],your_email:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],usr1:34,diff:[13,19,27,31,2,34,5,36,25,18,9,10,11,20,29],trust:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],assum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],duplic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chrome:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fri:33,three:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],been:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trigger:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],basic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],homepath:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hesit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],quickli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],life:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],file_edit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],suppress:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],worker:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],telnet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],argument:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],verify_api_cert:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],child:25,"catch":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ident:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],data_bag_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gnu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],servic:34,properti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],calcul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unsolv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dashboard:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nexenta:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],powershel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],seven:18,remount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],player:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exit:[9,1],conf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sever:15,amout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],growl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],perform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],suggest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],use_last_modifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],couchdb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],preserv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],descend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],djbdn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],syncd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],complet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],raid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],orgmapp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rais:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],portal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unicorn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tune:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mirror_expir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],kept:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scenario:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"30t21":5,name_of_premium_featur:18,inherit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],contact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gzip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],everyth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],left:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],protocol:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],just:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sigusr1:34,bandwidth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],human:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],name_of_servic:18,yet:18,languag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],previous:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reboot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mod_php:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],force_default:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],had:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],macport:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],save:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ubuntu12:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ubuntu10:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],applic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_vers:[4,5,31],metabas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fusion:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],json_class:[0,14,31,32,4,7,36,19],shadow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pingabl:18,daemon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],specif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deprec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nrpe:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],arbitrari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],manual:[33,30,34,17],graylog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deploy_revis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],public_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sublime_text:26,specifii:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],underli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],multi_str:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],right:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],interv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],percentag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tibetanspaniel:36,intern:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],successfulli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],transmiss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],knife_config:29,total:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],setloc:29,fidel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],track:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],select:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],condit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],foo:14,localhost:18,core:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],plu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],uncompress:5,insecur:18,repositori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],anagram:26,actions_messag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"super":34,grizzli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],subkei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],plug:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],postgresql:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],surround:[13,0,31,32,3,20,19],birdman:7,svn_argument:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],horizon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],commit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"float":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],profession:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bound:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],diwb:18,down:18,run_list:[29,1],storag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],eth1:18,git:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],suffici:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],support:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nova:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"class":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],avail:34,reli:29,gid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wordpress:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],editor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],jane:18,war:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lowest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],head:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],noevict:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],form:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],forc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],some:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],forg:[13,30,17],useradd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"25t23":5,icmp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"true":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wmi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],middle_nam:18,attr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ssh_known_host:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],maximum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tell:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inaccur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fundament:31,opensus:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],featur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openbsd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],classic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],decrypt:36,sale:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],diagnost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],glanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ship:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],check:[0,1,2,3,4,5,6,8,9,10,11,13,14,15,16,18,19,20,21,22,23,24,25,27,29,31,32,33,34,36],sticki:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],assembl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vista:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],groupmod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],encrypt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],when:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],actor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],win_wget_p:29,role:[1,2,3,4,5,6,8,9,10,11,13,14,16,18,29,20,21,22,25,27,19,31,32,34,36],test:[13,19,2,34,18,9,10,27,20,29],roll:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],node:[1,2,4,5,6,8,9,10,11,13,16,18,29,20,21,22,25,27,19,31,34,36],notif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],intend:26,phoenix:37,kvm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],asterisk:[26,18],devop:[0,31,32,4,5,19],stompserv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],intent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],consid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sql:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],younger:7,search_attribut:1,faster:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],anywher:[6,35],ignor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],time:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],push:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],backward:27,skip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],consum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],redis2:5,netbsd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],row:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zookeep:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],varnish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],middl:[13,17],depend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zone:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],decim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],installonlypkg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],comun:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],decis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],jvm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],text:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],downtim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aspx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],application_python:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sourc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],string:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],org_nam:18,cookbooks_path:9,cloudstack:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lru:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],template_filenam:29,brows:[6,35],public_hostnam:33,script_fil:1,pkgbuild:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],administr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],level:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],did:[12,18],magnet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],item:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cooki:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],validation_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prevent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bffcreat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sign:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],port:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"5272a43f":12,raid5:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],appear:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],icinga:5,repli:[13,17],current:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],id3lib:5,reg_binari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deriv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],executionpolici:29,gener:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unauthor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef11:18,chef12:18,modif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],address:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],locat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],along:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],redmin:5,wait:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],box:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_environ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],invit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],netdev:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],checksum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],behav:26,healthi:12,noinput:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],regardless:29,rightscal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],extra:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],modul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],test_system:1,prefer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],peer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],leav:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],seattl:37,visibl:1,instal:34,post:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],regex:[32,3,31,0,19],memori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],subvers:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],msn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],handler:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],msi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],criteria:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],checkout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],azur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rabbitmq_chef:5,visual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tandem:18,templat:[13,34,18,9,27,20],log_directori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],effort:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],role_nam:[32,0,25],proxy_cache_path:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tokyo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],uniqu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cat:1,descriptor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],profitbrick:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],graphit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],can:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],www:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opscode_erchef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],purpos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nearest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],container_servic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stream:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],backslash:[26,28],agent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],topic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],critic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mirrorlist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],occur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alwai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sundai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],multipl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gem_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ping:18,uptim:[33,18],write:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mixlib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],purg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],map:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],product:[13,21,35,15,4,6,18,20,29],omnitruck:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],max:28,clone:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sp4:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],identity_fil:[33,30,17,29],appnam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hklm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],log_level:[9,34,29],roundrobin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],data:[13,19,31,2,34,5,18,9,10,27,20,29],man:[9,34,27,18],freshli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nullsoft:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],purge_before_symlink:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],logwatch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],preced:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],combin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],talk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],port_list:26,config_fil:[10,30,17],ssh_wrapper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],partial_search:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ttl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gitignor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],still:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dynam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],entiti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],conjunct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],group:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],monitor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],duplex:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],platform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],non:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],main_monitor:3,rake:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],initi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],safari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],half:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nov:34,superset:26,provision:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],discuss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],term:34,name:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],drop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],revert:18,separ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],full_nam:18,compil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],failov:18,domain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],replac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],individu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],continu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unlock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gnu_parallel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],year:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],happen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],subnet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shown:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"3rd":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],space:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"100g":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],profil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vrrp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],internet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],correct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hkey_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],orgtest:15,newsiz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],migrat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],argv:1,mime:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],org:34,"byte":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],care:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reusabl:31,wai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],frequenc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],synchron:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],turn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],place:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fa0fc4abf3f6787aeb5c3c5c35de667c:31,router:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],principl:26,think:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],frequent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],first:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],origin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],directli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],carri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],onc:34,arrai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"long":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oppos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],uncaught:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],open:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],predefin:1,size:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],iam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],given:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reprepro:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],silent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],install_chef:29,ssh_command:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],iaa:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],baremetalcloud:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],citi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cumul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],averag:33,white:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],apt_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],json_attrib:29,environment_nam:[9,4,25],hub:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],especi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],provinc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],copi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],full_control:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],artifact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],broadcast:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"short":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],enclos:26,mostli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],john_smith:18,pecl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],than:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],png:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],serv:[0,1,2,3,4,5,6,8,9,10,11,13,14,15,16,18,19,20,21,22,25,27,29,31,32,34,36],wide:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sbuild:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],posix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],balanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],optimist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zsh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pre:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fork:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],config_cont:29,pro:26,delim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ani:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],client_kei:[26,34],ant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],medium:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],smartos_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cassandra:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],extralarg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],engin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],destroi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],note:1,sendfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ideal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],copyright_hold:31,take:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],noth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],channel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],begin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sure:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trace:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],normal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],buffer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],compress:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],statu:34,instiki:5,timestamped_deploi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pair:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],collectstat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],later:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],drive:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reg_expand_sz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],runtim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],superblock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],expand_str:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],steadi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],netdev_interfac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],show:34,encrypted_data_bag_secret:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],concurr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],permiss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sysctl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],help:34,xml:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],onli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],explicitli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],moneta:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],favor:[33,30,17],gceserviceaccount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],transact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],activ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],state:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dword:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hello_world:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],analyt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sighup:18,nearli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],variou:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],get:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stomp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],secondari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],repo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],ssl:[0,1,2,3,4,5,6,8,9,10,11,13,14,15,16,18,19,20,21,22,23,24,25,27,29,31,32,33,34,36],cannot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ssh:[0,1,2,3,4,5,6,8,9,10,11,13,14,15,16,18,19,20,21,22,23,24,25,27,29,31,32,34,36],ssd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],requir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],debian5:29,foodcrit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aptitud:33,netscalar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aris:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],where:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],summari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wiki:[26,5],kernel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],installshield:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],spork:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],endloc:29,drbd0:18,data_bag:[26,36,14],mtu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],xenserv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],concern:18,detect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],review:[0,1,2,3,4,25,6,7,8,11,12,14,15,16,35,29,21,22,23,24,5,28,19,31,32,33,36,37],label:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],behind:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],volatil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],between:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dockerfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"import":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],across:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sname:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],parent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],node_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],screen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],solaris_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],supermarket:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],syntax_check_cache_path:26,come:26,tue:34,gpasswd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],uuid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],region:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pychef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],library_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],datamapp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mani:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],runcontext:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reindex:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prereleas:29,color:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],period:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],symfoni:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],colon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],generic_writ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cancel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dsc_mof:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],poll:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bluepil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ultim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],org_full_nam:18,west:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rebuild:[13,19,27,1,22,2,21,31,4,5,6,34,36,25,18,9,10,11,20,29],replace_str:28,mark:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],spiceweasel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rebuilt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],my_cookbook:31,rubi:[13,19,27,21,22,2,31,4,5,6,34,36,25,18,9,10,11,20,29],editpad:26,thing:18,those:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"case":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],eip:21,pedant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],invok:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],base64:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],librato:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],suse:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],application_nginx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stdout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],metric:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_client:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],airbrak:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cluster:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ascii:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aa384235:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],develop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],author:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],media:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],same:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],binari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],html:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],document:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],week:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],finish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],webserv:[21,32,33,25,6,35,29],nest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],confidenti:36,driver:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],capabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openldap:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],improv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],extern:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],repoforg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],appropri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],megabyt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],without:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trusted_certs_dir:[13,30],model:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],resource_collect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],a29d6f254577b830091f140c3a78b1f:31,execut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],loaderror:33,key_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],kill:34,aspect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],org_cleanu:3,touch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],passphras:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],http_proxi:29,speed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aws_access_key_id:26,samba:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],display_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],except:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],apache2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],identif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],instrument:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],query_to_run:15,ruby1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pill:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],earli:18,around:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ohai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],read:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],traffic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],platform_vers:31,world:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yyyymmddhhmmss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mof:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],iftop:5,integ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],server:34,either:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],output:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rubyv:1,manag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cisco:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],glesi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],server01:[33,30,17],freez:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rsync:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],keytab:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],confirm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],definit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],appscript:33,keyston:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],highcpu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],portage_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],knife:[9,34,27,18],refer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],power:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],notepad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inspect:[6,13,20],broken:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],a45298c9:12,starttim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],found:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],berksfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bazaar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],appli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],comparison:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],central:9,ack:5,gplv2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gplv3:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],acl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],percona:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],act:27,backup:34,processor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],effici:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],max_siz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],your:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],charli:36,hkey_current_config:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],log:34,daemontool:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],simultan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],overwrit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],start:34,interfac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ipv4:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ipv6:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],svn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],enough:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bundl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],untar:5,cabinet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opensolari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],activemq:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],conclus:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],longer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chefclientfeatur:29,pull:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],possibl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"default":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pacman:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bucket:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],powershell_script:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vhd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],embed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],connect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cbc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],uid:36,creat:34,certain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],remote_directori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_handl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],decreas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fail2ban:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],file:34,fill:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],incorrect:34,file_maxbyt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],googl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prepend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],field:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],valid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],you:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],architectur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],codecademi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],registri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sequenc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],symbol:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pear:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fsck:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],snitch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dropbox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pool:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],netdev_lag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reduc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],directori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_copyright:26,mask:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],use_etag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],escap:[26,28],cpu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],actions_consum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],represent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],all:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],selinux:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],forbidden:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ibm305ramac:1,lacp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],java_opt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],netdev_l2_interfac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],follow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],disk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dism:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sympa:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dsl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],init:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],program:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],app_conf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scratch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],introduc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cloudkick:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],global:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],premium:18,fals:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],checkin:1,subcommand:34,util:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],verb:[13,22,23,8,11,20],failur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],veri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ossec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],excluded_memb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],list:34,last_nam:18,gerritt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],recipe_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],plain:36,user_nam:[33,30,7,17,18],pid_fil:34,enterpris:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],drbd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sync:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],past:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],syslog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rate:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],design:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pass:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ssh_attr:[33,30,17],further:18,current_dir:26,proxi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],what:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yum_repositori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sub:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],section:[13,20,26],abl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],brief:[12,13,20],rackspac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],delet:34,abbrevi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],version:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],noprofil:29,"public":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],millisecond:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],full:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],berkelei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],multilib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],solari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],excess:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gandi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],standard:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],modifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],valu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thrift:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],search:[13,19,31,2,34,18,9,10,27,20,29],memcach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prior:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],amount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],action:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],warrant:[13,20,1],via:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],transit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tmux:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],filenam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],establish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],redisio:4,proceed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],regist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],two:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],validation_client_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],more:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],flat:8,association_us:18,desir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],site:[13,19,31,2,34,18,9,10,27,20,29],flag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],particular:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],known:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],compani:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],destin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],installroot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],psql:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],none:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],endpoint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hour:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dep:[13,19,27,31,2,34,5,36,18,9,10,11,20,29],dev:[12,32,15,4,18],histori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oktawav:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],remain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hkey_local_machin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],caveat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],learn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nagio:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],external_url:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prompt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sensu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],share:[13,19,31,2,34,18,9,10,27,20,29],bootstrap_directori:29,accept:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],verify_non:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],minimum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],poni:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],explor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_data_bag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],csh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],first_nam:18,secur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rather:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],anoth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pxe_dust:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],simpl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],distro:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],regener:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],resourc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],referenc:[7,19],vlan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fstype:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rbac:26,perl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],data_bag_item_dogs_tibetanspaniel:36,associ:34,github:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],postfix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],created_at:5,django:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],caus:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],allkei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],logrot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opscod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rotat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],templatefortextstr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],i386:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],through:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],htop:5,paramet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],create_dirs_before_symlink:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],systemd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sql_databas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exact:[32,15],pend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_nam:[0,25,5,31],bypass:[6,13,20],"return":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],graylog2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],timestamp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],framework:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],admin_nam:26,troubleshoot:18,instruct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],authent:[13,19,27,21,22,2,31,4,5,6,34,36,25,18,9,10,11,20,29],"1password":5,userprofil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],token:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],average_r:5,compris:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fulli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unicod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],only_if:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],truncat:[32,5],denni:7,harm:[13,30],"300mb":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hard:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],crontab:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],expect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],new_client:1,create_wait_m:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],portland:37,beyond:26,event:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ftp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vancouv:37,robert:7,publish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],etag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],print:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],occurr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],file_nam:[19,7,31,18],gpl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],qualifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],asp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],devops_data:36,advanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],campfir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],effect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],quick:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reason:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],base:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],put:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],workstat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],basi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thread:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],launch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],omit:[15,19],perman:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],heartbeat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],assign:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],excurs:18,notifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],upper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],number:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],env_vari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],done:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stdlib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],blank:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],miss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],file_atomic_upd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pgdg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],differ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],script:[13,19,27,21,22,2,31,4,5,6,34,36,25,18,9,10,11,20,29],ipaddress:1,interact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unrestrict:29,least:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],checkpoint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],win2k8:15,statement:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zeromq:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scheme:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],journli:4,jetti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],store:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],schema:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dpkg_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],storm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],part:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pars:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],consult:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dpkg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reinstal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],grep:[34,5,29],remot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],remov:[1,2,4,5,6,8,9,10,11,13,16,18,29,20,21,22,25,27,19,31,34,36],reg_qword:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],secret_access_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],randomli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],comput:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gvim:26,packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],expir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dedic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],testmast:18,berkshelf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],built:[26,18],equival:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],also:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],centos5:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rakefil:21,build:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stackforg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],splai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],compat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pipelin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],distribut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exec:[13,19,27,21,22,2,31,4,5,6,34,36,25,18,9,10,11,20,29],previou:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],quota:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],most:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],private_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],preprod:18,cover:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],destruct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],clojur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],clean:33,microsoft:[13,34,18,9,27,20],carefulli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],xcode:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alphanumer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ignore_failur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],session:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fine:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],affin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],firewal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pretti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],solut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],jtimberman:[5,29],darwin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yml:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],everysec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unus:[7,19],chef_gem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"__file__":26,express:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],verify_p:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nativ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mainten:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fastest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],restart:34,"225f954f":12,data_bag_name_or_path:36,crt:21,boost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],your_company_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],common:[13,19,20,29],gelf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],syntax_check_cach:26,certif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],set:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],dump:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],creator:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],startup:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ifconfig:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],see:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],arg:28,reserv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ark:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],flavor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cssh:[33,30,17],git_ssh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],example_nod:1,prempt_delai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],someth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],subscript:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],altern:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],solo:[34,27,18],chef_nod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gemfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],numer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],javascript:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],succeed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],distinguish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],solr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],popul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],satisfi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reg_multi_sz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],delimit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pdn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],context:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],access_key_id:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lash:1,vault:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],load:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],markdown:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],point:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],schedul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],uptod:18,header:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shutdown:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ucspi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],desktop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],backend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],authz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rackspace_api_kei:26,unsuccess:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],java:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],devic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],add:[1,2,4,5,6,8,9,10,11,13,16,18,29,20,21,22,25,27,19,31,34,36],empti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],secret:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],strategi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],atomic_upd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],togeth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],imag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rspec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],understand:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0_8_0":5,look:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],registry_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],frozen:31,hkcc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bill:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],batch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],durat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],formatt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"while":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],corpsit:21,abov:29,error:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hkcr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],maradn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],loop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hkcu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],real:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],motd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],readm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],client_desc:1,dynect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],itself:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cento:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],skype:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vcloud:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"null":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fedora:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],grant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],belong:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hadoop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shorter:1,octal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],languages_ruby_vers:15,higher:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],x86:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0_7_0":5,cloud:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wherea:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inflat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alert:5,jpackag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lxc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nosess:26,typic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],recent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lower:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],task:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lib:29,older:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],british_sea_pow:29,ssl_verify_mod:[13,17],person:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reflect:4,docker:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rbenv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],propos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],override_attribut:[4,0],mysql:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openstack:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"07z":5,password:34,workflow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],web03:15,win:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],input:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],subsequ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],app:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vendor:5,obsolet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fqdn_or_ip_address:29,format:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],ipmi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],main_attribut:15,local_download_path:29,nginx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exceptionclass:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],characterist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],success:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],signal:18,svlogd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],resolv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],elaps:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],collect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],princip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],api:[13,19,27,21,22,2,31,4,5,6,34,36,25,18,9,10,11,20,29],encount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vsphere:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],often:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],simplifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],add_formatt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],acknowledg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],creation:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],macterm:[33,30,17],back:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unspecifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sampl:[32,36,0,18],staticfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],force_overrid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mirror:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_rol:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],virtualenv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scale:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lamin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],per:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],attribute_nam:32,retri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],larg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],undon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],slash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prod:18,proc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],snort:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],machin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sql_user:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],agreement:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],infra:18,step:[13,30,34],wget:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],crond:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ufw:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],generic_read:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],constraint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],drbdadm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],idl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],block:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],instance_typ:15,nsi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hudson:5,ohai_tim:1,smart_o_s_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opscodesupport:5,within:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ensur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rundeck:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],errno:34,question:26,fast:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],custom:[13,34,18,9,27,20],includ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],suit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],forward:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],properli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ifcfg:15,textpad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],remote_source_msi_url:29,pwd:29,link:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],translat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],newer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],atom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],noninteract:29,line:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],info:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],utc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],consist:[26,0],munin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],groovi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nscd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"export":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],similar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nsca:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],supervisor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],doesn:32,repres:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"char":28,incomplet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],home:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],curl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],titl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sequenti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],invalid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"_imag":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],transport:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],peopl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nice:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deseri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mongodb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],meaning:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_server_url:[26,34,27,29],eval:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],splunk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ladvd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],desert:25,lang:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"1024mb":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],infrequ:[13,20,1],algorithm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yourcompani:26,depth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_overview_attribut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hello:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],endtim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],code:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],partial:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],queri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],groupadd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trywgfa6r70no28pnhmpghevkbzuxouemnbnauqsuyo:36,steve:7,privat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ulimit:4,elsewher:9,send:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],junip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fatal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],getchef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],passiv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vlc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],volum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],recip:[1,2,4,5,6,8,9,10,11,13,14,16,18,29,20,21,22,25,27,19,31,32,34,36],magic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],netdev_vlan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],id_rsa:29,geograph:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hive:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"try":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pleas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],malici:[13,30],impli:15,jdk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cron:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],slackwar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],download:[13,19,2,34,18,9,10,27,20,29],click:34,append:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ps1:29,index:[13,19,27,1,22,2,21,31,4,5,6,34,36,25,18,9,10,11,20,29],compar:[13,19,27,21,22,2,31,5,6,34,36,25,18,9,10,11,20,29],a47823c9:12,winrm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],find:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],access:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],f65c969b:12,logloc:[9,34],isapi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hku:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bodi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],let:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ubuntu:[13,34,18,9,27,20],becom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sinc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],convert:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],copyright:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],overwritten:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aardvark:26,larger:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fetch:[0,1,2,3,4,5,6,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,31,32,33,34,36],converg:34,rpm_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ctl:34,chang:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],honor:27,fstab:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],firefox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ago:12,danger:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],spec_help:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],approxim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gatewai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],apt:[13,34,18,9,27,20],"boolean":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],smartmon:31,redi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pxe:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],from:[13,19,2,34,18,9,10,27,20,29],zip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],commun:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],doubl:26,upgrad:34,nexu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],next:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],websit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],few:[34,18],use_conditional_get:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],usr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sort:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mismatch:4,about:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"transient":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],starter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],account:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],retriev:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tunnel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alia:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],crazi:36,hint_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],control:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sqlite:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],weaker:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],process:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sudo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_collect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],high:34,tag:[0,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,36],proprietari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tarbal:[5,18],someurlher:31,symlink_before_migr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],delai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sit:[26,36],tamper:[13,30],zenpack:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reg_dword:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],subdirectori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],instead:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opscode_us:26,zendmd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],msdn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],somelongurlher:31,overridden:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],watch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],apicli:19,tier:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_repo_path:[21,13,22,35,25,23,6,24,8,11,28],physic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tenant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alloc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],delete_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],essenti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bind:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zenoss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],correspond:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],issu:[13,34,26,17,18],client_foo:19,allow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yum_globalconfig:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aws_secret_access_kei:26,jira:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],restorecon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],comma:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sql_ro_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],infrastructur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openvpn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],asa:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bittorr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],therefor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],keepaliv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],greater:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],python:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],auto:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],auth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yum_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rubygem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],recipe_url:9,front:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],file_cache_path:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],anyth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],edit:34,radiant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pacman_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0a7cffd5":15,mode:[34,18],all_cap:26,subset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],jane_do:18,chunk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],meta:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"static":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ec2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],citrix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],patch:5,special:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],out:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],variabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gentoo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bag:[13,19,31,2,34,5,18,9,10,27,20,29],armor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],erlang_solut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rails_enterpris:5,categori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],suitabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rem:29,hardwar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"_default":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"56g":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],local_destination_msi_path:29,red:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sql_server:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shut:18,insid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sendmail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],manipul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],standalon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],releas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shortest:18,qpid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stackscript:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],s3_bucket:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ask:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fqdn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],david:18,length:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],outsid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],retain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],respond:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],polici:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],echo:29,date:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],puppet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pgp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],kerbero:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],owner:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],facil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],underscor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],erubi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],licens:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mkdir:29,system:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],messag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],attach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],attack:[13,17],privaci:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],termin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"final":29,uri_for_https_serv:30,udp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shell:[34,18],big:18,fuzzi:15,shallow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rdoc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rsa:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exactli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],haven:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],passenger_apache2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],homedr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],structur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],charact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sens:5,sensit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],start_tim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],plaintext:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],remote_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inno:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],download_directori:31,have:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bootstrap_proxi:29,cfengin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],freebsd_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],min:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],atim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],accuraci:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],which:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"256f884f":12,datacent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zlib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],singl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reposerv:29,unless:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],freebsd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deploy:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],who:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oracl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cipher:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deploi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],xarg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,29,30,31,32,33,34,35,36,37],kuwata:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],segment:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],why:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],push_job:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],p180:29,url:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],request:[13,19,27,21,22,2,31,4,5,6,34,36,25,18,9,10,11,20,29],uri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deni:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],determin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],jenkin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],editpa:26,wikipedia:26,verbos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bring:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nagl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],redirect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inlin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],emac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],launchpad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rackspace_usernam:26,terremark:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"26am":34,jar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],should:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],local:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],contribut:5,"226ca64f":12,notat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],familiar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],passeng:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],autom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],beam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],increas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dsc_script:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],enabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],organ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],twice:32,sudoer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],num_to_keep:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sha:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],integr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],partit:18,contain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],view:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],debconf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],conform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],legaci:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],libshadow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],signatur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],displai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],elast:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],temporarili:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],brightbox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],imagemagick:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],xxxxx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],closer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],datadog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],impos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],correctli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pattern:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],machine_execut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vim74:26,sublim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],progress:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],application_php:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],email:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],retry_delai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],job:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],entir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],homebrew:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],swift:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],addit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],plugin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],admin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],equal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],etc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],instanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ami:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cinder:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sigterm:18,testclient:19,strftime:1,etm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],comment:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],extrasmal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hyphen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chmod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],solv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],b4c32f2:5,respect:31,rpm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mailto:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_email:26,yaml:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bluelock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dword_big_endian:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],insuffici:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],compon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],json:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],scriptabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ia2itmjrsw8:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],immedi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],capistrano:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],both:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vmware:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rvm:29,last:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thesecret123:36,present:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],replic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],need:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mvc3:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],defin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],passord:18,hkey_current_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],flowdock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],code_gener:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],helper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],squid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],slicehost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],archiv:[9,5],dual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lightweight:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],incom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],revis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],parti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],member:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],handl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],amazonec2tag:5,infer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],backtrac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],http:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hostnam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],again:36,keepal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],upon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nested_attribut:15,iop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],machine_batch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],identify_fil:[33,30,17],logfil:[9,34],php:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tftp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],expand:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cosmet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],center:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],not_if:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],well:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],command:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,30,31,32,33,34,35,36,37],digitalocean:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],setx:29,latest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],newest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],data_bag_item:36,less:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tcp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],end_tim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],machine_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],webui:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sdanna:5,dsc_resourc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sku:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],web:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gmc:28,smith:18,omnibu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],myhelpermodul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],apparmor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],foobar:32,logger:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"4d44b5b":5,match:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_path:26,cpan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],know:26,mynod:[25,29],cookbook_descript:5,recurs:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],insert:5,tail:34,resid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],like:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fsync:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],latest_vers:5,amazonaw:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],necessari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mustach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],soft:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],page:[9,34,27,18],apachev2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],eucalyptu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],revers:12,twitter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],kdc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],msiexec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_data_bag_item:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],flush:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],proper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],small:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],librari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tmp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbookvers:31,leaf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],leak:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],redis_lb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],qr_knife_web:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0a7ca19f":15,easy_install_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],investig:18,throttl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],usag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],symlink:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],maven:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vhost:5,host:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stage:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],homesick:5,sbin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ntlm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],actual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],justin:26,column:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],haproxi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],loftninja:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],disabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],own:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],automat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],guard:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],webpi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],smarto:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],merb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],virtualbox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],merg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],omnio:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],transfer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],appl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],downgrad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],progra:26,"var":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exampleorg:19,"function":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],waldendud:18,subscrib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],baseurl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],addloc:29,bff_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oauth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],highest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bug:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],count:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],made:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wise:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],arp_tabl:26,node_ip_address:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dmg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],whether:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rc1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],troubl:18,asynchron:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],record:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],below:18,limit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],indefinit:9,lvm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],otherwis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],problem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],actions_web:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],epel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],grantmc:28,evalu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ceilomet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dure:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],updated_at:5,ephemer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],implement:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mtime:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mutual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],boot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],detail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],virtual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],other:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],branch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],riak:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],upstart:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],juno:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rackspace_api_usernam:26,"100m":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thoreau:18,sbdm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],debian:[13,34,18,9,27,20],webpicmdlin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"25z":5,sphinx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tomcat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scientif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rule:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],blog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],emerg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0_8_1":5,cookbook:[13,19,2,34,18,9,10,27,20,29]},objtypes:{},objnames:{},filenames:["knife_role","knife_exec","knife_configure","knife_recipe_list","knife_environment","knife_cookbook_site","knife_download","knife_user","knife_list","ctl_chef_solo","knife_common_options","knife_delete","knife_status","index","knife_raw","knife_search","knife_index_rebuild","knife_ssl_check","ctl_chef_server","knife_client","knife","knife_diff","knife_edit","knife_show","knife_serve","knife_deps","knife_using","ctl_chef_shell","knife_xargs","knife_bootstrap","knife_ssl_fetch","knife_cookbook","knife_node","knife_ssh","ctl_chef_client","knife_upload","knife_data_bag","knife_tag"],titles:["knife role","knife exec","knife configure","knife recipe list","knife environment","knife cookbook site","knife download","knife user","knife list","chef-solo","Common Options","knife delete","knife status","chef-client Man Pages","knife raw","knife search","knife index rebuild","knife ssl check","chef-server-ctl","knife client","knife","knife diff","knife edit","knife show","knife serve","knife deps","Working with Knife","chef-shell","knife xargs","knife bootstrap","knife ssl fetch","knife cookbook","knife node","knife ssh","chef-client","knife upload","knife data bag","knife tag"],objects:{},titleterms:{help:18,show:[0,31,32,4,5,23,7,18,36,19],text:26,syntax:[0,1,2,3,4,25,6,7,8,11,12,14,15,16,35,19,21,22,23,24,5,26,28,29,31,32,33,36,37],privileg:34,configur:2,reregist:[7,19],window:[34,29],format:26,subcommand:18,stop:18,repo:26,ssl:[30,17],verb:26,ssh:33,password:18,restart:18,recip:3,term:18,tail:18,edit:[0,22,4,32,7,18,36,19],list:[0,31,32,3,37,4,5,7,18,8,36,19],upload:[35,31],authent:1,server:18,bag:36,common:10,kill:18,remov:32,set:26,chef:[34,9,27,18,13],instal:[5,18],download:[6,5,31],unshar:5,index:16,statu:[12,18],sub:26,compar:4,delet:[36,0,31,32,37,4,7,18,11,19],knife:[0,1,2,3,4,5,6,7,8,11,12,13,14,15,16,17,35,19,20,21,22,23,24,25,26,28,29,30,31,32,33,36,37],metadata:31,solo:9,run:34,add:32,ubuntu:29,org:18,plug:26,search:[26,15,5],cleans:18,page:13,recov:18,ctl:18,mani:26,backup:18,onc:18,apt:29,api:1,run_list:32,linux:34,diff:21,from:[32,4,36,0,31],log:18,script:1,data:[26,36],rebuild:16,upgrad:18,custom:29,avail:18,start:18,json:26,master:18,editor:26,shell:27,option:[0,1,2,3,4,25,6,7,8,9,10,11,12,14,15,16,35,19,21,22,23,24,5,27,28,29,31,32,33,34,36,37],rubi:1,reconfigur:18,bulk:[32,31,0,19],hup:18,uninstal:18,serv:24,dep:25,servic:18,work:26,fetch:30,bootstrap:29,creat:[0,31,32,37,4,7,18,36,19],"int":18,share:5,site:5,templat:29,mode:27,high:18,raw:14,tag:37,file:[0,31,32,4,18,36],check:17,quot:26,same:26,client:[13,34,19],role:0,test:31,environ:4,config:18,node:32,elev:34,exec:1,user:[26,7,18],xarg:28,associ:18,debian:29,man:13,gather:18,request:1,exampl:[0,1,2,3,4,25,6,7,8,9,11,12,14,15,16,35,19,21,22,23,24,5,28,29,31,32,33,34,36,37],command:26,wildcard:26,disassoci:18,cookbook:[5,31],microsoft:29}}) \ No newline at end of file
+Search.setIndex({envversion:42,terms:{kickstart:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chisamor:12,poorli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],four:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prefix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dirnam:26,rsyslog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oldest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],accur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],service_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],umask:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],descript:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_typ:[0,14,31,32,4,7,36,19],under:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],slowest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],replica:18,digit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],everi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_maintain:5,upstream:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],affect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],month:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],csshx:[33,30,17],raw_data:36,cmd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],upload:[],rabbitmq:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rabbitmqctl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],verif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],x86_64:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],proxy_url:29,hord:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],application_java:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hint_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],direct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],consequ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],second:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aggreg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ips_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],start_chef:29,even:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],supervis:18,hide:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],asid:27,peer_or_non:29,"new":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],net:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],topolog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],metadata:[],default_attribut:[4,0],kilobyt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],run_list_item:[32,9,34],displai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],never:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],macports_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],here:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],num_vers:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],recipe_nam:[32,0],host_head:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],path:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],interpret:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hosted_everyth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dry:[6,35,28,5],erl_cal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rubocop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],url_or_uri:[30,17],chefspec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],databagitem:36,runlist:[9,34],brought:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],substr:26,unix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],printf:1,hipchat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],txt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],describ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],would:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bundler:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],call:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],asset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],recommend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],indiana:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],type:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],until:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fastcgi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],relat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],server_url:27,notic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],warn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oc_bifrost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exce:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],relai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],killal:34,hold:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],must:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gecod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],join:1,henri:18,orgnam:[26,19,29],setup:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],work:[],bluebox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],raid1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],erb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fnmatch:31,root:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],could:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ss6p92l_sca:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],overrid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],give:[34,1],smtp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],elrepo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],indic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],want:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],keep:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],end:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],quot:[],eni:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vagrant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],how:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],env:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],verifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],config:[],updat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],after:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lab:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],emac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],befor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],windows_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],arch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],parallel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],demonstr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],request_path:14,attempt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],client_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opaqu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bootstrap:[],credenti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exclud:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alias:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],maintain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],environ:[],danno:7,enter:[12,21,34,0,14,1,32,33,15,31,4,5,6,7,37,35,26,36,19],order:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],softwar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],over:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],becaus:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vari:[29,18],cli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],generic_execut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],denver:37,better:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],persist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],erlang:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],serverspec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],split:1,them:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],woken:34,thei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],proce:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rackspaceknif:5,"40g":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],choic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],changelog:31,conflict:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],timeout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],each:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],debug:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],search_queri:[33,15,30,17,5],eacc:34,side:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mean:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],voxel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],log_loc:29,extract:[6,9,20,13],linod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],network:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reg_sz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],god:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],newli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],content:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rewrit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],devops_prod1:37,billing_admin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dsc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prioriti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],http_request:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],putti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gunicorn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],written:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ntp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],situat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],free:1,fred:36,qword:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],node1:32,kit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"1_0_0":5,"1_0_1":5,"1_0_2":5,"1_0_3":5,reconfigur:[],sigkil:18,reg_dword_big_endian:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],whateverthedefaultmightb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openssh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openssl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],filter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],iso:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],temporari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],user:[],pristin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rang:[12,15,34],render:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chefignor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],independ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],capac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],restrict:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hook:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],instruct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alreadi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],messag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],netfx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],primari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],role1:0,rewritten:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tinydn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],top:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sometim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mercuri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],master:[],too:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],amqp_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],john:18,listen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cloudform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],iptabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],consol:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"8wjyvhy9fhcegaareg":36,namespac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tool:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],erchef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0a58cf8":15,yield:26,"10g":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bookshelf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sha1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],max_arg:28,auxw:34,target:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],provid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tree:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zero:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],project:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],matter:26,gnupg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],entri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],minut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],provis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],behavior:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ram:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mine:29,unicast:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],raw:[],pessimist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],seed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],application_rubi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],snow:29,chefservicefeatur:29,blue:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],though:32,usernam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],glob:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],object:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],regular:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],s001:34,specifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],letter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],breakpoint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bsd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],don:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],doc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],metal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dog:36,doe:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_licens:26,wildcard:[],teck:7,unchang:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],antartica:29,dot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bomb:[9,27,34],runit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opposit:[6,13,35,20,18],whitelist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],random:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ruby_block:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],syntax:[],radio:7,identifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],make:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],celeri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],absolut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],layout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0a58e134":15,holder:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],configur:[],apach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lwrp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ldap:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],folder:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oct:33,likewis:5,stop:[],compli:18,amazon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],servermanagercmd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],report:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],youtub:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bar:[9,27,34],method:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],runa:34,reload:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zabbix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],no_proxy_url_or_ip:29,groupinstal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],num:[33,30,17],mandatori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],result:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],respons:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],noinput:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],key_fil:34,mdadm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],best:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rsa_kei:19,awar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],said:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],databas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],multiinst:26,sigint:18,solr4:18,irb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],irc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],approach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],databag:14,attribut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],extend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],were:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],extens:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],policyfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],toler:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],advertis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],kitchen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],protect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],easi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],met:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],howev:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],against:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fedora13:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],logic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],countri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],login:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],com:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rehash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],publishset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trunk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],loader:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],your_email:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],usr1:34,diff:[],trust:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],assum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],duplic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hints_path:29,chrome:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fri:33,three:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],been:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trigger:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],basic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],homepath:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hesit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],quickli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],life:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],file_edit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],suppress:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],worker:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],telnet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],argument:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],verify_api_cert:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],child:25,"catch":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ident:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],data_bag_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gnu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],servic:[],properti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],calcul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unsolv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dashboard:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nexenta:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],powershel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],seven:18,remount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],player:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exit:[9,34,1],conf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sever:15,amout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],growl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],perform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],suggest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],use_last_modifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],couchdb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],preserv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],descend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],djbdn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],syncd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],complet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],raid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],orgmapp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rais:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],portal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unicorn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tune:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mirror_expir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],kept:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scenario:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"30t21":5,flush_cach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],name_of_premium_featur:18,inherit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],contact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gzip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],everyth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],left:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],protocol:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],just:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sigusr1:34,bandwidth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],human:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],name_of_servic:18,yet:18,languag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],previous:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reboot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mod_php:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],had:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],macport:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],els:29,save:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ubuntu12:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ubuntu10:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],applic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_vers:[4,5,31],mayb:[9,27,34],metabas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fusion:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],json_class:[0,14,31,32,4,7,36,19],shadow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pingabl:18,daemon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],specif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deprec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nrpe:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],arbitrari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],manual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],graylog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deploy_revis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],public_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sublime_text:26,specifii:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],el6:18,underli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],multi_str:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],right:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],interv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],percentag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tibetanspaniel:36,intern:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],successfulli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],transmiss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],knife_config:29,total:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],setloc:29,deploy:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],track:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],select:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],condit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],foo:[9,27,14,34],localhost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],core:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],plu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],uncompress:5,insecur:18,repositori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],anagram:26,actions_messag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"super":34,grizzli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],subkei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],plug:[],postgresql:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],surround:[13,0,31,32,3,20,19],birdman:7,svn_argument:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],horizon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],commit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"float":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],profession:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bound:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],diwb:18,down:18,run_list:[],storag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],eth1:18,git:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],suffici:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],support:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nova:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"class":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],avail:[],reli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wordpress:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],editor:[],jane:18,sha512:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],war:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lowest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],head:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],noevict:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],form:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],forc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],some:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],forg:[13,30,17],useradd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"25t23":5,icmp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"true":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wmi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],middle_nam:18,attr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ssh_known_host:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],maximum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mtu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inaccur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fundament:31,opensus:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],featur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openbsd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],classic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],decrypt:36,sale:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],diagnost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],glanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ship:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],check:[],sticki:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],assembl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vista:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],groupmod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],encrypt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],when:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],actor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],win_wget_p:29,role:[],test:[],roll:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],node:[],notif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],intend:26,phoenix:37,kvm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],asterisk:[26,18],devop:[0,31,32,4,5,19],stompserv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],intent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],consid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sql:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],younger:7,search_attribut:1,faster:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],anywher:[6,35],pbkdf2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ignor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],time:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],push:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],backward:27,impli:15,skip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],consum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],redis2:5,netbsd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],row:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zookeep:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],varnish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],middl:[13,17],depend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zone:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],decim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],installonlypkg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],comun:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],decis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],jvm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],text:[],downtim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aspx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],application_python:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sourc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],string:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],org_nam:18,cookbooks_path:9,cloudstack:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lru:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],template_filenam:29,brows:[6,35],public_hostnam:33,script_fil:1,pkgbuild:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],administr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],level:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],did:[12,18],iter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],magnet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],item:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cooki:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],validation_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prevent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bffcreat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sign:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],port:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"5272a43f":12,raid5:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],appear:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],icinga:5,repli:[13,17],current:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],id3lib:5,reg_binari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deriv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],executionpolici:29,gener:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unauthor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef11:18,chef12:18,modif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],address:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],along:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],redmin:5,wait:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],box:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_environ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],invit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],netdev:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],checksum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],behav:26,healthi:12,regardless:29,rightscal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],extra:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],modul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],test_system:1,prefer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],peer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],leav:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],seattl:37,visibl:1,instal:[],post:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],regex:[32,3,31,0,19],memori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sensu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],subvers:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],msn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],handler:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],msi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],criteria:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],checkout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],azur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rabbitmq_chef:5,visual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tandem:18,templat:[],log_directori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],effort:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],role_nam:[32,0,25],proxy_cache_path:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tokyo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],uniqu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cat:1,descriptor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],profitbrick:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],graphit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],can:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],www:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opscode_erchef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],purpos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nearest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],container_servic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stream:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],backslash:[26,28],agent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],topic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],critic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mirrorlist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],occur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alwai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sundai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],multipl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gem_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ping:18,uptim:[33,18],write:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mixlib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],purg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],map:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],product:[13,21,35,15,4,6,18,20,29],omnitruck:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],max:28,clone:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sp4:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],identity_fil:[33,30,17,29],appnam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hklm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],log_level:[9,34,29],roundrobin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],data:[],man:[],freshli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nullsoft:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],purge_before_symlink:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],logwatch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],preced:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],combin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],talk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],port_list:26,config_fil:[10,30,17],ssh_wrapper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],partial_search:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ttl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gitignor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],still:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dynam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],entiti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],conjunct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],group:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],monitor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],duplex:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],platform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],non:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],main_monitor:3,rake:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],initi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],safari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],half:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nov:34,superset:26,provision:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],discuss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],term:[],name:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],drop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],revert:18,separ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],full_nam:18,compil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],failov:18,domain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],replac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],individu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],name_of_packag:18,continu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unlock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gnu_parallel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],year:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],happen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],subnet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shown:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"3rd":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],space:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"100g":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],profil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vrrp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],internet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],correct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hkey_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],orgtest:15,newsiz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],migrat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],argv:1,mime:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],org:[],"byte":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],care:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reusabl:31,wai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],frequenc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],synchron:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thing:18,place:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fa0fc4abf3f6787aeb5c3c5c35de667c:31,router:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],principl:26,think:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],frequent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],first:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],origin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],directli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],carri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],onc:[],arrai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"long":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oppos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],uncaught:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],open:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],predefin:1,size:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],iam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],given:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reprepro:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],silent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],install_chef:29,ssh_command:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],iaa:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],baremetalcloud:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],citi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cumul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],averag:33,white:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],apt_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],json_attrib:29,environment_nam:[9,4,25],hub:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],especi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],provinc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],copi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],full_control:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],artifact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],broadcast:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],minitest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"short":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],enclos:26,mostli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],john_smith:18,pecl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],than:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],png:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],serv:[],wide:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sbuild:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],windows_servic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],posix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],balanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],optimist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zsh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pre:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fork:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],config_cont:29,pro:26,delim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ani:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],client_kei:[26,34],ant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],medium:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],smartos_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cassandra:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],extralarg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],engin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],destroi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],note:1,sendfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ideal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],copyright_hold:31,take:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],noth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],channel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],begin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sure:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trace:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],normal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],buffer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],compress:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],statu:[],instiki:5,timestamped_deploi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pair:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],collectstat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],later:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],drive:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reg_expand_sz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],runtim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],superblock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],expand_str:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],salt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],netdev_interfac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],show:[],encrypted_data_bag_secret:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],concurr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],permiss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sysctl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],help:[],xml:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],onli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],explicitli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],moneta:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],favor:[33,30,17],gceserviceaccount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],transact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],activ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],state:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dword:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hello_world:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],analyt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sighup:18,nearli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],variou:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],get:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stomp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],secondari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],repo:[],ssl:[],cannot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ssh:[],requir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],debian5:29,foodcrit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aptitud:33,netscalar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aris:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],where:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],summari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wiki:[26,5],kernel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],installshield:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],spork:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],endloc:29,drbd0:18,data_bag:[26,36,14],xenserv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],concern:18,detect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],review:[0,1,2,3,4,25,6,7,8,11,12,14,15,16,35,29,21,22,23,24,5,28,19,31,32,33,36,37],label:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],behind:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],volatil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],between:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dockerfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"import":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],across:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sname:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],parent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],node_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],screen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],solaris_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],supermarket:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],syntax_check_cache_path:26,come:26,tue:34,gpasswd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],uuid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],librato:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pychef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],library_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],datamapp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mani:[],runcontext:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reindex:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],color:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],period:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],symfoni:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],colon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],generic_writ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cancel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dsc_mof:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],poll:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bluepil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ultim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],org_full_nam:18,west:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rebuild:[],replace_str:28,mark:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],spiceweasel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rebuilt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],my_cookbook:31,rubi:[],editpad:26,those:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"case":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],eip:21,pedant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],invok:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],base64:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],region:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],suse:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],application_nginx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stdout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],metric:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_client:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],airbrak:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cluster:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ascii:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aa384235:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],develop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],author:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],media:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],same:[],binari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],html:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],document:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],week:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],finish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],webserv:[21,32,33,34,25,6,35,9,27,29],nest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],confidenti:36,driver:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],capabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openldap:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],improv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],extern:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],repoforg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],appropri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],megabyt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],without:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trusted_certs_dir:[13,30],model:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],resource_collect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],a29d6f254577b830091f140c3a78b1f:31,execut:[],loaderror:33,key_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],kill:[],aspect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],org_cleanu:3,touch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],passphras:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],http_proxi:29,speed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aws_access_key_id:26,samba:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],display_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],except:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],apache2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],identif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],instrument:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],query_to_run:15,ruby1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pill:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],earli:18,around:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ohai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],read:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],traffic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],platform_vers:31,world:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yyyymmddhhmmss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mof:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],iftop:5,integ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],server:[],either:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],output:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rubyv:1,manag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cisco:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],glesi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],server01:[33,30,17],freez:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rsync:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],keytab:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],easili:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],definit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],appscript:33,keyston:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],highcpu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],portage_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],knife:[],refer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],power:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],notepad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inspect:[6,13,20],broken:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],a45298c9:12,starttim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],found:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],berksfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bazaar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],appli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],comparison:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],central:9,ack:5,gplv2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gplv3:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],acl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],percona:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],act:27,backup:[],processor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],effici:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],max_siz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],insuffici:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],your:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],charli:36,hkey_current_config:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],log:[],daemontool:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],simultan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],overwrit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],start:[],interfac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ipv4:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ipv6:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],svn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],enough:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bundl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],untar:5,cabinet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opensolari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],activemq:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],conclus:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],longer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chefclientfeatur:29,pull:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],possibl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"default":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pacman:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bucket:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],powershell_script:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vhd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],embed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],connect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cbc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],uid:36,creat:[],certain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],remote_directori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_handl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],decreas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fail2ban:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],file:[],fill:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],incorrect:34,file_maxbyt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],googl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prepend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],field:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],valid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],you:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],architectur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],codecademi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],registri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sequenc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],symbol:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pear:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fsck:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],snitch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dropbox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pool:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],netdev_lag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reduc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],directori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_copyright:26,mask:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],use_etag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],escap:[26,28],cpu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],actions_consum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],represent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],all:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],selinux:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],forbidden:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ibm305ramac:1,lacp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],java_opt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],netdev_l2_interfac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],follow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],disk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],children:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sympa:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dsl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],init:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],program:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],app_conf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scratch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],introduc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cloudkick:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],global:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],premium:18,fals:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],checkin:1,subcommand:[],util:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],verb:[],mechan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],failur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],veri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ossec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],excluded_memb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],list:[],last_nam:18,gerritt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],recipe_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],plain:36,user_nam:[33,30,7,17,18],pid_fil:34,enterpris:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],drbd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sync:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],past:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],syslog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rate:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],design:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pass:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ssh_attr:[33,30,17],further:18,current_dir:26,proxi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],what:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yum_repositori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sub:[],section:[13,20,26],abl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],brief:[12,13,20],rackspac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],delet:[],abbrevi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],version:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],noprofil:29,"public":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prereleas:29,full:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],berkelei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],multilib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],solari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],excess:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gandi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],standard:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],modifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],valu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thrift:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],search:[],memcach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prior:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],amount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pick:34,action:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],warrant:[13,20,1],via:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],transit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tmux:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],filenam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],establish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],redisio:4,proceed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],regist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],two:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],validation_client_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],more:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],flat:8,association_us:18,wrapper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],desir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],site:[],flag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],particular:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],known:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],compani:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],destin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],installroot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],psql:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],none:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],endpoint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hour:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dep:[],dev:[12,32,15,34,4,18,9,27],histori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oktawav:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],remain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hkey_local_machin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],caveat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],learn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nagio:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],external_url:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prompt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scan:34,share:[],bootstrap_directori:29,accept:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],verify_non:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],minimum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],poni:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],explor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_data_bag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],csh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],first_nam:18,secur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rather:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],anoth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pxe_dust:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],simpl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],distro:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],regener:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],resourc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],referenc:[7,19],vlan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fstype:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rbac:26,perl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],data_bag_item_dogs_tibetanspaniel:36,associ:[],github:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],postfix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],created_at:5,django:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],caus:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],allkei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],logrot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opscod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rotat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],templatefortextstr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],i386:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],through:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],htop:5,paramet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],create_dirs_before_symlink:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],systemd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sql_databas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exact:[32,15],pend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_nam:[0,25,5,31],bypass:[6,13,20],"return":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],graylog2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],timestamp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],framework:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],admin_nam:26,troubleshoot:18,hkey_classes_root:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],authent:[],"1password":5,userprofil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],token:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],average_r:5,compris:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fulli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unicod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],only_if:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],truncat:[32,5],denni:7,harm:[13,30],"300mb":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hard:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],crontab:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],expect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],new_client:1,create_wait_m:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],portland:37,beyond:26,event:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ftp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vancouv:37,robert:7,publish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],etag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],print:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],occurr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],file_nam:[19,7,31,18],gpl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],qualifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],asp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],devops_data:36,advanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],upon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],campfir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],effect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],quick:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reason:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],base:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],put:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],workstat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],basi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thread:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],launch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],omit:[15,19],perman:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],heartbeat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],assign:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],excurs:18,notifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],upper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],number:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],env_vari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],done:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stdlib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],blank:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],miss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],file_atomic_upd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pgdg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],differ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],script:[],ipaddress:1,interact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unrestrict:29,least:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],checkpoint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],win2k8:15,statement:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zeromq:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scheme:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],journli:4,jetti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],store:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],schema:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dpkg_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],storm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],part:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pars:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],consult:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dpkg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reinstal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],grep:[34,5,29],remot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],remov:[],reg_qword:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],secret_access_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],randomli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],comput:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gvim:26,packag:[],expir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dedic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],testmast:18,berkshelf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],built:[26,18],equival:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],also:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],centos5:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rakefil:21,build:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stackforg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],splai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],compat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pipelin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],distribut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exec:[],previou:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],quota:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],most:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],private_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],preprod:18,clear:34,cover:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],destruct:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],clojur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],clean:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],packagecloud:18,configuration_data_script:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],microsoft:[],carefulli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],xcode:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alphanumer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ignore_failur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],session:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fine:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],affin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],firewal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bff:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pretti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],solut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],jtimberman:[5,29],darwin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yml:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],everysec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unus:[7,19],chef_gem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"__file__":26,express:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],verify_p:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nativ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mainten:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fastest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],restart:[],"225f954f":12,data_bag_name_or_path:36,crt:21,boost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],your_company_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],common:[],gelf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cmdlet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],syntax_check_cach:26,certif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],set:[],dump:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],creator:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],startup:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ifconfig:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],see:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],arg:28,reserv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ark:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],flavor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cssh:[33,30,17],git_ssh:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],example_nod:1,prempt_delai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],someth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],subscript:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],altern:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],solo:[],chef_nod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gemfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],numer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],javascript:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],succeed:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],distinguish:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],solr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],popul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],satisfi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reg_multi_sz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],delimit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],configuration_data:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pdn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],context:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],access_key_id:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lash:1,vault:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],load:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],markdown:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],point:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],schedul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],uptod:18,header:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shutdown:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ucspi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],desktop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],backend:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],authz:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rackspace_api_kei:26,unsuccess:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],java:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],devic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],add:[],empti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],secret:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],strategi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],atomic_upd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],homebrew_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],togeth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],imag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rspec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],understand:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0_8_0":5,look:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],registry_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],frozen:31,hkcc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bill:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],batch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],durat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],formatt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"while":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],corpsit:21,abov:29,error:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hkcr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],maradn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],loop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hkcu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],real:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],motd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],readm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],client_desc:1,dynect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],itself:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cento:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],skype:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vcloud:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unmount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fedora:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],grant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],belong:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hadoop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shorter:1,octal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],languages_ruby_vers:15,higher:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],x86:26,"0_7_0":5,optim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cloud:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wherea:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inflat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alert:5,jpackag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lxc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nosess:26,typic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],recent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lower:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],task:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lib:29,older:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],british_sea_pow:29,ssl_verify_mod:[13,17,29],person:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],apptastic_tier_nam:[9,27,34],reflect:4,docker:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rbenv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],propos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],override_attribut:[4,34,27,0,9],mysql:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openstack:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"07z":5,password:[],busser:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],web03:15,win:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],input:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tell:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],subsequ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],app:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vendor:5,obsolet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fqdn_or_ip_address:29,format:[],ipmi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],main_attribut:15,local_download_path:29,nginx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exceptionclass:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],characterist:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],success:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],signal:18,svlogd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],resolv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],elaps:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],collect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],princip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],api:[],encount:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vsphere:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],often:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],simplifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],add_formatt:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],acknowledg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],creation:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],macterm:[33,30,17],back:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],unspecifi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sampl:[32,36,0,18],staticfil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],force_overrid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mirror:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_rol:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],virtualenv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scale:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lamin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],per:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],attribute_nam:32,retri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],larg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],undon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],slash:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],prod:18,proc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],snort:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],machin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sql_user:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],agreement:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],infra:18,step:[13,30,34],apptast:[9,27,34],wget:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],crond:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ufw:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],generic_read:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],constraint:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],drbdadm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],idl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],block:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],instance_typ:15,nsi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hudson:5,ohai_tim:1,smart_o_s_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opscodesupport:5,within:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ensur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rundeck:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],errno:34,question:26,arctic_hint:29,fast:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],custom:[],includ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],suit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],forward:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],properli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ifcfg:15,textpad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],remote_source_msi_url:29,pwd:29,link:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],translat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],newer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],atom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],noninteract:29,line:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],penguin:29,info:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],utc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],consist:[26,0],munin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],groovi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nscd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"export":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],similar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nsca:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],supervisor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],doesn:32,repres:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"char":28,incomplet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],home:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],curl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],titl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sequenti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],invalid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"_imag":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],transport:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],peopl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nice:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deseri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mongodb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],meaning:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_server_url:[26,34,27,29],eval:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],splunk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ladvd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],desert:25,lang:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"1024mb":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],infrequ:[13,20,1],algorithm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],confirm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yourcompani:26,depth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_overview_attribut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hello:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],endtim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],code:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],partial:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],queri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],groupadd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trywgfa6r70no28pnhmpghevkbzuxouemnbnauqsuyo:36,steve:7,privat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ulimit:4,elsewher:[],send:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],junip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fatal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],getchef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],passiv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vlc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],volum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],recip:[],magic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],netdev_vlan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],id_rsa:29,geograph:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hive:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"try":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pleas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],malici:[13,30],startup_typ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],jdk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cron:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],slackwar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],download:[],click:34,append:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ps1:29,index:[],turn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],compar:[],a47823c9:12,winrm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],find:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],access:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],f65c969b:12,logloc:[9,34],isapi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hku:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bodi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],let:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ubuntu:[],becom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sinc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],convert:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],copyright:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],overwritten:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aardvark:26,larger:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],steadi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fetch:[],converg:34,cert:29,rpm_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ctl:[],chang:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],honor:27,fstab:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],firefox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ago:12,danger:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],spec_help:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],approxim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gatewai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],apt:[],"boolean":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],smartmon:31,redi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pxe:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],from:[],zip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],commun:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],doubl:26,upgrad:[],nexu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],next:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],websit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],few:[34,18],use_conditional_get:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],usr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sort:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],src:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mismatch:4,about:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"transient":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],starter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],account:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],retriev:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tunnel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alia:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],crazi:36,hint_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],control:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sqlite:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],weaker:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],process:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sudo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_collect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],high:[],tag:[],proprietari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tarbal:[5,18],someurlher:31,symlink_before_migr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],delai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sit:[26,36],tamper:[13,30],zenpack:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reg_dword:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],subdirectori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],instead:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],opscode_us:26,zendmd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],msdn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],somelongurlher:31,overridden:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],watch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],apicli:19,tier:[],chef_repo_path:[21,13,22,35,25,23,6,24,8,11,28],physic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tenant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],alloc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],delete_kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],essenti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bind:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zenoss:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],correspond:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],issu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],client_foo:19,allow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yum_globalconfig:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],aws_secret_access_kei:26,jira:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],restorecon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],comma:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sql_ro_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],infrastructur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],openvpn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],asa:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bittorr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],therefor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],keepaliv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],greater:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],python:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],auto:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],auth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yum_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rubygem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],recipe_url:9,front:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],file_cache_path:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],trac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],anyth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],edit:[],radiant:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pacman_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0a7cffd5":15,resource_nam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],all_cap:26,subset:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],jane_do:18,chunk:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],meta:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"static":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ec2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],citrix:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],patch:5,special:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],out:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],variabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gentoo:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bag:[],armor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],erlang_solut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rails_enterpris:5,categori:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],suitabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rem:29,hardwar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"_default":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"56g":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],local_destination_msi_path:29,red:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sql_server:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shut:18,insid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],workflow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],manipul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],standalon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],releas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shortest:18,qpid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stackscript:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],s3_bucket:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ask:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fqdn:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],david:18,length:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],outsid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],retain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],respond:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],polici:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],echo:29,date:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],puppet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pgp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],kerbero:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],owner:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],facil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],underscor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],erubi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],licens:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mkdir:29,system:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],arista:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],attach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],attack:[13,17],privaci:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],termin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"final":29,uri_for_https_serv:30,udp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shell:[],big:18,fuzzi:15,shallow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rdoc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rsa:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exactli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],haven:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],passenger_apache2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],homedr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],structur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],charact:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sens:5,sensit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],start_tim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],plaintext:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],remote_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inno:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],download_directori:31,have:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bootstrap_proxi:29,cfengin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],freebsd_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],min:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rout:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],atim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],accuraci:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],which:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"256f884f":12,datacent:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],zlib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],force_default:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],reposerv:29,unless:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],freebsd:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fidel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],who:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oracl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],discov:29,cipher:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deploi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],xarg:[],kuwata:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],segment:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],why:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],push_job:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],placement:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],p180:29,url:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],request:[],uri:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],deni:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],yum:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],determin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],jenkin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],editpa:26,millisecond:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wikipedia:26,verbos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bring:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nagl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],redirect:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inlin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],locat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],launchpad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rackspace_usernam:26,terremark:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"26am":34,jar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sendmail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],should:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],local:[],contribut:5,"226ca64f":12,notat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],familiar:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],passeng:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],autom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],beam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],increas:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dsc_script:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],enabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],organ:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],twice:32,sudoer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],num_to_keep:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sha:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stuff:[9,27,34],integr:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],partit:18,contain:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_zero:34,view:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],debconf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],conform:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],legaci:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],libshadow:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],signatur:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],easy_install_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],elast:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],temporarili:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],brightbox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],imagemagick:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],xxxxx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],closer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],datadog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],impos:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],correctli:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pattern:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],machine_execut:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vim74:26,sublim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],progress:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],application_php:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],email:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],kei:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],retry_delai:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],job:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],entir:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],homebrew:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],swift:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],addit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],plugin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],admin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],equal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],etc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],instanc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ami:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cinder:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sigterm:18,testclient:19,strftime:1,etm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],comment:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],extrasmal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hyphen:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chmod:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],solv:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],b4c32f2:5,respect:31,rpm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mailto:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_email:26,yaml:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bluelock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dword_big_endian:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],enable_apptast:[9,27,34],compon:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],json:[],treat:[9,27,34],scriptabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ia2itmjrsw8:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],immedi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],capistrano:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],both:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vmware:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rvm:29,last:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thesecret123:36,present:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],replic:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],need:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mvc3:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],defin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],passord:18,hkey_current_us:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],flowdock:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],code_gener:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],helper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],squid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],slicehost:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],archiv:[9,5],dual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],lightweight:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],incom:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],revis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],parti:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],member:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],handl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],amazonec2tag:5,infer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],backtrac:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],http:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],hostnam:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],again:36,keepal:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"null":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],nested_attribut:15,iop:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],machine_batch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],identify_fil:[33,30,17],logfil:[9,34],php:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tftp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],expand:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cosmet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],center:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],not_if:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],well:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],command:[],digitalocean:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],setx:29,latest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],newest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],data_bag_item:36,less:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tcp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],end_tim:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],machine_fil:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],webui:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sdanna:5,dsc_resourc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],sku:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],web:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],gmc:28,smith:18,omnibu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],myhelpermodul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],apparmor:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],foobar:32,logger:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"4d44b5b":5,match:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbook_path:26,cpan:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],know:26,mynod:[25,29],cookbook_descript:5,recurs:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],insert:5,tail:[],resid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],like:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],fsync:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],latest_vers:5,amazonaw:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],necessari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mustach:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],soft:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],page:[],apachev2:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],shef:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],eucalyptu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],revers:12,twitter:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],kdc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],msiexec:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],chef_data_bag_item:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],flush:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],proper:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],small:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],librari:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tmp:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],cookbookvers:31,leaf:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],leak:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],redis_lb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],qr_knife_web:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0a7ca19f":15,mode:[],investig:18,throttl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],usag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],symlink:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],maven:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],vhost:5,host:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],stage:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],homesick:5,sbin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ntlm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],actual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],justin:26,column:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dism:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],haproxi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],loftninja:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],disabl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],own:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],automat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],guard:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],webpi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],smarto:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],merb:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],virtualbox:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],merg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],omnio:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],transfer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],machine_imag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],singl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],appl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],downgrad:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],progra:26,"var":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],exampleorg:19,"function":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],waldendud:18,subscrib:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],baseurl:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],addloc:29,bff_packag:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],oauth:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],highest:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],bug:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],count:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],succe:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],made:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],wise:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],arp_tabl:26,node_ip_address:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dmg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],whether:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rc1:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],troubl:18,asynchron:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],record:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],below:18,limit:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],indefinit:[9,34],lvm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],otherwis:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],problem:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],actions_web:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],epel:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],grantmc:[28,18],evalu:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],ceilomet:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],dure:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pid:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],updated_at:5,ephemer:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],implement:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mtime:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],pip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],inc:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],mutual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],boot:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],detail:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],virtual:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],other:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],branch:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],riak:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],upstart:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],juno:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rackspace_api_usernam:26,"100m":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],thoreau:18,sbdm:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],debian:[],webpicmdlin:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"25z":5,sphinx:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],tomcat:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],scientif:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],rule:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],blog:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],emerg:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"0_8_1":5,cookbook:[]},objtypes:{},objnames:{},filenames:["knife_role","knife_exec","knife_configure","knife_recipe_list","knife_environment","knife_cookbook_site","knife_download","knife_user","knife_list","ctl_chef_solo","knife_common_options","knife_delete","knife_status","index","knife_raw","knife_search","knife_index_rebuild","knife_ssl_check","ctl_chef_server","knife_client","knife","knife_diff","knife_edit","knife_show","knife_serve","knife_deps","knife_using","ctl_chef_shell","knife_xargs","knife_bootstrap","knife_ssl_fetch","knife_cookbook","knife_node","knife_ssh","ctl_chef_client","knife_upload","knife_data_bag","knife_tag"],titles:["knife role","knife exec","knife configure","knife recipe list","knife environment","knife cookbook site","knife download","knife user","knife list","chef-solo","Common Options","knife delete","knife status","chef-client Man Pages","knife raw","knife search","knife index rebuild","knife ssl check","chef-server-ctl (executable)","knife client","knife","knife diff","knife edit","knife show","knife serve","knife deps","Working with Knife","chef-shell","knife xargs","knife bootstrap","knife ssl fetch","knife cookbook","knife node","knife ssh","chef-client","knife upload","knife data bag","knife tag"],objects:{},titleterms:{help:18,execut:18,show:[0,31,32,4,5,23,7,18,36,19],text:26,syntax:[0,1,2,3,4,25,6,7,8,11,12,14,15,16,35,19,21,22,23,24,5,26,28,29,31,32,33,36,37],privileg:34,configur:2,reregist:[7,19],window:[34,29],local:18,format:26,subcommand:18,stop:18,repo:26,ssl:[30,17],verb:26,ssh:33,password:18,restart:18,recip:3,term:18,tail:18,edit:[0,22,4,32,7,18,36,19],list:[0,31,32,3,37,4,5,7,18,8,36,19],upload:[35,31],authent:1,server:18,bag:36,common:10,kill:18,remov:[32,18],set:26,chef:[34,9,27,18,13],instal:[5,18],download:[6,31,5,18],unshar:5,index:16,statu:[12,18],sub:26,compar:4,delet:[36,0,31,32,37,4,7,18,11,19],knife:[0,1,2,3,4,5,6,7,8,11,12,13,14,15,16,17,35,19,20,21,22,23,24,25,26,28,29,30,31,32,33,36,37],metadata:31,solo:9,run:34,add:[32,18],ubuntu:29,org:18,plug:26,search:[26,15,5],cleans:18,page:13,recov:18,ctl:18,mani:26,backup:18,onc:18,apt:29,api:1,run_list:32,linux:34,diff:21,from:[32,4,36,0,31],log:18,script:1,data:[26,36],rebuild:16,upgrad:18,custom:29,avail:18,start:18,json:26,master:18,editor:26,shell:27,option:[0,1,2,3,4,25,6,7,8,9,10,11,12,14,15,16,35,19,21,22,23,24,5,27,28,29,31,32,33,34,36,37],rubi:1,reconfigur:18,bulk:[32,31,0,19],hup:18,uninstal:18,serv:24,packag:18,dep:25,servic:18,work:26,fetch:30,bootstrap:29,creat:[0,31,32,37,4,7,18,36,19],"int":18,share:5,site:5,templat:29,mode:27,high:18,raw:14,tag:37,file:[0,31,32,4,18,36],check:17,quot:26,same:26,client:[13,34,19],role:0,test:31,environ:4,config:18,node:32,elev:34,exec:1,user:[26,7,18],xarg:28,associ:[],debian:29,man:13,gather:18,request:1,exampl:[0,1,2,3,4,25,6,7,8,9,11,12,14,15,16,35,19,21,22,23,24,5,28,29,31,32,33,34,36,37],command:26,wildcard:26,disassoci:[],cookbook:[5,31],microsoft:29}}) \ No newline at end of file
diff --git a/distro/common/man/man1/chef-shell.1 b/distro/common/man/man1/chef-shell.1
index 97aa50bbd0..df004c5b0f 100644
--- a/distro/common/man/man1/chef-shell.1
+++ b/distro/common/man/man1/chef-shell.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "CHEF-SHELL" "1" "Chef 11.16" "" "chef-shell"
+.TH "CHEF-SHELL" "1" "Chef 12.0" "" "chef-shell"
.SH NAME
chef-shell \- The man page for the chef-shell command line tool.
.
@@ -101,6 +101,77 @@ Shows help for the command.
.TP
.B \fB\-j PATH\fP, \fB\-\-json\-attributes PATH\fP
The path to a file that contains JSON data.
+.sp
+Use this option to define a \fBrun_list\fP object. For example, a JSON file similar to:
+.INDENT 7.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+"run_list": [
+ "recipe[base]",
+ "recipe[foo]",
+ "recipe[bar]",
+ "role[webserver]"
+],
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+may be used by running \fBchef\-client \-j path/to/file.json\fP\&.
+.sp
+In certain situations this option may be used to update \fBnormal\fP attributes.
+.sp
+\fBWARNING:\fP
+.INDENT 7.0
+.INDENT 3.5
+Any other attribute type that is contained in this JSON file will be treated as a \fBnormal\fP attribute. For example, attempting to update \fBoverride\fP attributes using the \fB\-j\fP option:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+{
+ "name": "dev\-99",
+ "description": "Install some stuff",
+ "override_attributes": {
+ "apptastic": {
+ "enable_apptastic": "false",
+ "apptastic_tier_name": "dev\-99.bomb.com"
+ }
+ }
+}
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+will result in a node object similar to:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+{
+ "name": "maybe\-dev\-99",
+ "normal": {
+ "name": "dev\-99",
+ "description": "Install some stuff",
+ "override_attributes": {
+ "apptastic": {
+ "enable_apptastic": "false",
+ "apptastic_tier_name": "dev\-99.bomb.com"
+ }
+ }
+ }
+}
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.UNINDENT
+.UNINDENT
.TP
.B \fB\-l LEVEL\fP, \fB\-\-log\-level LEVEL\fP
The level of logging that will be stored in a log file.
diff --git a/distro/common/man/man1/knife-bootstrap.1 b/distro/common/man/man1/knife-bootstrap.1
index 1068daa224..a4a699872f 100644
--- a/distro/common/man/man1/knife-bootstrap.1
+++ b/distro/common/man/man1/knife-bootstrap.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-BOOTSTRAP" "1" "Chef 11.16" "" "knife bootstrap"
+.TH "KNIFE-BOOTSTRAP" "1" "Chef 12.0" "" "knife bootstrap"
.SH NAME
knife-bootstrap \- The man page for the knife bootstrap subcommand.
.
@@ -57,61 +57,78 @@ This subcommand has the following options:
.B \fB\-A\fP, \fB\-\-forward\-agent\fP
Use to enable SSH agent forwarding.
.TP
-.B \fB\-\-bootstrap\-no\-proxy NO_PROXY_URL_or_IP\fP
-A URL or IP address that specifies a location that should not be proxied. Note: This option is used internally by Chef to help verify bootstrap operations during testing and should never be used during an actual bootstrap operation.
-.TP
-.B \fB\-\-bootstrap\-proxy PROXY_URL\fP
-The proxy server for the node that is the target of a bootstrap operation.
-.TP
-.B \fB\-\-bootstrap\-version VERSION\fP
-The version of the chef\-client to install.
-.TP
-.B \fB\-c CONFIG_FILE\fP, \fB\-\-config CONFIG_FILE\fP
-The configuration file to use.
+.B \fB\-\-bootstrap\-curl\-options OPTIONS\fP
+Use to specify arbitrary options to be added to the bootstrap command when using cURL\&. This option may not be used in the same command with \fB\-\-bootstrap\-install\-command\fP\&.
.TP
-.B \fB\-\-chef\-zero\-port PORT\fP
-The port on which chef\-zero will listen.
+.B \fB\-\-bootstrap\-install\-command COMMAND\fP
+Use to execute a custom installation command sequence for the chef\-client\&. This option may not be used in the same command with \fB\-\-bootstrap\-curl\-options\fP, \fB\-\-bootstrap\-install\-sh\fP, or \fB\-\-bootstrap\-wget\-options\fP\&.
.TP
-.B \fB\-\-[no\-]color\fP
-Use to view colored output.
+.B \fB\-\-bootstrap\-install\-sh URL\fP
+Use to fetch and execute an installation script at the specified URL. This option may not be used in the same command with \fB\-\-bootstrap\-install\-command\fP\&.
.TP
-.B \fB\-d DISTRO\fP, \fB\-\-distro DISTRO\fP
+.B \fB\-\-bootstrap\-no\-proxy NO_PROXY_URL_or_IP\fP
+A URL or IP address that specifies a location that should not be proxied.
.sp
-\fBWARNING:\fP
+\fBNOTE:\fP
.INDENT 7.0
.INDENT 3.5
-The default bootstrap operation uses the omnibus installer, which means the default template file (\fBchef\-full\fP) should work on all supported platforms. It is recommended to use custom bootstrap templates only when the omnibus installer cannot be used. The \fB\&.erb\fP file extension is added automatically and should not be passed as part of the bootstrap command.
+This option is used internally by Chef to help verify bootstrap operations during testing and should never be used during an actual bootstrap operation.
.UNINDENT
.UNINDENT
-.sp
-The template file to be used during a bootstrap operation. The following distributions are supported: \fBchef\-full\fP (the default bootstrap), \fBcentos5\-gems\fP, \fBfedora13\-gems\fP, \fBubuntu10.04\-gems\fP, \fBubuntu10.04\-apt\fP, \fBubuntu12.04\-gems\fP, and the name of a custom bootstrap template file. When this option is used, knife will search for the template file in the following order: the \fBbootstrap/\fP folder in the current working directory, the \fBbootstrap/\fP folder in the chef\-repo, the \fBbootstrap/\fP folder in the \fB~/.chef/\fP directory, or a default bootstrap file. Do not use the \fB\-\-template\-file\fP option when \fB\-\-distro\fP is specified.
.TP
-.B \fB\-\-defaults\fP
-Use to have knife use the default value instead of asking a user to provide one.
+.B \fB\-\-bootstrap\-proxy PROXY_URL\fP
+The proxy server for the node that is the target of a bootstrap operation.
.TP
-.B \fB\-\-disable\-editing\fP
-Use to prevent the $EDITOR from being opened and to accept data as\-is.
+.B \fB\-\-bootstrap\-version VERSION\fP
+The version of the chef\-client to install.
.TP
-.B \fB\-e EDITOR\fP, \fB\-\-editor EDITOR\fP
-The $EDITOR that is used for all interactive commands.
+.B \fB\-\-bootstrap\-wget\-options OPTIONS\fP
+Use to specify arbitrary options to be added to the bootstrap command when using GNU Wget\&. This option may not be used in the same command with \fB\-\-bootstrap\-install\-command\fP\&.
.TP
.B \fB\-E ENVIRONMENT\fP, \fB\-\-environment ENVIRONMENT\fP
The name of the environment. When this option is added to a command, the command will run only against the named environment.
.TP
-.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
-The output format: \fBsummary\fP (default), \fBtext\fP, \fBjson\fP, \fByaml\fP, and \fBpp\fP\&.
-.TP
.B \fB\-G GATEWAY\fP, \fB\-\-ssh\-gateway GATEWAY\fP
The SSH tunnel or gateway that is used to run a bootstrap action on a machine that is not accessible from the workstation.
.TP
-.B \fB\-h\fP, \fB\-\-help\fP
-Shows help for the command.
-.TP
.B \fB\-\-hint HINT_NAME[=HINT_FILE]\fP
-An Ohai hint to be set on the target of the bootstrap. The hint is contained in a file and is formatted as JSON: \fB{"attribute":"value","attribute":"value"...}\fP\&. \fBHINT_NAME\fP is the name of the hint and \fBHINT_FILE\fP is the name of the hint file located at \fB/etc/chef/ohai/hints/HINT_FILE.json\fP\&. Use multiple \fB\-\-hint\fP options in the command to specify multiple hints.
-.TP
-.B \fB\-\-[no\-]host\-key\-verify\fP
-Use \fB\-\-no\-host\-key\-verify\fP to disable host key verification. Default setting: \fB\-\-host\-key\-verify\fP\&.
+Use to specify an Ohai hint to be set on the target node.
+.sp
+Ohai hints are used to tell Ohai something about the system that it is running on that it would not be able to discover itself. An Ohai hint exists if a JSON file exists in the hint directory with the same name as the hint. For example, calling \fBhint?(\(aqantartica\(aq)\fP in an Ohai plugin would return an empty hash if the file \fBantartica.json\fP existed in the hints directory, and return nil if the file does not exist.
+.sp
+If the hint file contains JSON content, it will be returned as a hash from the call to \fBhint?\fP\&.
+.INDENT 7.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+{
+ "snow": true,
+ "penguins": "many"
+}
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.INDENT 7.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+arctic_hint = hint?(\(aqantartica\(aq)
+if arctic_hint[\(aqsnow\(aq]
+ "There are #{arctic_hint[\(aqpenguins\(aq]} penguins here."
+else
+ "There is no snow here, and penguins like snow."
+end
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+The default directory in which hint files are located is \fB/etc/chef/ohai/hints/\fP\&. Use the \fBOhai::Config[:hints_path]\fP setting in the client.rb file to customize this location.
+.sp
+\fBHINT_FILE\fP is the name of the JSON file. \fBHINT_NAME\fP is the name of a hint in a JSON file. Use multiple \fB\-\-hint\fP options to specify multiple hints.
.TP
.B \fB\-i IDENTITY_FILE\fP, \fB\-\-identity\-file IDENTITY_FILE\fP
The SSH identity file used for authentication. Key\-based authentication is recommended.
@@ -119,12 +136,24 @@ The SSH identity file used for authentication. Key\-based authentication is reco
.B \fB\-j JSON_ATTRIBS\fP, \fB\-\-json\-attributes JSON_ATTRIBS\fP
A JSON string that is added to the first run of a chef\-client\&.
.TP
-.B \fB\-k KEY\fP, \fB\-\-key KEY\fP
-The private key that knife will use to sign requests made by the API client to the Chef server\&.
-.TP
.B \fB\-N NAME\fP, \fB\-\-node\-name NAME\fP
The name of the node.
.TP
+.B \fB\-\-[no\-]host\-key\-verify\fP
+Use \fB\-\-no\-host\-key\-verify\fP to disable host key verification. Default setting: \fB\-\-host\-key\-verify\fP\&.
+.TP
+.B \fB\-\-[no\-]node\-verify\-api\-cert\fP
+Use \fBverify_api_cert\fP to only do SSL validation of the Chef server connection; may be needed if the chef\-client needs to talk to other services that have broken SSL certificates. If this option is not specified, the setting for \fBverify_api_cert\fP in the configuration file is applied.
+.TP
+.B \fB\-\-node\-ssl\-verify\-mode PEER_OR_NONE\fP
+The verify mode for HTTPS requests.
+.sp
+Use \fB:verify_none\fP to do no validation of SSL certificates.
+.sp
+Use \fB:verify_peer\fP to do validation of all SSL certificates, including the Chef server connections, S3 connections, and any HTTPS \fBremote_file\fP resource URLs used in the chef\-client run. This is the recommended setting.
+.sp
+If this option is not specified, the setting for \fBssl_verify_mode\fP in the configuration file is applied.
+.TP
.B \fB\-p PORT\fP, \fB\-\-ssh\-port PORT\fP
The SSH port.
.TP
@@ -134,15 +163,9 @@ The SSH password. This can be used to pass the password directly on the command
.B \fB\-\-prerelease\fP
Use to install pre\-release gems.
.TP
-.B \fB\-\-print\-after\fP
-Use to show data after a destructive operation.
-.TP
.B \fB\-r RUN_LIST\fP, \fB\-\-run\-list RUN_LIST\fP
A comma\-separated list of roles and/or recipes to be applied.
.TP
-.B \fB\-s URL\fP, \fB\-\-server\-url URL\fP
-The URL for the Chef server\&.
-.TP
.B \fB\-\-secret SECRET\fP
The encryption key that is used for values contained within a data bag item.
.TP
@@ -152,32 +175,17 @@ The path to the file that contains the encryption key.
.B \fB\-\-sudo\fP
Use to execute a bootstrap operation with sudo\&.
.TP
-.B \fB\-\-template\-file TEMPLATE\fP
-The path to a template file that will be used during a bootstrap operation. Do not use the \fB\-\-distro\fP option when \fB\-\-template\-file\fP is specified.
-.TP
-.B \fB\-u USER\fP, \fB\-\-user USER\fP
-The user name used by knife to sign requests made by the API client to the Chef server\&. Authentication will fail if the user name does not match the private key.
+.B \fB\-t TEMPLATE\fP, \fB\-\-bootstrap\-template TEMPLATE\fP
+Use to specify the bootstrap template to use. This may specify the name of a bootstrap template\-\-\-\fBchef\-full\fP, for example\-\-\-or it may specify the full path to an Embedded Ruby (ERB) template that defines a custom bootstrap. Default value: \fBchef\-full\fP, which installs the chef\-client using the omnibus installer on all supported platforms.
.TP
.B \fB\-\-use\-sudo\-password\fP
Use to perform a bootstrap operation with sudo; specify the password with the \fB\-P\fP (or \fB\-\-ssh\-password\fP) option.
.TP
-.B \fB\-v\fP, \fB\-\-version\fP
-The version of the chef\-client\&.
-.TP
-.B \fB\-V\fP, \fB\-\-verbose\fP
-Set for more verbose outputs. Use \fB\-VV\fP for maximum verbosity.
-.TP
.B \fB\-V \-V\fP
Use to run the initial chef\-client run at the \fBdebug\fP log\-level (e.g. \fBchef\-client \-l debug\fP).
.TP
.B \fB\-x USERNAME\fP, \fB\-\-ssh\-user USERNAME\fP
The SSH user name.
-.TP
-.B \fB\-y\fP, \fB\-\-yes\fP
-Use to respond to all confirmation prompts with "Yes". knife will not ask for confirmation.
-.TP
-.B \fB\-z\fP, \fB\-\-local\-mode\fP
-Use to run the chef\-client in local mode. This allows all commands that work against the Chef server to also work against the local chef\-repo\&.
.UNINDENT
.sp
\fBExamples\fP
diff --git a/distro/common/man/man1/knife-client.1 b/distro/common/man/man1/knife-client.1
index 9606b93687..9dbd174c71 100644
--- a/distro/common/man/man1/knife-client.1
+++ b/distro/common/man/man1/knife-client.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-CLIENT" "1" "Chef 11.16" "" "knife client"
+.TH "KNIFE-CLIENT" "1" "Chef 12.0" "" "knife client"
.SH NAME
knife-client \- The man page for the knife client subcommand.
.
diff --git a/distro/common/man/man1/knife-configure.1 b/distro/common/man/man1/knife-configure.1
index 55ddb910ac..91eb69f1c6 100644
--- a/distro/common/man/man1/knife-configure.1
+++ b/distro/common/man/man1/knife-configure.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-CONFIGURE" "1" "Chef 11.16" "" "knife configure"
+.TH "KNIFE-CONFIGURE" "1" "Chef 12.0" "" "knife configure"
.SH NAME
knife-configure \- The man page for the knife configure subcommand.
.
diff --git a/distro/common/man/man1/knife-cookbook-site.1 b/distro/common/man/man1/knife-cookbook-site.1
index add01304d9..a90a5305f0 100644
--- a/distro/common/man/man1/knife-cookbook-site.1
+++ b/distro/common/man/man1/knife-cookbook-site.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-COOKBOOK-SITE" "1" "Chef 11.16" "" "knife cookbook site"
+.TH "KNIFE-COOKBOOK-SITE" "1" "Chef 12.0" "" "knife cookbook site"
.SH NAME
knife-cookbook-site \- The man page for the knife cookbook site subcommand.
.
@@ -409,6 +409,9 @@ This argument has the following options:
.B \fBCATEGORY\fP
The cookbook category: \fB"Databases"\fP, \fB"Web Servers"\fP, \fB"Process Management"\fP, \fB"Monitoring & Trending"\fP, \fB"Programming Languages"\fP, \fB"Package Management"\fP, \fB"Applications"\fP, \fB"Networking"\fP, \fB"Operating Systems & Virtualization"\fP, \fB"Utilities"\fP, or \fB"Other"\fP\&.
.TP
+.B \fB\-n\fP, \fB\-\-dry\-run\fP
+Use to take no action and only print out results. Default: \fBfalse\fP\&.
+.TP
.B \fB\-o PATH:PATH\fP, \fB\-\-cookbook\-path PATH:PATH\fP
The directory in which cookbooks are created. This can be a colon\-separated path.
.UNINDENT
diff --git a/distro/common/man/man1/knife-cookbook.1 b/distro/common/man/man1/knife-cookbook.1
index b42338c905..ce74c9dd8c 100644
--- a/distro/common/man/man1/knife-cookbook.1
+++ b/distro/common/man/man1/knife-cookbook.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-COOKBOOK" "1" "Chef 11.16" "" "knife cookbook"
+.TH "KNIFE-COOKBOOK" "1" "Chef 12.0" "" "knife cookbook"
.SH NAME
knife-cookbook \- The man page for the knife cookbook subcommand.
.
diff --git a/distro/common/man/man1/knife-data-bag.1 b/distro/common/man/man1/knife-data-bag.1
index 556f56a054..a4d45ce60e 100644
--- a/distro/common/man/man1/knife-data-bag.1
+++ b/distro/common/man/man1/knife-data-bag.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-DATA-BAG" "1" "Chef 11.16" "" "knife data bag"
+.TH "KNIFE-DATA-BAG" "1" "Chef 12.0" "" "knife data bag"
.SH NAME
knife-data-bag \- The man page for the knife data bag subcommand.
.
@@ -119,7 +119,7 @@ This argument has the following options:
The name of a specific item within a data bag.
.TP
.B \fB\-\-secret SECRET\fP
-The encryption key that is used for values contained within a data bag item.
+The encryption key that is used for values contained within a data bag item. If \fBsecret\fP is not specified, the chef\-client will look for a secret at the path specified by the \fBencrypted_data_bag_secret\fP setting in the client.rb file.
.TP
.B \fB\-\-secret\-file FILE\fP
The path to the file that contains the encryption key.
@@ -236,7 +236,7 @@ This argument has the following options:
The name of a specific item within a data bag.
.TP
.B \fB\-\-secret SECRET\fP
-The encryption key that is used for values contained within a data bag item.
+The encryption key that is used for values contained within a data bag item. If \fBsecret\fP is not specified, the chef\-client will look for a secret at the path specified by the \fBencrypted_data_bag_secret\fP setting in the client.rb file.
.TP
.B \fB\-\-secret\-file FILE\fP
The path to the file that contains the encryption key.
@@ -372,7 +372,7 @@ This argument has the following options:
Use to upload all data bags found at the specified path.
.TP
.B \fB\-\-secret SECRET\fP
-The encryption key that is used for values contained within a data bag item.
+The encryption key that is used for values contained within a data bag item. If \fBsecret\fP is not specified, the chef\-client will look for a secret at the path specified by the \fBencrypted_data_bag_secret\fP setting in the client.rb file.
.TP
.B \fB\-\-secret\-file FILE\fP
The path to the file that contains the encryption key.
@@ -475,7 +475,7 @@ This argument has the following options:
The name of a specific item within a data bag.
.TP
.B \fB\-\-secret SECRET\fP
-The encryption key that is used for values contained within a data bag item.
+The encryption key that is used for values contained within a data bag item. If \fBsecret\fP is not specified, the chef\-client will look for a secret at the path specified by the \fBencrypted_data_bag_secret\fP setting in the client.rb file.
.TP
.B \fB\-\-secret\-file FILE\fP
The path to the file that contains the encryption key.
diff --git a/distro/common/man/man1/knife-delete.1 b/distro/common/man/man1/knife-delete.1
index 1b31849596..fcbf52a65a 100644
--- a/distro/common/man/man1/knife-delete.1
+++ b/distro/common/man/man1/knife-delete.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-DELETE" "1" "Chef 11.16" "" "knife delete"
+.TH "KNIFE-DELETE" "1" "Chef 12.0" "" "knife delete"
.SH NAME
knife-delete \- The man page for the knife delete subcommand.
.
diff --git a/distro/common/man/man1/knife-deps.1 b/distro/common/man/man1/knife-deps.1
index 581ea6f0e9..afa384c1a9 100644
--- a/distro/common/man/man1/knife-deps.1
+++ b/distro/common/man/man1/knife-deps.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-DEPS" "1" "Chef 11.16" "" "knife deps"
+.TH "KNIFE-DEPS" "1" "Chef 12.0" "" "knife deps"
.SH NAME
knife-deps \- The man page for the knife deps subcommand.
.
diff --git a/distro/common/man/man1/knife-diff.1 b/distro/common/man/man1/knife-diff.1
index 97938ef13c..8bf19ef609 100644
--- a/distro/common/man/man1/knife-diff.1
+++ b/distro/common/man/man1/knife-diff.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-DIFF" "1" "Chef 11.16" "" "knife diff"
+.TH "KNIFE-DIFF" "1" "Chef 12.0" "" "knife diff"
.SH NAME
knife-diff \- The man page for the knife diff subcommand.
.
diff --git a/distro/common/man/man1/knife-download.1 b/distro/common/man/man1/knife-download.1
index 3b60df12e2..ab232fe613 100644
--- a/distro/common/man/man1/knife-download.1
+++ b/distro/common/man/man1/knife-download.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-DOWNLOAD" "1" "Chef 11.16" "" "knife download"
+.TH "KNIFE-DOWNLOAD" "1" "Chef 12.0" "" "knife download"
.SH NAME
knife-download \- The man page for the knife download subcommand.
.
diff --git a/distro/common/man/man1/knife-edit.1 b/distro/common/man/man1/knife-edit.1
index 344431b082..bc159e6444 100644
--- a/distro/common/man/man1/knife-edit.1
+++ b/distro/common/man/man1/knife-edit.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-EDIT" "1" "Chef 11.16" "" "knife edit"
+.TH "KNIFE-EDIT" "1" "Chef 12.0" "" "knife edit"
.SH NAME
knife-edit \- The man page for the knife edit subcommand.
.
diff --git a/distro/common/man/man1/knife-environment.1 b/distro/common/man/man1/knife-environment.1
index d7aedf35c5..d583abe7fa 100644
--- a/distro/common/man/man1/knife-environment.1
+++ b/distro/common/man/man1/knife-environment.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-ENVIRONMENT" "1" "Chef 11.16" "" "knife environment"
+.TH "KNIFE-ENVIRONMENT" "1" "Chef 12.0" "" "knife environment"
.SH NAME
knife-environment \- The man page for the knife environment subcommand.
.
diff --git a/distro/common/man/man1/knife-exec.1 b/distro/common/man/man1/knife-exec.1
index 7f46263108..b63491185f 100644
--- a/distro/common/man/man1/knife-exec.1
+++ b/distro/common/man/man1/knife-exec.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-EXEC" "1" "Chef 11.16" "" "knife exec"
+.TH "KNIFE-EXEC" "1" "Chef 12.0" "" "knife exec"
.SH NAME
knife-exec \- The man page for the knife exec subcommand.
.
diff --git a/distro/common/man/man1/knife-index-rebuild.1 b/distro/common/man/man1/knife-index-rebuild.1
index d327c4b2e6..3fe2c52f8c 100644
--- a/distro/common/man/man1/knife-index-rebuild.1
+++ b/distro/common/man/man1/knife-index-rebuild.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-INDEX-REBUILD" "1" "Chef 11.16" "" "knife index rebuild"
+.TH "KNIFE-INDEX-REBUILD" "1" "Chef 12.0" "" "knife index rebuild"
.SH NAME
knife-index-rebuild \- The man page for the knife index rebuild subcommand.
.
diff --git a/distro/common/man/man1/knife-list.1 b/distro/common/man/man1/knife-list.1
index 546eacf009..c9349fa822 100644
--- a/distro/common/man/man1/knife-list.1
+++ b/distro/common/man/man1/knife-list.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-LIST" "1" "Chef 11.16" "" "knife list"
+.TH "KNIFE-LIST" "1" "Chef 12.0" "" "knife list"
.SH NAME
knife-list \- The man page for the knife list subcommand.
.
diff --git a/distro/common/man/man1/knife-node.1 b/distro/common/man/man1/knife-node.1
index fb1adffe9d..af7eab9317 100644
--- a/distro/common/man/man1/knife-node.1
+++ b/distro/common/man/man1/knife-node.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-NODE" "1" "Chef 11.16" "" "knife node"
+.TH "KNIFE-NODE" "1" "Chef 12.0" "" "knife node"
.SH NAME
knife-node \- The man page for the knife node subcommand.
.
@@ -557,10 +557,10 @@ This argument has the following options:
The attribute (or attributes) to show.
.TP
.B \fB\-l\fP, \fB\-\-long\fP
-Display long output when searching nodes while using the default summary format.
+Use to display all attributes in the output and to show the output as JSON\&.
.TP
.B \fB\-m\fP, \fB\-\-medium\fP
-Display more, but not all, of a node\(aqs data when searching using the default summary format.
+Use to display normal attributes in the output and to show the output as JSON\&.
.TP
.B \fB\-r\fP, \fB\-\-run\-list\fP
Use to show only the run\-list.
diff --git a/distro/common/man/man1/knife-raw.1 b/distro/common/man/man1/knife-raw.1
index 53cb7abf34..a484db25bb 100644
--- a/distro/common/man/man1/knife-raw.1
+++ b/distro/common/man/man1/knife-raw.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-RAW" "1" "Chef 11.16" "" "knife raw"
+.TH "KNIFE-RAW" "1" "Chef 12.0" "" "knife raw"
.SH NAME
knife-raw \- The man page for the knife raw subcommand.
.
@@ -31,7 +31,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.sp
-The \fBknife raw\fP subcommand is used to send a REST request to a specified path using the Chef server API\&.
+The \fBknife raw\fP subcommand is used to send a REST request to an endpoint in the Chef server API\&.
.sp
\fBSyntax\fP
.sp
diff --git a/distro/common/man/man1/knife-recipe-list.1 b/distro/common/man/man1/knife-recipe-list.1
index cba87be064..3bd5a4c3aa 100644
--- a/distro/common/man/man1/knife-recipe-list.1
+++ b/distro/common/man/man1/knife-recipe-list.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-RECIPE-LIST" "1" "Chef 11.16" "" "knife recipe list"
+.TH "KNIFE-RECIPE-LIST" "1" "Chef 12.0" "" "knife recipe list"
.SH NAME
knife-recipe-list \- The man page for the knife recipe list subcommand.
.
diff --git a/distro/common/man/man1/knife-role.1 b/distro/common/man/man1/knife-role.1
index 5275489dd8..d5b5616d31 100644
--- a/distro/common/man/man1/knife-role.1
+++ b/distro/common/man/man1/knife-role.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-ROLE" "1" "Chef 11.16" "" "knife role"
+.TH "KNIFE-ROLE" "1" "Chef 12.0" "" "knife role"
.SH NAME
knife-role \- The man page for the knife role subcommand.
.
@@ -31,7 +31,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.sp
-A role is a way to define certain patterns and processes that exist across nodes in an organization as belonging to a single job function. Each role consists of zero (or more) attributes and a run list. Each node can have zero (or more) roles assigned to it. When a role is run against a node, the configuration details of that node are compared against the attributes of the role, and then the contents of that role\(aqs run list are applied to the node\(aqs configuration details. When a chef\-client runs, it merges its own attributes and run lists with those contained within each assigned role.
+A role is a way to define certain patterns and processes that exist across nodes in an organization as belonging to a single job function. Each role consists of zero (or more) attributes and a run\-list. Each node can have zero (or more) roles assigned to it. When a role is run against a node, the configuration details of that node are compared against the attributes of the role, and then the contents of that role\(aqs run\-list are applied to the node\(aqs configuration details. When a chef\-client runs, it merges its own attributes and run\-lists with those contained within each assigned role.
.sp
The \fBknife role\fP subcommand is used to manage the roles that are associated with one or more nodes on a Chef server\&.
.SH COMMON OPTIONS
diff --git a/distro/common/man/man1/knife-search.1 b/distro/common/man/man1/knife-search.1
index 5955a12529..3b81898530 100644
--- a/distro/common/man/man1/knife-search.1
+++ b/distro/common/man/man1/knife-search.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-SEARCH" "1" "Chef 11.16" "" "knife search"
+.TH "KNIFE-SEARCH" "1" "Chef 12.0" "" "knife search"
.SH NAME
knife-search \- The man page for the knife search subcommand.
.
@@ -31,7 +31,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.sp
-Search indexes allow queries to be made for any type of data that is indexed by the Chef server, including data bags (and data bag items), environments, nodes, and roles. A defined query syntax is used to support search patterns like exact, wildcard, range, and fuzzy. A search is a full\-text query that can be done from several locations, including from within a recipe, by using the \fBsearch\fP subcommand in knife, or by using the \fB/search\fP or \fB/search/INDEX\fP endpoints in the Chef server API\&. The search engine is based on Apache Solr and is run from the Chef server\&.
+Search indexes allow queries to be made for any type of data that is indexed by the Chef server, including data bags (and data bag items), environments, nodes, and roles. A defined query syntax is used to support search patterns like exact, wildcard, range, and fuzzy. A search is a full\-text query that can be done from several locations, including from within a recipe, by using the \fBsearch\fP subcommand in knife, the \fBsearch\fP method in the Recipe DSL, and by using the \fB/search\fP or \fB/search/INDEX\fP endpoints in the Chef server API\&. The search engine is based on Apache Solr and is run from the Chef server\&.
.sp
The \fBknife search\fP subcommand is used run a search query for information that is indexed on a Chef server\&.
.sp
@@ -168,10 +168,10 @@ The name of the index to be queried: \fBclient\fP, \fBenvironment\fP, \fBnode\fP
The private key that knife will use to sign requests made by the API client to the Chef server\&.
.TP
.B \fB\-l\fP, \fB\-\-long\fP
-Display long output when searching nodes while using the default summary format.
+Use to display all attributes in the output and to show the output as JSON\&.
.TP
.B \fB\-m\fP, \fB\-\-medium\fP
-Display more, but not all, of a node\(aqs data when searching using the default summary format.
+Use to display normal attributes in the output and to show the output as JSON\&.
.TP
.B \fB\-o SORT\fP, \fB\-\-sort SORT\fP
The order in which search results will be sorted.
diff --git a/distro/common/man/man1/knife-serve.1 b/distro/common/man/man1/knife-serve.1
index e56c8dbe9f..8760559f32 100644
--- a/distro/common/man/man1/knife-serve.1
+++ b/distro/common/man/man1/knife-serve.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-SERVE" "1" "Chef 11.16" "" "knife serve"
+.TH "KNIFE-SERVE" "1" "Chef 12.0" "" "knife serve"
.SH NAME
knife-serve \- The man page for the knife serve subcommand.
.
diff --git a/distro/common/man/man1/knife-show.1 b/distro/common/man/man1/knife-show.1
index 2ee107d37b..94f295afb7 100644
--- a/distro/common/man/man1/knife-show.1
+++ b/distro/common/man/man1/knife-show.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-SHOW" "1" "Chef 11.16" "" "knife show"
+.TH "KNIFE-SHOW" "1" "Chef 12.0" "" "knife show"
.SH NAME
knife-show \- The man page for the knife show subcommand.
.
diff --git a/distro/common/man/man1/knife-ssh.1 b/distro/common/man/man1/knife-ssh.1
index 50a4babae3..78555b7293 100644
--- a/distro/common/man/man1/knife-ssh.1
+++ b/distro/common/man/man1/knife-ssh.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-SSH" "1" "Chef 11.16" "" "knife ssh"
+.TH "KNIFE-SSH" "1" "Chef 12.0" "" "knife ssh"
.SH NAME
knife-ssh \- The man page for the knife ssh subcommand.
.
diff --git a/distro/common/man/man1/knife-ssl-check.1 b/distro/common/man/man1/knife-ssl-check.1
index c90f7be05c..23b945468d 100644
--- a/distro/common/man/man1/knife-ssl-check.1
+++ b/distro/common/man/man1/knife-ssl-check.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-SSL-CHECK" "1" "Chef 11.16" "" "knife ssl check"
+.TH "KNIFE-SSL-CHECK" "1" "Chef 12.0" "" "knife ssl check"
.SH NAME
knife-ssl-check \- The man page for the knife ssl check subcommand.
.
diff --git a/distro/common/man/man1/knife-ssl-fetch.1 b/distro/common/man/man1/knife-ssl-fetch.1
index c6f0af2472..88b0ad1ebf 100644
--- a/distro/common/man/man1/knife-ssl-fetch.1
+++ b/distro/common/man/man1/knife-ssl-fetch.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-SSL-FETCH" "1" "Chef 11.16" "" "knife ssl fetch"
+.TH "KNIFE-SSL-FETCH" "1" "Chef 12.0" "" "knife ssl fetch"
.SH NAME
knife-ssl-fetch \- The man page for the knife ssl fetch subcommand.
.
diff --git a/distro/common/man/man1/knife-status.1 b/distro/common/man/man1/knife-status.1
index 52929d5d8c..038cf3a0f0 100644
--- a/distro/common/man/man1/knife-status.1
+++ b/distro/common/man/man1/knife-status.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-STATUS" "1" "Chef 11.16" "" "knife status"
+.TH "KNIFE-STATUS" "1" "Chef 12.0" "" "knife status"
.SH NAME
knife-status \- The man page for the knife status subcommand.
.
diff --git a/distro/common/man/man1/knife-tag.1 b/distro/common/man/man1/knife-tag.1
index d794f1953a..3149f520f1 100644
--- a/distro/common/man/man1/knife-tag.1
+++ b/distro/common/man/man1/knife-tag.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-TAG" "1" "Chef 11.16" "" "knife tag"
+.TH "KNIFE-TAG" "1" "Chef 12.0" "" "knife tag"
.SH NAME
knife-tag \- The man page for the knife tag subcommand.
.
diff --git a/distro/common/man/man1/knife-upload.1 b/distro/common/man/man1/knife-upload.1
index 82bb3e464e..dfc20e0270 100644
--- a/distro/common/man/man1/knife-upload.1
+++ b/distro/common/man/man1/knife-upload.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-UPLOAD" "1" "Chef 11.16" "" "knife upload"
+.TH "KNIFE-UPLOAD" "1" "Chef 12.0" "" "knife upload"
.SH NAME
knife-upload \- The man page for the knife upload subcommand.
.
diff --git a/distro/common/man/man1/knife-user.1 b/distro/common/man/man1/knife-user.1
index 88dd5dae7d..cdd15b9d14 100644
--- a/distro/common/man/man1/knife-user.1
+++ b/distro/common/man/man1/knife-user.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-USER" "1" "Chef 11.16" "" "knife user"
+.TH "KNIFE-USER" "1" "Chef 12.0" "" "knife user"
.SH NAME
knife-user \- The man page for the knife user subcommand.
.
diff --git a/distro/common/man/man1/knife-xargs.1 b/distro/common/man/man1/knife-xargs.1
index ff78b2d068..1fcc3d9f4a 100644
--- a/distro/common/man/man1/knife-xargs.1
+++ b/distro/common/man/man1/knife-xargs.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE-XARGS" "1" "Chef 11.16" "" "knife xargs"
+.TH "KNIFE-XARGS" "1" "Chef 12.0" "" "knife xargs"
.SH NAME
knife-xargs \- The man page for the knife xargs subcommand.
.
diff --git a/distro/common/man/man1/knife.1 b/distro/common/man/man1/knife.1
index f0bc35ba37..9259da8477 100644
--- a/distro/common/man/man1/knife.1
+++ b/distro/common/man/man1/knife.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "KNIFE" "1" "Chef 11.16" "" "knife"
+.TH "KNIFE" "1" "Chef 12.0" "" "knife"
.SH NAME
knife \- The man page for the knife command line tool.
.
diff --git a/distro/common/man/man8/chef-apply.8 b/distro/common/man/man8/chef-apply.8
new file mode 100644
index 0000000000..b12f01e886
--- /dev/null
+++ b/distro/common/man/man8/chef-apply.8
@@ -0,0 +1,86 @@
+.\" Man page generated from reStructuredText.
+.
+.TH "CHEF-APPLY" "8" "Chef 12.0" "" "chef-client"
+.SH NAME
+chef-apply \- The man page for the chef-apply command line tool.
+.
+.nr rst2man-indent-level 0
+.
+.de1 rstReportMargin
+\\$1 \\n[an-margin]
+level \\n[rst2man-indent-level]
+level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
+-
+\\n[rst2man-indent0]
+\\n[rst2man-indent1]
+\\n[rst2man-indent2]
+..
+.de1 INDENT
+.\" .rstReportMargin pre:
+. RS \\$1
+. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
+. nr rst2man-indent-level +1
+.\" .rstReportMargin post:
+..
+.de UNINDENT
+. RE
+.\" indent \\n[an-margin]
+.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.nr rst2man-indent-level -1
+.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
+.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
+..
+.sp
+chef\-apply allows a single recipe to be run from the command line.
+.SH OPTIONS
+.sp
+This command has the following syntax:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+chef\-apply name_of_recipe.rb
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+This tool has the following options:
+.INDENT 0.0
+.TP
+.B \fB\-e RECIPE_TEXT\fP, \fB\-\-execute RECIPE_TEXT\fP
+Use to execute a resource using a string.
+.TP
+.B \fB\-l LEVEL\fP, \fB\-\-log_level LEVEL\fP
+The level of logging that will be stored in a log file.
+.TP
+.B \fB\-s\fP, \fB\-\-stdin\fP
+Use to execute a resource using standard input.
+.TP
+.B \fB\-v\fP, \fB\-\-version\fP
+The version of the chef\-client\&.
+.TP
+.B \fB\-W\fP, \fB\-\-why\-run\fP
+Use to run the executable in why\-run mode, which is a type of chef\-client run that does everything except modify the system. Use why\-run mode to understand why the chef\-client makes the decisions that it makes and to learn more about the current and proposed state of the system.
+.TP
+.B \fB\-h\fP, \fB\-\-help\fP
+Shows help for the command.
+.UNINDENT
+.SH EXAMPLES
+.sp
+To use chef\-apply to run a recipe named \fBmachinations.rb\fP, enter the following:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+$ chef\-apply machinations.rb
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.SH AUTHOR
+Chef
+.\" Generated by docutils manpage writer.
+.
diff --git a/distro/common/man/man8/chef-client.8 b/distro/common/man/man8/chef-client.8
index 6a8de44e27..4c8a1f7b8f 100644
--- a/distro/common/man/man8/chef-client.8
+++ b/distro/common/man/man8/chef-client.8
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "CHEF-CLIENT" "8" "Chef 11.16" "" "chef-client"
+.TH "CHEF-CLIENT" "8" "Chef 12.0" "" "chef-client"
.SH NAME
chef-client \- The man page for the chef-client command line tool.
.
@@ -86,7 +86,7 @@ This command has the following options:
Use to cause a chef\-client run to fail when the chef\-client does not have administrator privileges in Microsoft Windows\&.
.TP
.B \fB\-\-chef\-zero\-port PORT\fP
-The port on which chef\-zero will listen.
+The port on which chef\-zero will listen. If a port is not specified\-\-\-individually, as range of ports, or from the \fBchef_zero.port\fP setting in the client.rb file\-\-\-the chef\-client will scan for ports between 8889\-9999 and will pick the first port that is available.
.TP
.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
The output format: \fBdoc\fP (default) or \fBmin\fP\&.
@@ -110,10 +110,81 @@ The name of the group that owns a process. This is required when starting any ex
Shows help for the command.
.TP
.B \fB\-i SECONDS\fP, \fB\-\-interval SECONDS\fP
-The frequency (in seconds) at which the chef\-client runs. Default value: \fB1800\fP\&.
+The frequency (in seconds) at which the chef\-client runs. When the chef\-client is run at intervals, \fB\-\-splay\fP and \fB\-\-interval\fP values are applied before the chef\-client run. Default value: \fB1800\fP\&.
.TP
.B \fB\-j PATH\fP, \fB\-\-json\-attributes PATH\fP
The path to a file that contains JSON data.
+.sp
+Use this option to define a \fBrun_list\fP object. For example, a JSON file similar to:
+.INDENT 7.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+"run_list": [
+ "recipe[base]",
+ "recipe[foo]",
+ "recipe[bar]",
+ "role[webserver]"
+],
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+may be used by running \fBchef\-client \-j path/to/file.json\fP\&.
+.sp
+In certain situations this option may be used to update \fBnormal\fP attributes.
+.sp
+\fBWARNING:\fP
+.INDENT 7.0
+.INDENT 3.5
+Any other attribute type that is contained in this JSON file will be treated as a \fBnormal\fP attribute. For example, attempting to update \fBoverride\fP attributes using the \fB\-j\fP option:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+{
+ "name": "dev\-99",
+ "description": "Install some stuff",
+ "override_attributes": {
+ "apptastic": {
+ "enable_apptastic": "false",
+ "apptastic_tier_name": "dev\-99.bomb.com"
+ }
+ }
+}
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+will result in a node object similar to:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+{
+ "name": "maybe\-dev\-99",
+ "normal": {
+ "name": "dev\-99",
+ "description": "Install some stuff",
+ "override_attributes": {
+ "apptastic": {
+ "enable_apptastic": "false",
+ "apptastic_tier_name": "dev\-99.bomb.com"
+ }
+ }
+ }
+}
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.UNINDENT
+.UNINDENT
.TP
.B \fB\-k KEY_FILE\fP, \fB\-\-client_key KEY_FILE\fP
The location of the file which contains the client key. Default value: \fB/etc/chef/client.pem\fP\&.
@@ -134,7 +205,7 @@ Use to view colored output. Default setting: \fB\-\-color\fP\&.
The name of the node.
.TP
.B \fB\-o RUN_LIST_ITEM\fP, \fB\-\-override\-runlist RUN_LIST_ITEM\fP
-Replace the current run list with the specified items.
+Replace the current run list with the specified items. This option will not clear the list of cookbooks (and related files) that is cached on the node.
.TP
.B \fB\-\-once\fP
Use to run the chef\-client only once and to cancel \fBinterval\fP and \fBsplay\fP options.
@@ -155,7 +226,7 @@ The path to a recipe. For example, if a recipe file is in the current directory,
The amount of time (in seconds) to wait for a chef\-client run to finish. Default value: not set (indefinite). Set to \fB0\fP to cause a second chef\-client to exit immediately.
.TP
.B \fB\-s SECONDS\fP, \fB\-\-splay SECONDS\fP
-A number (in seconds) to add to the \fBinterval\fP that is used to determine the frequency of chef\-client runs. This number can help prevent server load when there are many clients running at the same time.
+A number (in seconds) to add to the \fBinterval\fP that is used to determine the frequency of chef\-client runs. This number can help prevent server load when there are many clients running at the same time. When the chef\-client is run at intervals, \fB\-\-splay\fP and \fB\-\-interval\fP values are applied before the chef\-client run.
.TP
.B \fB\-S CHEF_SERVER_URL\fP, \fB\-\-server CHEF_SERVER_URL\fP
The URL for the Chef server\&.
diff --git a/distro/common/man/man8/chef-solo.8 b/distro/common/man/man8/chef-solo.8
index 73a49a79cf..d4bbc7507f 100644
--- a/distro/common/man/man8/chef-solo.8
+++ b/distro/common/man/man8/chef-solo.8
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "CHEF-SOLO" "8" "Chef 11.16" "" "chef-solo"
+.TH "CHEF-SOLO" "8" "Chef 12.0" "" "chef-solo"
.SH NAME
chef-solo \- The man page for the chef-solo command line tool.
.
@@ -77,13 +77,15 @@ This command has the following options:
The configuration file to use.
.TP
.B \fB\-d\fP, \fB\-\-daemonize\fP
-Use to run the executable as a daemon. This option is only available on machines that run in UNIX or Linux environments. For machines that are running Microsoft Windows that require similar functionality, use the \fBchef\-client::service\fP recipe in the \fBchef\-client\fP cookbook: \fI\%http://community.opscode.com/cookbooks/chef\-client\fP\&. This will install a chef\-client service under Microsoft Windows using the Windows Service Wrapper\&.
+Use to run the executable as a daemon. This option may not be used in the same command with the \fB\-\-[no\-]fork\fP option.
+.sp
+This option is only available on machines that run in UNIX or Linux environments. For machines that are running Microsoft Windows that require similar functionality, use the \fBchef\-client::service\fP recipe in the \fBchef\-client\fP cookbook: \fI\%http://community.opscode.com/cookbooks/chef\-client\fP\&. This will install a chef\-client service under Microsoft Windows using the Windows Service Wrapper\&.
.TP
.B \fB\-E ENVIRONMENT_NAME\fP, \fB\-\-environment ENVIRONMENT_NAME\fP
The name of the environment.
.TP
.B \fB\-f\fP, \fB\-\-[no\-]fork\fP
-Use to contain the chef\-client run in a secondary process with dedicated RAM. When the chef\-client run is complete the RAM will be returned to the master process. This option helps ensure that a chef\-client will use a steady amount of RAM over time because the master process will not run recipes. This option will also help prevent memory leaks (such as those that can be introduced by the code contained within a poorly designed cookbook). Use \fB\-\-no\-fork\fP to disable running the chef\-client in fork node. Default value: \fB\-\-fork\fP\&.
+Use to contain the chef\-client run in a secondary process with dedicated RAM. When the chef\-client run is complete the RAM will be returned to the master process. This option helps ensure that a chef\-client will use a steady amount of RAM over time because the master process will not run recipes. This option will also help prevent memory leaks (such as those that can be introduced by the code contained within a poorly designed cookbook). Use \fB\-\-no\-fork\fP to disable running the chef\-client in fork node. Default value: \fB\-\-fork\fP\&. This option may not be used in the same command with the \fB\-\-daemonize\fP and \fB\-\-interval\fP options.
.TP
.B \fB\-F FORMAT\fP, \fB\-\-format FORMAT\fP
The output format: \fBdoc\fP (default) or \fBmin\fP\&.
@@ -107,10 +109,81 @@ The name of the group that owns a process. This is required when starting any ex
Shows help for the command.
.TP
.B \fB\-i SECONDS\fP, \fB\-\-interval SECONDS\fP
-The frequency (in seconds) at which the chef\-client runs.
+The frequency (in seconds) at which the chef\-client runs. When the chef\-client is run at intervals, \fB\-\-splay\fP and \fB\-\-interval\fP values are applied before the chef\-client run. This option may not be used in the same command with the \fB\-\-[no\-]fork\fP option.
.TP
.B \fB\-j PATH\fP, \fB\-\-json\-attributes PATH\fP
-The path to a file that contains JSON data. Use this option to override \fBnormal\fP attributes set elsewhere.
+The path to a file that contains JSON data.
+.sp
+Use this option to define a \fBrun_list\fP object. For example, a JSON file similar to:
+.INDENT 7.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+"run_list": [
+ "recipe[base]",
+ "recipe[foo]",
+ "recipe[bar]",
+ "role[webserver]"
+],
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+may be used by running \fBchef\-client \-j path/to/file.json\fP\&.
+.sp
+In certain situations this option may be used to update \fBnormal\fP attributes.
+.sp
+\fBWARNING:\fP
+.INDENT 7.0
+.INDENT 3.5
+Any other attribute type that is contained in this JSON file will be treated as a \fBnormal\fP attribute. For example, attempting to update \fBoverride\fP attributes using the \fB\-j\fP option:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+{
+ "name": "dev\-99",
+ "description": "Install some stuff",
+ "override_attributes": {
+ "apptastic": {
+ "enable_apptastic": "false",
+ "apptastic_tier_name": "dev\-99.bomb.com"
+ }
+ }
+}
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+will result in a node object similar to:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+{
+ "name": "maybe\-dev\-99",
+ "normal": {
+ "name": "dev\-99",
+ "description": "Install some stuff",
+ "override_attributes": {
+ "apptastic": {
+ "enable_apptastic": "false",
+ "apptastic_tier_name": "dev\-99.bomb.com"
+ }
+ }
+ }
+}
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.UNINDENT
+.UNINDENT
.TP
.B \fB\-l LEVEL\fP, \fB\-\-log_level LEVEL\fP
The level of logging that will be stored in a log file.
@@ -134,7 +207,7 @@ The URL location from which a remote cookbook tar.gz will be downloaded.
The amount of time (in seconds) to wait for a chef\-client run to finish. Default value: not set (indefinite). Set to \fB0\fP to cause a second chef\-client to exit immediately.
.TP
.B \fB\-s SECONDS\fP, \fB\-\-splay SECONDS\fP
-A number (in seconds) to add to the \fBinterval\fP that is used to determine the frequency of chef\-client runs. This number can help prevent server load when there are many clients running at the same time.
+A number (in seconds) to add to the \fBinterval\fP that is used to determine the frequency of chef\-client runs. This number can help prevent server load when there are many clients running at the same time. When the chef\-client is run at intervals, \fB\-\-splay\fP and \fB\-\-interval\fP values are applied before the chef\-client run.
.TP
.B \fB\-u USER\fP, \fB\-\-user USER\fP
The user that owns a process. This is required when starting any executable as a daemon.
diff --git a/distro/common/markdown/man1/knife-bootstrap.mkd b/distro/common/markdown/man1/knife-bootstrap.mkd
index 5c5e456023..cb292de311 100644
--- a/distro/common/markdown/man1/knife-bootstrap.mkd
+++ b/distro/common/markdown/man1/knife-bootstrap.mkd
@@ -84,7 +84,7 @@ When this is complete, the bootstrapped node will have:
- Latest Chef version installed from RubyGems or APT Packages from Opscode. This may be a later version than the local system.
- Be validated with the configured Chef Server.
- - Have run Chef with its default run list if one is specfied.
+ - Have run Chef with its default run list if one is specified.
Additional custom bootstrap templates can be created and stored in
`.chef/bootstrap/DISTRO.erb`, replacing __DISTRO__ with the value passed
diff --git a/distro/common/markdown/man1/knife-cookbook-site.mkd b/distro/common/markdown/man1/knife-cookbook-site.mkd
index 7c2b0fe31b..9496cf1765 100644
--- a/distro/common/markdown/man1/knife-cookbook-site.mkd
+++ b/distro/common/markdown/man1/knife-cookbook-site.mkd
@@ -26,7 +26,7 @@ repository. Running `knife cookbook site install` does the following:
upstream;
2. All existing cookbooks are removed from the branch;
3. The cookbook is downloaded from the cookbook site in tarball form;
-4. The downloaded cookbook is untarred, and its contents commited via git;
+4. The downloaded cookbook is untarred, and its contents committed via git;
5. The pristine copy branch is merged into the master branch.
By installing cookbook with this process, you can locally modify the
diff --git a/distro/common/markdown/man1/knife-data-bag.mkd b/distro/common/markdown/man1/knife-data-bag.mkd
index 67ec02158c..53abf95272 100644
--- a/distro/common/markdown/man1/knife-data-bag.mkd
+++ b/distro/common/markdown/man1/knife-data-bag.mkd
@@ -90,7 +90,7 @@ formatted according to the --format option.
## ENCRYPTION SUPPORT
Data Bag Items may be encrypted to keep their contents secret. This may
-be desireable when storing sensitive information such as database
+be desirable when storing sensitive information such as database
passwords, API keys, etc.
Data Bag Item encryption uses the AES-256 CBC symmetric key algorithm.
diff --git a/distro/common/markdown/man1/knife-environment.mkd b/distro/common/markdown/man1/knife-environment.mkd
index 2eebffbce6..98ca4997bd 100644
--- a/distro/common/markdown/man1/knife-environment.mkd
+++ b/distro/common/markdown/man1/knife-environment.mkd
@@ -73,7 +73,7 @@ represented as a single JSON object, like this:
{"apache2": ">= 1.5.0"}
-In the Ruby format, the cookbook version contraints for an environment
+In the Ruby format, the cookbook version constraints for an environment
are represented as a Ruby Hash, like this:
{"apache2" => ">= 1.5.0"}
diff --git a/distro/common/markdown/man1/knife.mkd b/distro/common/markdown/man1/knife.mkd
index 61e0c7f8b9..c3add163f9 100644
--- a/distro/common/markdown/man1/knife.mkd
+++ b/distro/common/markdown/man1/knife.mkd
@@ -174,7 +174,7 @@ recommended though, and git fits with a lot of the workflow paradigms.
## ENVIRONMENT
* `EDITOR`:
The text editor to use for editing data. The --editor option takes
- precedence over this value, and the --disable-editing option supresses
+ precedence over this value, and the --disable-editing option suppresses
data editing entirely.
## SEE ALSO
diff --git a/kitchen-tests/.chef/client.rb b/kitchen-tests/.chef/client.rb
index 5eb200a939..be46e2e8d7 100644
--- a/kitchen-tests/.chef/client.rb
+++ b/kitchen-tests/.chef/client.rb
@@ -1,7 +1,10 @@
-chef_dir = File.expand_path(File.dirame(__FILE__))
-repo_dir = File.expand_path(Fild.join(chef_dir, '..'))
+chef_dir = File.expand_path(File.dirname(__FILE__))
+repo_dir = File.expand_path(File.join(chef_dir, '..'))
-log_level :info
+log_level :info
chef_repo_path repo_dir
-local_mode true
+local_mode true
+cache_path "#{ENV['HOME']}/.cache/chef"
+
+audit_mode :enabled \ No newline at end of file
diff --git a/kitchen-tests/.kitchen.travis.yml b/kitchen-tests/.kitchen.travis.yml
index fa44c210ba..15795e033a 100644
--- a/kitchen-tests/.kitchen.travis.yml
+++ b/kitchen-tests/.kitchen.travis.yml
@@ -6,18 +6,28 @@ driver_config:
iam_profile_name: <%= ENV['IAM_PROFILE_NAME'] %>
provisioner:
- name: chef_solo
+ name: chef_zero
github: <%= ENV['TRAVIS_REPO_SLUG'] %>
branch: <%= ENV['TRAVIS_COMMIT'] %>
require_chef_omnibus: 12.0.0-rc.2
data_path: test/fixtures
+# disable file provider diffs so we don't overflow travis' line limit
+ client_rb:
+ diff_disabled: true
platforms:
- name: ubuntu-12.04
driver_plugin: ec2
driver_config:
region: "us-west-2"
- availability_zone: "us-west-2b"
+ availability_zone: "us-west-2a"
+ ssh_key: <%= ENV['EC2_SSH_KEY_PATH'] %>
+ security_group_ids: ["travis-ci"]
+ - name: centos-6.4
+ driver_plugin: ec2
+ driver_config:
+ region: "us-west-2"
+ availability_zone: "us-west-2a"
ssh_key: <%= ENV['EC2_SSH_KEY_PATH'] %>
security_group_ids: ["travis-ci"]
diff --git a/kitchen-tests/.kitchen.yml b/kitchen-tests/.kitchen.yml
index 651a606502..775bb59378 100644
--- a/kitchen-tests/.kitchen.yml
+++ b/kitchen-tests/.kitchen.yml
@@ -1,14 +1,34 @@
---
+driver:
+ name: vagrant
+ customize:
+ cpus: 4
+ memory: 2048
+
provisioner:
- name: chef_solo
+ name: chef_zero
github: "opscode/chef"
branch: <%= %x(git rev-parse HEAD) %>
require_chef_omnibus: true
data_path: test/fixtures
+ client_rb:
+ diff_disabled: true
platforms:
+ # upstream community mysql cookbook broken on 10.04
+ #- name: ubuntu-10.04
+ # run_list: apt::default
- name: ubuntu-12.04
- driver_plugin: vagrant
+ run_list: apt::default
+ - name: ubuntu-14.04
+ run_list: apt::default
+ # upstream community mysql cookbook also broken on 14.10
+ #- name: ubuntu-14.10
+ # run_list: apt::default
+ - name: centos-6.4
+ run_list: yum-epel::default
+ - name: centos-5.10
+ run_list: yum-epel::default
suites:
- name: webapp
diff --git a/kitchen-tests/cookbooks/audit_test/.gitignore b/kitchen-tests/cookbooks/audit_test/.gitignore
new file mode 100644
index 0000000000..ec2a890bd3
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/.gitignore
@@ -0,0 +1,16 @@
+.vagrant
+Berksfile.lock
+*~
+*#
+.#*
+\#*#
+.*.sw[a-z]
+*.un~
+
+# Bundler
+Gemfile.lock
+bin/*
+.bundle/*
+
+.kitchen/
+.kitchen.local.yml
diff --git a/kitchen-tests/cookbooks/audit_test/.kitchen.yml b/kitchen-tests/cookbooks/audit_test/.kitchen.yml
new file mode 100644
index 0000000000..be11e33081
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/.kitchen.yml
@@ -0,0 +1,16 @@
+---
+driver:
+ name: vagrant
+
+provisioner:
+ name: chef_zero
+
+platforms:
+ - name: ubuntu-12.04
+ - name: centos-6.5
+
+suites:
+ - name: default
+ run_list:
+ - recipe[audit_test::default]
+ attributes:
diff --git a/kitchen-tests/cookbooks/audit_test/Berksfile b/kitchen-tests/cookbooks/audit_test/Berksfile
new file mode 100644
index 0000000000..0ac9b78cf7
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/Berksfile
@@ -0,0 +1,3 @@
+source "https://supermarket.getchef.com"
+
+metadata
diff --git a/kitchen-tests/cookbooks/audit_test/README.md b/kitchen-tests/cookbooks/audit_test/README.md
new file mode 100644
index 0000000000..75e2f44808
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/README.md
@@ -0,0 +1,12 @@
+# audit_test
+
+This cookbook has some basic recipes to test audit mode.
+
+In order to run these tests on your dev box:
+
+```
+$ bundle install
+$ bundle exec chef-client -c kitchen-tests/.chef/client.rb -z -o audit_test::default -l debug
+```
+
+Expected JSON output for the tests will be printed to `debug` log.
diff --git a/kitchen-tests/cookbooks/audit_test/chefignore b/kitchen-tests/cookbooks/audit_test/chefignore
new file mode 100644
index 0000000000..80dc2d20ef
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/chefignore
@@ -0,0 +1,95 @@
+# Put files/directories that should be ignored in this file when uploading
+# or sharing to the community site.
+# Lines that start with '# ' are comments.
+
+# OS generated files #
+######################
+.DS_Store
+Icon?
+nohup.out
+ehthumbs.db
+Thumbs.db
+
+# SASS #
+########
+.sass-cache
+
+# EDITORS #
+###########
+\#*
+.#*
+*~
+*.sw[a-z]
+*.bak
+REVISION
+TAGS*
+tmtags
+*_flymake.*
+*_flymake
+*.tmproj
+.project
+.settings
+mkmf.log
+
+## COMPILED ##
+##############
+a.out
+*.o
+*.pyc
+*.so
+*.com
+*.class
+*.dll
+*.exe
+*/rdoc/
+
+# Testing #
+###########
+.watchr
+.rspec
+spec/*
+spec/fixtures/*
+test/*
+features/*
+Guardfile
+Procfile
+
+# SCM #
+#######
+.git
+*/.git
+.gitignore
+.gitmodules
+.gitconfig
+.gitattributes
+.svn
+*/.bzr/*
+*/.hg/*
+*/.svn/*
+
+# Berkshelf #
+#############
+Berksfile
+Berksfile.lock
+cookbooks/*
+tmp
+
+# Cookbooks #
+#############
+CONTRIBUTING
+
+# Strainer #
+############
+Colanderfile
+Strainerfile
+.colander
+.strainer
+
+# Vagrant #
+###########
+.vagrant
+Vagrantfile
+
+# Travis #
+##########
+.travis.yml
diff --git a/kitchen-tests/cookbooks/audit_test/metadata.rb b/kitchen-tests/cookbooks/audit_test/metadata.rb
new file mode 100644
index 0000000000..4a60104e92
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/metadata.rb
@@ -0,0 +1,8 @@
+name 'audit_test'
+maintainer 'The Authors'
+maintainer_email 'you@example.com'
+license 'all_rights'
+description 'Installs/Configures audit_test'
+long_description 'Installs/Configures audit_test'
+version '0.1.0'
+
diff --git a/kitchen-tests/cookbooks/audit_test/recipes/default.rb b/kitchen-tests/cookbooks/audit_test/recipes/default.rb
new file mode 100644
index 0000000000..833c12064a
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/recipes/default.rb
@@ -0,0 +1,26 @@
+#
+# Cookbook Name:: audit_test
+# Recipe:: default
+#
+# Copyright (c) 2014 The Authors, All Rights Reserved.
+
+control_group "basic control group" do
+ control "basic math" do
+ it "should pass" do
+ expect(2 - 2).to eq(0)
+ end
+ end
+end
+
+control_group "control group without top level control" do
+ it "should pass" do
+ expect(2 - 2).to eq(0)
+ end
+end
+
+control_group "control group with empty control" do
+ control "empty"
+end
+
+control_group "empty control group with block" do
+end
diff --git a/kitchen-tests/cookbooks/audit_test/recipes/error_duplicate_control_groups.rb b/kitchen-tests/cookbooks/audit_test/recipes/error_duplicate_control_groups.rb
new file mode 100644
index 0000000000..82b358d4be
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/recipes/error_duplicate_control_groups.rb
@@ -0,0 +1,17 @@
+#
+# Cookbook Name:: audit_test
+# Recipe:: error_duplicate_control_groups
+#
+# Copyright (c) 2014 The Authors, All Rights Reserved.
+
+control_group "basic control group" do
+ it "should pass" do
+ expect(2 - 2).to eq(0)
+ end
+end
+
+control_group "basic control group" do
+ it "should pass" do
+ expect(2 - 2).to eq(0)
+ end
+end
diff --git a/kitchen-tests/cookbooks/audit_test/recipes/error_no_block.rb b/kitchen-tests/cookbooks/audit_test/recipes/error_no_block.rb
new file mode 100644
index 0000000000..42da81aa4f
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/recipes/error_no_block.rb
@@ -0,0 +1,7 @@
+#
+# Cookbook Name:: audit_test
+# Recipe:: error_no_block
+#
+# Copyright (c) 2014 The Authors, All Rights Reserved.
+
+control_group "empty control group without block"
diff --git a/kitchen-tests/cookbooks/audit_test/recipes/error_orphan_control.rb b/kitchen-tests/cookbooks/audit_test/recipes/error_orphan_control.rb
new file mode 100644
index 0000000000..4f2a8e6c55
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/recipes/error_orphan_control.rb
@@ -0,0 +1,13 @@
+#
+# Cookbook Name:: audit_test
+# Recipe:: error_orphan_control
+#
+# Copyright (c) 2014 The Authors, All Rights Reserved.
+
+control_group "basic control group" do
+ it "should pass" do
+ expect(2 - 2).to eq(0)
+ end
+end
+
+control "orphan control"
diff --git a/kitchen-tests/cookbooks/audit_test/recipes/failed_specs.rb b/kitchen-tests/cookbooks/audit_test/recipes/failed_specs.rb
new file mode 100644
index 0000000000..c5c2c32f0a
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/recipes/failed_specs.rb
@@ -0,0 +1,14 @@
+#
+# Cookbook Name:: audit_test
+# Recipe:: failed_specs
+#
+# Copyright (c) 2014 The Authors, All Rights Reserved.
+
+control_group "basic control group" do
+ control "basic math" do
+ # Can not write a good control :(
+ it "should pass" do
+ expect(2 - 0).to eq(0)
+ end
+ end
+end
diff --git a/kitchen-tests/cookbooks/audit_test/recipes/serverspec_collision.rb b/kitchen-tests/cookbooks/audit_test/recipes/serverspec_collision.rb
new file mode 100644
index 0000000000..c433bd1a90
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/recipes/serverspec_collision.rb
@@ -0,0 +1,31 @@
+#
+# Cookbook Name:: audit_test
+# Recipe:: serverspec_collision
+#
+# Copyright (c) 2014 The Authors, All Rights Reserved.
+
+file "/tmp/audit_test_file" do
+ action :create
+ content "Welcome to audit mode."
+end
+
+control_group "file auditing" do
+ describe "test file" do
+ it "says welcome" do
+ expect(file("/tmp/audit_test_file")).to contain("Welcome")
+ end
+ end
+end
+
+file "/tmp/audit_test_file_2" do
+ action :create
+ content "Bye to audit mode."
+end
+
+control_group "end file auditing" do
+ describe "end file" do
+ it "says bye" do
+ expect(file("/tmp/audit_test_file_2")).to contain("Bye")
+ end
+ end
+end
diff --git a/kitchen-tests/cookbooks/audit_test/recipes/serverspec_support.rb b/kitchen-tests/cookbooks/audit_test/recipes/serverspec_support.rb
new file mode 100644
index 0000000000..8b3c35a6bd
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/recipes/serverspec_support.rb
@@ -0,0 +1,37 @@
+#
+# Cookbook Name:: audit_test
+# Recipe:: serverspec_support
+#
+# Copyright (c) 2014 The Authors, All Rights Reserved.
+
+file "/tmp/audit_test_file" do
+ action :create
+ content "Welcome to audit mode."
+end
+
+# package "curl" do
+# action :install
+# end
+
+control_group "serverspec helpers with types" do
+ control "file helper" do
+ it "says welcome" do
+ expect(file("/tmp/audit_test_file")).to contain("Welcome")
+ end
+ end
+
+ control service("com.apple.CoreRAID") do
+ it { is_expected.to be_enabled }
+ it { is_expected.not_to be_running }
+ end
+
+ # describe "package helper" do
+ # it "works" do
+ # expect(package("curl")).to be_installed
+ # end
+ # end
+
+ control package("postgresql") do
+ it { is_expected.to_not be_installed }
+ end
+end
diff --git a/kitchen-tests/cookbooks/audit_test/recipes/with_include_recipe.rb b/kitchen-tests/cookbooks/audit_test/recipes/with_include_recipe.rb
new file mode 100644
index 0000000000..f795f7786a
--- /dev/null
+++ b/kitchen-tests/cookbooks/audit_test/recipes/with_include_recipe.rb
@@ -0,0 +1,16 @@
+#
+# Cookbook Name:: audit_test
+# Recipe:: with_include_recipe
+#
+# Copyright (c) 2014 The Authors, All Rights Reserved.
+
+include_recipe "audit_test::serverspec_collision"
+
+control_group "basic example" do
+ it "should pass" do
+ expect(2 - 2).to eq(0)
+ end
+end
+
+include_recipe "audit_test::serverspec_collision"
+include_recipe "audit_test::default"
diff --git a/kitchen-tests/cookbooks/webapp/README.md b/kitchen-tests/cookbooks/webapp/README.md
index e8de6ee467..f19ab46735 100644
--- a/kitchen-tests/cookbooks/webapp/README.md
+++ b/kitchen-tests/cookbooks/webapp/README.md
@@ -1,4 +1,3 @@
# webapp
TODO: Enter the cookbook description here.
-
diff --git a/kitchen-tests/cookbooks/webapp/attributes/default.rb b/kitchen-tests/cookbooks/webapp/attributes/default.rb
index efe06b6549..fb33efa49e 100644
--- a/kitchen-tests/cookbooks/webapp/attributes/default.rb
+++ b/kitchen-tests/cookbooks/webapp/attributes/default.rb
@@ -1,7 +1,14 @@
default['apache']['remote_host_ip'] = '127.0.0.1'
-default['mysql']['version'] = "5.5"
-
default['webapp']['database'] = 'webapp'
default['webapp']['db_username'] = 'webapp'
-default['webapp']['path'] = '/var/www/'
+default['webapp']['path'] = '/srv/webapp'
+
+# XXX: apache2 cookbook 2.0.0 has bugs around changing the mpm and then attempting a graceful restart
+# which fails and leaves the service down.
+case node['platform']
+when "ubuntu"
+ if node['platform_version'].to_f >= 14.04
+ default[:apache][:mpm] = 'event'
+ end
+end
diff --git a/kitchen-tests/cookbooks/webapp/recipes/default.rb b/kitchen-tests/cookbooks/webapp/recipes/default.rb
index 82479e5137..839b0ad8d8 100644
--- a/kitchen-tests/cookbooks/webapp/recipes/default.rb
+++ b/kitchen-tests/cookbooks/webapp/recipes/default.rb
@@ -14,8 +14,11 @@ creds = Hash.new
creds[item_name] = data_bag_item('passwords', item_name)
end
-apache_site "default" do
- enable true
+web_app "webapp" do
+ server_name 'localhost'
+ server_aliases [node['fqdn'], node['hostname'], 'localhost.localdomain']
+ docroot node['webapp']['path']
+ cookbook 'apache2'
end
mysql_service "default" do
diff --git a/kitchen-tests/test/fixtures/platforms/centos/5.json b/kitchen-tests/test/fixtures/platforms/centos/5.json
new file mode 100644
index 0000000000..9d324a2f03
--- /dev/null
+++ b/kitchen-tests/test/fixtures/platforms/centos/5.json
@@ -0,0 +1,14 @@
+{
+ "apache": {
+ "package": "httpd",
+ "service_name": "httpd"
+ },
+ "mysql": {
+ "server_package": "mysql-server",
+ "client_package": "mysql",
+ "service_name": "mysqld"
+ },
+ "php" : {
+ "package": "php53"
+ }
+}
diff --git a/kitchen-tests/test/fixtures/platforms/centos/6.json b/kitchen-tests/test/fixtures/platforms/centos/6.json
new file mode 100644
index 0000000000..4f74a3ed4a
--- /dev/null
+++ b/kitchen-tests/test/fixtures/platforms/centos/6.json
@@ -0,0 +1,14 @@
+{
+ "apache": {
+ "package": "httpd",
+ "service_name": "httpd"
+ },
+ "mysql": {
+ "server_package": "mysql-server",
+ "client_package": "mysql",
+ "service_name": "mysqld"
+ },
+ "php" : {
+ "package": "php"
+ }
+}
diff --git a/kitchen-tests/test/fixtures/platforms/ubuntu/10.04.json b/kitchen-tests/test/fixtures/platforms/ubuntu/10.04.json
new file mode 100644
index 0000000000..a9677c7ca5
--- /dev/null
+++ b/kitchen-tests/test/fixtures/platforms/ubuntu/10.04.json
@@ -0,0 +1,14 @@
+{
+ "apache": {
+ "package": "apache2",
+ "service_name": "apache2"
+ },
+ "mysql": {
+ "server_package": "mysql-server-5.1",
+ "client_package": "mysql-client-5.1",
+ "service_name": "mysql"
+ },
+ "php" : {
+ "package": "php5"
+ }
+}
diff --git a/kitchen-tests/test/fixtures/platforms/ubuntu/12.04.json b/kitchen-tests/test/fixtures/platforms/ubuntu/12.04.json
index 5e436a3cb0..eab46db2e5 100644
--- a/kitchen-tests/test/fixtures/platforms/ubuntu/12.04.json
+++ b/kitchen-tests/test/fixtures/platforms/ubuntu/12.04.json
@@ -1,42 +1,14 @@
{
- "apache": {
- "package": "apache2",
- "binary": "/usr/sbin/apache2",
- "dir": "/etc/apache2",
- "lib_dir": "/usr/lib/apache2",
- "libexec_dir": "/usr/lib/apache2/modules",
- "cache_dir": "/var/cache/apache2",
- "cgibin_dir": "/usr/lib/cgi-bin",
- "docroot_dir": "/var/www",
- "conf": "/etc/apache2/apache2.conf",
- "perl_pkg": "perl",
- "log_dir": "/var/log/apache2",
- "root_group": "root",
- "service_name": "apache2",
- "service_restart_command": "/usr/sbin/invoke-rc.d apache2 restart && sleep 1",
- "service_reload_command": "/usr/sbin/invoke-rc.d apache2 reload && sleep 1",
- "default_site_name": "000-default",
- "default_site_enabled": false,
- "default_modules": [
- "status",
- "alias",
- "auth_basic",
- "authn_file",
- "authz_core",
- "authz_groupfile",
- "authz_host",
- "authz_user",
- "autoindex",
- "dir",
- "env",
- "mime",
- "negotiation",
- "setenvif"
- ]
- },
- "mysql": {
- "server": {
- "version": "5.5"
- }
- }
+ "apache": {
+ "package": "apache2",
+ "service_name": "apache2"
+ },
+ "mysql": {
+ "server_package": "mysql-server-5.5",
+ "client_package": "mysql-client-5.5",
+ "service_name": "mysql"
+ },
+ "php" : {
+ "package": "php5"
+ }
}
diff --git a/kitchen-tests/test/fixtures/platforms/ubuntu/14.04.json b/kitchen-tests/test/fixtures/platforms/ubuntu/14.04.json
new file mode 100644
index 0000000000..eab46db2e5
--- /dev/null
+++ b/kitchen-tests/test/fixtures/platforms/ubuntu/14.04.json
@@ -0,0 +1,14 @@
+{
+ "apache": {
+ "package": "apache2",
+ "service_name": "apache2"
+ },
+ "mysql": {
+ "server_package": "mysql-server-5.5",
+ "client_package": "mysql-client-5.5",
+ "service_name": "mysql"
+ },
+ "php" : {
+ "package": "php5"
+ }
+}
diff --git a/kitchen-tests/test/fixtures/platforms/ubuntu/14.10.json b/kitchen-tests/test/fixtures/platforms/ubuntu/14.10.json
new file mode 100644
index 0000000000..eab46db2e5
--- /dev/null
+++ b/kitchen-tests/test/fixtures/platforms/ubuntu/14.10.json
@@ -0,0 +1,14 @@
+{
+ "apache": {
+ "package": "apache2",
+ "service_name": "apache2"
+ },
+ "mysql": {
+ "server_package": "mysql-server-5.5",
+ "client_package": "mysql-client-5.5",
+ "service_name": "mysql"
+ },
+ "php" : {
+ "package": "php5"
+ }
+}
diff --git a/kitchen-tests/test/fixtures/serverspec_helper.rb b/kitchen-tests/test/fixtures/serverspec_helper.rb
index 48963dc45d..ad1f866775 100644
--- a/kitchen-tests/test/fixtures/serverspec_helper.rb
+++ b/kitchen-tests/test/fixtures/serverspec_helper.rb
@@ -1,4 +1,4 @@
-# Shamelessly copied from opscode/onehealth-cookbooks/apache2/test/fixtures/serverspec_helper.rb
+# Shamelessly copied from https://github.com/onehealth-cookbooks/apache2/blob/master/test/fixtures/serverspec_helper.rb
# The commented-out platforms in the osmapping hash can be added once we have added them into
# our .kitchen.yml and .kitchen.travis.yml and added the appropriate JSON under test/fixtures/platforms.
diff --git a/kitchen-tests/test/integration/webapp/serverspec/localhost/default_spec.rb b/kitchen-tests/test/integration/webapp/serverspec/localhost/default_spec.rb
index 05da3ff337..64c9121a6f 100644
--- a/kitchen-tests/test/integration/webapp/serverspec/localhost/default_spec.rb
+++ b/kitchen-tests/test/integration/webapp/serverspec/localhost/default_spec.rb
@@ -19,21 +19,21 @@ describe "webapp::default", :end_to_end => true do
end
end
- describe "mysql-server-#{property[:mysql][:server][:version]} package" do
+ describe "#{property[:mysql][:server_package]} package" do
include_examples "a package" do
- let(:package_name) { "mysql-server-#{property[:mysql][:server][:version]}" }
+ let(:package_name) { property[:mysql][:server_package] }
end
end
- describe "mysql-client-5.5 package" do
+ describe "#{property[:mysql][:client_package]} package" do
include_examples "a package" do
- let(:package_name) { "mysql-client-5.5" }
+ let(:package_name) { property[:mysql][:client_package] }
end
end
describe "php package" do
include_examples "a package" do
- let(:package_name) { "php5" }
+ let(:package_name) { property[:php][:package] }
end
end
end
@@ -57,7 +57,7 @@ describe "webapp::default", :end_to_end => true do
describe "mysql service" do
include_examples "a service" do
- let(:service_name) { "mysql" }
+ let(:service_name) { property[:mysql][:service_name] }
end
end
diff --git a/lib/chef.rb b/lib/chef.rb
index 0d5fb3de2c..7f54b91f14 100644
--- a/lib/chef.rb
+++ b/lib/chef.rb
@@ -32,10 +32,3 @@ require 'chef/run_status'
require 'chef/handler'
require 'chef/handler/json_file'
-require 'chef/monkey_patches/tempfile'
-require 'chef/monkey_patches/string'
-require 'chef/monkey_patches/numeric'
-require 'chef/monkey_patches/object'
-require 'chef/monkey_patches/file'
-require 'chef/monkey_patches/uri'
-
diff --git a/lib/chef/api_client.rb b/lib/chef/api_client.rb
index 334fb23f38..ce9ceb312c 100644
--- a/lib/chef/api_client.rb
+++ b/lib/chef/api_client.rb
@@ -96,7 +96,7 @@ class Chef
set_or_return(
:private_key,
arg,
- :kind_of => String
+ :kind_of => [String, FalseClass]
)
end
@@ -124,7 +124,7 @@ class Chef
Chef::JSONCompat.to_json(to_hash, *a)
end
- def self.json_create(o)
+ def self.from_hash(o)
client = Chef::ApiClient.new
client.name(o["name"] || o["clientname"])
client.private_key(o["private_key"]) if o.key?("private_key")
@@ -134,6 +134,14 @@ class Chef
client
end
+ def self.json_create(data)
+ from_hash(data)
+ end
+
+ def self.from_json(j)
+ from_hash(Chef::JSONCompat.parse(j))
+ end
+
def self.http_api
Chef::REST.new(Chef::Config[:chef_server_url])
end
diff --git a/lib/chef/api_client/registration.rb b/lib/chef/api_client/registration.rb
index 8a5885eff3..de5fc7ac3d 100644
--- a/lib/chef/api_client/registration.rb
+++ b/lib/chef/api_client/registration.rb
@@ -33,9 +33,10 @@ class Chef
attr_reader :destination
attr_reader :name
- def initialize(name, destination)
- @name = name
- @destination = destination
+ def initialize(name, destination, http_api: nil)
+ @name = name
+ @destination = destination
+ @http_api = http_api
@server_generated_private_key = nil
end
@@ -120,11 +121,10 @@ class Chef
post_data
end
-
def http_api
- @http_api_as_validator ||= Chef::REST.new(Chef::Config[:chef_server_url],
- Chef::Config[:validation_client_name],
- Chef::Config[:validation_key])
+ @http_api ||= Chef::REST.new(Chef::Config[:chef_server_url],
+ Chef::Config[:validation_client_name],
+ Chef::Config[:validation_key])
end
# Whether or not to generate keys locally and post the public key to the
@@ -161,5 +161,3 @@ class Chef
end
end
end
-
-
diff --git a/lib/chef/application.rb b/lib/chef/application.rb
index a2718e7556..297e46ef3c 100644
--- a/lib/chef/application.rb
+++ b/lib/chef/application.rb
@@ -17,6 +17,7 @@
# limitations under the License.
require 'pp'
+require 'uri'
require 'socket'
require 'chef/config'
require 'chef/config_fetcher'
@@ -48,6 +49,7 @@ class Chef
configure_logging
configure_proxy_environment_variables
configure_encoding
+ emit_warnings
end
# Get this party started
@@ -102,6 +104,12 @@ class Chef
Chef::Config.merge!(config)
end
+ def set_specific_recipes
+ Chef::Config[:specific_recipes] =
+ cli_arguments.map { |file| File.expand_path(file) } if
+ cli_arguments.respond_to?(:map)
+ end
+
# Initialize and configure the logger.
# === Loggers and Formatters
# In Chef 10.x and previous, the Logger was the primary/only way that Chef
@@ -198,16 +206,18 @@ class Chef
# Initializes Chef::Client instance and runs it
def run_chef_client(specific_recipes = [])
+ unless specific_recipes.respond_to?(:size)
+ raise ArgumentError, 'received non-Array like specific_recipes argument'
+ end
+
Chef::LocalMode.with_server_connectivity do
override_runlist = config[:override_runlist]
- if specific_recipes.size > 0
- override_runlist ||= []
- end
+ override_runlist ||= [] if specific_recipes.size > 0
@chef_client = Chef::Client.new(
@chef_client_json,
- :override_runlist => config[:override_runlist],
- :specific_recipes => specific_recipes,
- :runlist => config[:runlist]
+ override_runlist: override_runlist,
+ specific_recipes: specific_recipes,
+ runlist: config[:runlist]
)
@chef_client_json = nil
@@ -226,7 +236,7 @@ class Chef
private
def can_fork?
# win32-process gem exposes some form of :fork for Process
- # class. So we are seperately ensuring that the platform we're
+ # class. So we are separately ensuring that the platform we're
# running on is not windows before forking.
Chef::Config[:client_fork] && Process.respond_to?(:fork) && !Chef::Platform.windows?
end
@@ -237,7 +247,7 @@ class Chef
# Override the TERM signal.
trap('TERM') do
Chef::Log.debug("SIGTERM received during converge," +
- " finishing converge to exit normally (send SIGINT to terminate immediately)")
+ " finishing converge to exit normally (send SIGINT to terminate immediately)")
end
@chef_client.run
@@ -251,7 +261,7 @@ class Chef
# TERM singal is received (exit gracefully)
trap('TERM') do
Chef::Log.debug("SIGTERM received during converge," +
- " finishing converge to exit normally (send SIGINT to terminate immediately)")
+ " finishing converge to exit normally (send SIGINT to terminate immediately)")
end
client_solo = Chef::Config[:solo] ? "chef-solo" : "chef-client"
@@ -297,7 +307,7 @@ class Chef
def configure_http_proxy
if http_proxy = Chef::Config[:http_proxy]
http_proxy_string = configure_proxy("http", http_proxy,
- Chef::Config[:http_proxy_user], Chef::Config[:http_proxy_pass])
+ Chef::Config[:http_proxy_user], Chef::Config[:http_proxy_pass])
env['http_proxy'] = http_proxy_string unless env['http_proxy']
env['HTTP_PROXY'] = http_proxy_string unless env['HTTP_PROXY']
end
@@ -307,7 +317,7 @@ class Chef
def configure_https_proxy
if https_proxy = Chef::Config[:https_proxy]
https_proxy_string = configure_proxy("https", https_proxy,
- Chef::Config[:https_proxy_user], Chef::Config[:https_proxy_pass])
+ Chef::Config[:https_proxy_user], Chef::Config[:https_proxy_pass])
env['https_proxy'] = https_proxy_string unless env['https_proxy']
env['HTTPS_PROXY'] = https_proxy_string unless env['HTTPS_PROXY']
end
@@ -317,7 +327,7 @@ class Chef
def configure_ftp_proxy
if ftp_proxy = Chef::Config[:ftp_proxy]
ftp_proxy_string = configure_proxy("ftp", ftp_proxy,
- Chef::Config[:ftp_proxy_user], Chef::Config[:ftp_proxy_pass])
+ Chef::Config[:ftp_proxy_user], Chef::Config[:ftp_proxy_pass])
env['ftp_proxy'] = ftp_proxy_string unless env['ftp_proxy']
env['FTP_PROXY'] = ftp_proxy_string unless env['FTP_PROXY']
end
@@ -371,6 +381,12 @@ class Chef
ENV
end
+ def emit_warnings
+ if Chef::Config[:chef_gem_compile_time]
+ Chef::Log.deprecation "setting chef_gem_compile_time to true is deprecated"
+ end
+ end
+
class << self
def debug_stacktrace(e)
message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
diff --git a/lib/chef/application/agent.rb b/lib/chef/application/agent.rb
deleted file mode 100644
index 66b0c25cbf..0000000000
--- a/lib/chef/application/agent.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Author:: AJ Christensen (<aj@opscode.comz>)
-# Copyright:: Copyright (c) 2008 Opscode, 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/application'
diff --git a/lib/chef/application/apply.rb b/lib/chef/application/apply.rb
index 22d835e876..42805001d8 100644
--- a/lib/chef/application/apply.rb
+++ b/lib/chef/application/apply.rb
@@ -43,6 +43,12 @@ class Chef::Application::Apply < Chef::Application
:description => "Execute resources read from STDIN",
:boolean => true
+ option :json_attribs,
+ :short => "-j JSON_ATTRIBS",
+ :long => "--json-attributes JSON_ATTRIBS",
+ :description => "Load attributes from a JSON file or URL",
+ :proc => nil
+
option :log_level,
:short => "-l LEVEL",
:long => "--log_level LEVEL",
@@ -79,6 +85,8 @@ class Chef::Application::Apply < Chef::Application
:default => !Chef::Platform.windows?,
:description => "Use colored output, defaults to enabled"
+ attr_reader :json_attribs
+
def initialize
super
end
@@ -88,6 +96,14 @@ class Chef::Application::Apply < Chef::Application
Chef::Config.merge!(config)
configure_logging
configure_proxy_environment_variables
+ parse_json
+ end
+
+ def parse_json
+ if Chef::Config[:json_attribs]
+ config_fetcher = Chef::ConfigFetcher.new(Chef::Config[:json_attribs])
+ @json_attribs = config_fetcher.fetch_json
+ end
end
def read_recipe_file(file_name)
@@ -106,7 +122,7 @@ class Chef::Application::Apply < Chef::Application
def get_recipe_and_run_context
Chef::Config[:solo] = true
- @chef_client = Chef::Client.new
+ @chef_client = Chef::Client.new(@json_attribs)
@chef_client.run_ohai
@chef_client.load_node
@chef_client.build_node
diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb
index 295dc2470e..d5dc936f83 100644
--- a/lib/chef/application/client.rb
+++ b/lib/chef/application/client.rb
@@ -27,6 +27,7 @@ require 'chef/handler/error_report'
require 'chef/workstation_config_loader'
class Chef::Application::Client < Chef::Application
+ include Chef::Mixin::ShellOut
# Mimic self_pipe sleep from Unicorn to capture signals safely
SELF_PIPE = []
@@ -63,7 +64,7 @@ class Chef::Application::Client < Chef::Application
option :log_level,
:short => "-l LEVEL",
:long => "--log_level LEVEL",
- :description => "Set the log level (debug, info, warn, error, fatal)",
+ :description => "Set the log level (auto, debug, info, warn, error, fatal)",
:proc => lambda { |l| l.to_sym }
option :log_location,
@@ -104,7 +105,12 @@ class Chef::Application::Client < Chef::Application
option :pid_file,
:short => "-P PID_FILE",
:long => "--pid PIDFILE",
- :description => "Set the PID file location, defaults to /tmp/chef-client.pid",
+ :description => "Set the PID file location, for the chef-client daemon process. Defaults to /tmp/chef-client.pid",
+ :proc => nil
+
+ option :lockfile,
+ :long => "--lockfile LOCKFILE",
+ :description => "Set the lockfile location. Prevents multiple client processes from converging at the same time",
:proc => nil
option :interval,
@@ -200,6 +206,10 @@ class Chef::Application::Client < Chef::Application
:description => "Fork client",
:boolean => true
+ option :recipe_url,
+ :long => "--recipe-url=RECIPE_URL",
+ :description => "Pull down a remote archive of recipes and unpack it to the cookbook cache. Only used in local mode."
+
option :enable_reporting,
:short => "-R",
:long => "--enable-reporting",
@@ -239,9 +249,9 @@ class Chef::Application::Client < Chef::Application
end
option :audit_mode,
- :long => "--[no-]audit-mode",
- :description => "If not specified, run converge and audit phase. If true, run only audit phase. If false, run only converge phase.",
- :boolean => true
+ :long => "--audit-mode MODE",
+ :description => "Enable audit-mode with `enabled`. Disable audit-mode with `disabled`. Skip converge and only perform audits with `audit-only`",
+ :proc => lambda { |mo| mo.gsub("-", "_").to_sym }
IMMEDIATE_RUN_SIGNAL = "1".freeze
@@ -252,7 +262,9 @@ class Chef::Application::Client < Chef::Application
def reconfigure
super
- Chef::Config[:specific_recipes] = cli_arguments.map { |file| File.expand_path(file) }
+ raise Chef::Exceptions::PIDFileLockfileMatch if Chef::Util::PathHelper.paths_eql? (Chef::Config[:pid_file] || '' ), (Chef::Config[:lockfile] || '')
+
+ set_specific_recipes
Chef::Config[:chef_server_url] = config[:chef_server_url] if config.has_key? :chef_server_url
@@ -260,6 +272,18 @@ class Chef::Application::Client < Chef::Application
if Chef::Config.local_mode && !Chef::Config.has_key?(:cookbook_path) && !Chef::Config.has_key?(:chef_repo_path)
Chef::Config.chef_repo_path = Chef::Config.find_chef_repo_path(Dir.pwd)
end
+
+ if !Chef::Config.local_mode && Chef::Config.has_key?(:recipe_url)
+ Chef::Application.fatal!("chef-client recipe-url can be used only in local-mode", 1)
+ elsif Chef::Config.local_mode && Chef::Config.has_key?(:recipe_url)
+ Chef::Log.debug "Creating path #{Chef::Config.chef_repo_path} to extract recipes into"
+ FileUtils.mkdir_p(Chef::Config.chef_repo_path)
+ tarball_path = File.join(Chef::Config.chef_repo_path, 'recipes.tgz')
+ fetch_recipe_tarball(Chef::Config[:recipe_url], tarball_path)
+ result = shell_out!("tar zxvf #{tarball_path} -C #{Chef::Config.chef_repo_path}")
+ Chef::Log.debug "#{result.stdout}"
+ end
+
Chef::Config.chef_zero.host = config[:chef_zero_host] if config[:chef_zero_host]
Chef::Config.chef_zero.port = config[:chef_zero_port] if config[:chef_zero_port]
@@ -280,6 +304,19 @@ class Chef::Application::Client < Chef::Application
config_fetcher = Chef::ConfigFetcher.new(Chef::Config[:json_attribs])
@chef_client_json = config_fetcher.fetch_json
end
+
+ if mode = config[:audit_mode] || Chef::Config[:audit_mode]
+ expected_modes = [:enabled, :disabled, :audit_only]
+ unless expected_modes.include?(mode)
+ Chef::Application.fatal!(unrecognized_audit_mode(mode))
+ end
+
+ unless mode == :disabled
+ # This should be removed when audit-mode is enabled by default/no longer
+ # an experimental feature.
+ Chef::Log.warn(audit_mode_experimental_message)
+ end
+ end
end
def load_config_file
@@ -400,4 +437,35 @@ class Chef::Application::Client < Chef::Application
"#{"\n interval = #{Chef::Config[:interval]} seconds" if Chef::Config[:interval]}" +
"\nEnable chef-client interval runs by setting `:client_fork = true` in your config file or adding `--fork` to your command line options."
end
+
+ def audit_mode_settings_explaination
+ "\n* To enable audit mode after converge, use command line option `--audit-mode enabled` or set `:audit_mode = :enabled` in your config file." +
+ "\n* To disable audit mode, use command line option `--audit-mode disabled` or set `:audit_mode = :disabled` in your config file." +
+ "\n* To only run audit mode, use command line option `--audit-mode audit-only` or set `:audit_mode = :audit_only` in your config file." +
+ "\nAudit mode is disabled by default."
+ end
+
+ def unrecognized_audit_mode(mode)
+ "Unrecognized setting #{mode} for audit mode." + audit_mode_settings_explaination
+ end
+
+ def audit_mode_experimental_message
+ msg = if Chef::Config[:audit_mode] == :audit_only
+ "Chef-client has been configured to skip converge and run only audits."
+ else
+ "Chef-client has been configured to run audits after it converges."
+ end
+ msg += " Audit mode is an experimental feature currently under development. API changes may occur. Use at your own risk."
+ msg += audit_mode_settings_explaination
+ return msg
+ end
+
+ def fetch_recipe_tarball(url, path)
+ Chef::Log.debug("Download recipes tarball from #{url} to #{path}")
+ File.open(path, 'wb') do |f|
+ open(url) do |r|
+ f.write(r.read)
+ end
+ end
+ end
end
diff --git a/lib/chef/application/knife.rb b/lib/chef/application/knife.rb
index d3e2f55757..1a19a45598 100644
--- a/lib/chef/application/knife.rb
+++ b/lib/chef/application/knife.rb
@@ -20,7 +20,6 @@ require 'chef/application'
require 'mixlib/log'
require 'ohai/config'
require 'chef/monkey_patches/net_http.rb'
-require 'chef/monkey_patches/uri.rb'
class Chef::Application::Knife < Chef::Application
@@ -64,7 +63,7 @@ class Chef::Application::Knife < Chef::Application
:long => "--disable-editing",
:description => "Do not open EDITOR, just accept the data as is",
:boolean => true,
- :defaut => false
+ :default => false
option :help,
:short => "-h",
diff --git a/lib/chef/application/solo.rb b/lib/chef/application/solo.rb
index 474bbf3f6c..97a1952d0f 100644
--- a/lib/chef/application/solo.rb
+++ b/lib/chef/application/solo.rb
@@ -99,6 +99,11 @@ class Chef::Application::Solo < Chef::Application
:proc => lambda { |p| true }
end
+ option :lockfile,
+ :long => "--lockfile LOCKFILE",
+ :description => "Set the lockfile location. Prevents multiple processes from converging at the same time",
+ :proc => nil
+
option :interval,
:short => "-i SECONDS",
:long => "--interval SECONDS",
@@ -160,6 +165,11 @@ class Chef::Application::Solo < Chef::Application
:description => 'Enable whyrun mode',
:boolean => true
+ option :ez,
+ :long => '--ez',
+ :description => 'A memorial for Ezra Zygmuntowicz',
+ :boolean => true
+
option :environment,
:short => '-E ENVIRONMENT',
:long => '--environment ENVIRONMENT',
@@ -179,6 +189,8 @@ class Chef::Application::Solo < Chef::Application
def reconfigure
super
+ set_specific_recipes
+
Chef::Config[:solo] = true
if Chef::Config[:daemonize]
@@ -191,6 +203,8 @@ class Chef::Application::Solo < Chef::Application
cookbooks_path = Array(Chef::Config[:cookbook_path]).detect{|e| e =~ /\/cookbooks\/*$/ }
recipes_path = File.expand_path(File.join(cookbooks_path, '..'))
+ Chef::Log.debug "Cleanup path #{recipes_path} before extract recipes into it"
+ FileUtils.rm_rf(recipes_path, :secure => true)
Chef::Log.debug "Creating path #{recipes_path} to extract recipes into"
FileUtils.mkdir_p(recipes_path)
tarball_path = File.join(recipes_path, 'recipes.tgz')
@@ -204,6 +218,9 @@ class Chef::Application::Solo < Chef::Application
config_fetcher = Chef::ConfigFetcher.new(Chef::Config[:json_attribs])
@chef_client_json = config_fetcher.fetch_json
end
+
+ # Disable auditing for solo
+ Chef::Config[:audit_mode] = :disabled
end
def setup_application
@@ -211,6 +228,7 @@ class Chef::Application::Solo < Chef::Application
end
def run_application
+ for_ezra if Chef::Config[:ez]
if !Chef::Config[:client_fork] || Chef::Config[:once]
# Run immediately without interval sleep or splay
begin
@@ -225,7 +243,19 @@ class Chef::Application::Solo < Chef::Application
end
end
+
private
+
+ def for_ezra
+ puts <<-EOH
+For Ezra Zygmuntowicz:
+ The man who brought you Chef Solo
+ Early contributor to Chef
+ Kind hearted open source advocate
+ Rest in peace, Ezra.
+EOH
+ end
+
def interval_run_chef_client
if Chef::Config[:daemonize]
Chef::Daemon.daemonize("chef-client")
diff --git a/lib/chef/application/windows_service.rb b/lib/chef/application/windows_service.rb
index bea5e9fcdc..ba7c6dab5a 100644
--- a/lib/chef/application/windows_service.rb
+++ b/lib/chef/application/windows_service.rb
@@ -26,6 +26,7 @@ require 'chef/log'
require 'chef/rest'
require 'mixlib/cli'
require 'socket'
+require 'uri'
require 'win32/daemon'
require 'chef/mixin/shell_out'
diff --git a/lib/chef/application/windows_service_manager.rb b/lib/chef/application/windows_service_manager.rb
index 30810c51f2..de8ed657c2 100644
--- a/lib/chef/application/windows_service_manager.rb
+++ b/lib/chef/application/windows_service_manager.rb
@@ -16,7 +16,9 @@
# limitations under the License.
#
-require 'win32/service'
+if RUBY_PLATFORM =~ /mswin|mingw32|windows/
+ require 'win32/service'
+end
require 'chef/config'
require 'mixlib/cli'
@@ -88,6 +90,8 @@ class Chef
@service_display_name = service_options[:service_display_name]
@service_description = service_options[:service_description]
@service_file_path = service_options[:service_file_path]
+ @service_start_name = service_options[:run_as_user]
+ @password = service_options[:run_as_password]
end
def run(params = ARGV)
@@ -116,7 +120,9 @@ class Chef
# and we don't want that, so we need to override the service type.
:service_type => ::Win32::Service::SERVICE_WIN32_OWN_PROCESS,
:start_type => ::Win32::Service::SERVICE_AUTO_START,
- :binary_path_name => cmd
+ :binary_path_name => cmd,
+ :service_start_name => @service_start_name,
+ :password => @password,
)
puts "Service '#{@service_name}' has successfully been installed."
end
diff --git a/lib/chef/applications.rb b/lib/chef/applications.rb
index 6160bb96cd..6a1a2e8a92 100644
--- a/lib/chef/applications.rb
+++ b/lib/chef/applications.rb
@@ -1,4 +1,3 @@
-require 'chef/application/agent'
require 'chef/application/client'
require 'chef/application/knife'
require 'chef/application/solo'
diff --git a/lib/chef/audit/audit_event_proxy.rb b/lib/chef/audit/audit_event_proxy.rb
new file mode 100644
index 0000000000..b9ca39e5dc
--- /dev/null
+++ b/lib/chef/audit/audit_event_proxy.rb
@@ -0,0 +1,93 @@
+#
+# Author:: Tyler Ball (<tball@chef.io>)
+# Copyright:: Copyright (c) 2014 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.
+#
+
+RSpec::Support.require_rspec_core "formatters/base_text_formatter"
+
+class Chef
+ class Audit
+ class AuditEventProxy < ::RSpec::Core::Formatters::BaseFormatter
+ ::RSpec::Core::Formatters.register self, :stop, :example_group_started
+
+ # TODO I don't like this, but I don't see another way to pass this in
+ # see rspec files configuration.rb#L671 and formatters.rb#L129
+ def self.events=(events)
+ @@events = events
+ end
+
+ def events
+ @@events
+ end
+
+ def example_group_started(notification)
+ if notification.group.parent_groups.size == 1
+ # top level `control_group` block
+ desc = notification.group.description
+ Chef::Log.debug("Entered `control_group` block named #{desc}")
+ events.control_group_started(desc)
+ end
+ end
+
+ def stop(notification)
+ Chef::Log.info("Successfully executed all `control_group` blocks and contained examples")
+ notification.examples.each do |example|
+ control_group_name, control_data = build_control_from(example)
+ e = example.exception
+ if e
+ events.control_example_failure(control_group_name, control_data, e)
+ else
+ events.control_example_success(control_group_name, control_data)
+ end
+ end
+ end
+
+ private
+
+ def build_control_from(example)
+ described_class = example.metadata[:described_class]
+ if described_class
+ resource_type = described_class.class.name.split(':')[-1]
+ resource_name = described_class.name
+ end
+
+ # The following code builds up the context - the list of wrapping `describe` or `control` blocks
+ describe_groups = []
+ group = example.metadata[:example_group]
+ # If the innermost block has a resource instead of a string, don't include it in context
+ describe_groups.unshift(group[:description]) if described_class.nil?
+ group = group[:parent_example_group]
+ while !group.nil?
+ describe_groups.unshift(group[:description])
+ group = group[:parent_example_group]
+ end
+
+ # We know all of our examples each live in a top-level `control_group` block - get this name now
+ outermost_group_desc = describe_groups.shift
+
+ return outermost_group_desc, {
+ :name => example.description,
+ :desc => example.full_description,
+ :resource_type => resource_type,
+ :resource_name => resource_name,
+ :context => describe_groups,
+ :line_number => example.metadata[:line_number]
+ }
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/audit/audit_reporter.rb b/lib/chef/audit/audit_reporter.rb
new file mode 100644
index 0000000000..a5dd9a6c48
--- /dev/null
+++ b/lib/chef/audit/audit_reporter.rb
@@ -0,0 +1,169 @@
+#
+# Author:: Tyler Ball (<tball@chef.io>)
+#
+# Copyright:: Copyright (c) 2014 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/event_dispatch/base'
+require 'chef/audit/control_group_data'
+require 'time'
+
+class Chef
+ class Audit
+ class AuditReporter < EventDispatch::Base
+
+ attr_reader :rest_client, :audit_data, :ordered_control_groups, :run_status
+ private :rest_client, :audit_data, :ordered_control_groups, :run_status
+
+ PROTOCOL_VERSION = '0.1.1'
+
+ def initialize(rest_client)
+ @rest_client = rest_client
+ # Ruby 1.9.3 and above "enumerate their values in the order that the corresponding keys were inserted."
+ @ordered_control_groups = Hash.new
+ end
+
+ def run_context
+ run_status.run_context
+ end
+
+ def audit_phase_start(run_status)
+ Chef::Log.debug("Audit Reporter starting")
+ @audit_data = AuditData.new(run_status.node.name, run_status.run_id)
+ @run_status = run_status
+ end
+
+ def audit_phase_complete
+ Chef::Log.debug("Audit Reporter completed successfully without errors.")
+ ordered_control_groups.each do |name, control_group|
+ audit_data.add_control_group(control_group)
+ end
+ end
+
+ # If the audit phase failed, its because there was some kind of error in the framework
+ # that runs tests - normal errors are interpreted as EXAMPLE failures and captured.
+ # We still want to send available audit information to the server so we process the
+ # known control groups.
+ def audit_phase_failed(error)
+ # The stacktrace information has already been logged elsewhere
+ Chef::Log.debug("Audit Reporter failed.")
+ ordered_control_groups.each do |name, control_group|
+ audit_data.add_control_group(control_group)
+ end
+ end
+
+ def run_completed(node)
+ post_auditing_data
+ end
+
+ def run_failed(error)
+ post_auditing_data(error)
+ end
+
+ def control_group_started(name)
+ if ordered_control_groups.has_key?(name)
+ raise Chef::Exceptions::AuditControlGroupDuplicate.new(name)
+ end
+ metadata = run_context.audits[name].metadata
+ ordered_control_groups.store(name, ControlGroupData.new(name, metadata))
+ end
+
+ def control_example_success(control_group_name, example_data)
+ control_group = ordered_control_groups[control_group_name]
+ control_group.example_success(example_data)
+ end
+
+ def control_example_failure(control_group_name, example_data, error)
+ control_group = ordered_control_groups[control_group_name]
+ control_group.example_failure(example_data, error.message)
+ end
+
+ # If @audit_enabled is nil or true, we want to run audits
+ def auditing_enabled?
+ Chef::Config[:audit_mode] != :disabled
+ end
+
+ private
+
+ def post_auditing_data(error = nil)
+ unless auditing_enabled?
+ Chef::Log.debug("Audit Reports are disabled. Skipping sending reports.")
+ return
+ end
+
+ unless run_status
+ Chef::Log.debug("Run failed before audits were initialized, not sending audit report to server")
+ return
+ end
+
+ audit_data.start_time = iso8601ify(run_status.start_time)
+ audit_data.end_time = iso8601ify(run_status.end_time)
+
+ audit_history_url = "controls"
+ Chef::Log.debug("Sending audit report (run-id: #{audit_data.run_id})")
+ run_data = audit_data.to_hash
+
+ if error
+ run_data[:error] = "#{error.class.to_s}: #{error.message}\n#{error.backtrace.join("\n")}"
+ end
+
+ Chef::Log.debug "Audit Report:\n#{Chef::JSONCompat.to_json_pretty(run_data)}"
+ # Since we're posting compressed data we can not directly call post_rest which expects JSON
+ begin
+ audit_url = rest_client.create_url(audit_history_url)
+ rest_client.post(audit_url, run_data, headers)
+ rescue StandardError => e
+ if e.respond_to? :response
+ # 404 error code is OK. This means the version of server we're running against doesn't support
+ # audit reporting. Don't alarm failure in this case.
+ if e.response.code == "404"
+ Chef::Log.debug("Server doesn't support audit reporting. Skipping report.")
+ return
+ else
+ # 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)}")
+ end
+ else
+ Chef::Log.error("Failed to post audit report to server (#{e})")
+ end
+
+ if Chef::Config[:enable_reporting_url_fatals]
+ Chef::Log.error("Reporting fatals enabled. Aborting run.")
+ raise
+ end
+ end
+ end
+
+ def headers(additional_headers = {})
+ options = {'X-Ops-Audit-Report-Protocol-Version' => PROTOCOL_VERSION}
+ options.merge(additional_headers)
+ end
+
+ def encode_gzip(data)
+ "".tap do |out|
+ Zlib::GzipWriter.wrap(StringIO.new(out)){|gz| gz << data }
+ end
+ end
+
+ def iso8601ify(time)
+ time.utc.iso8601.to_s
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/audit/control_group_data.rb b/lib/chef/audit/control_group_data.rb
new file mode 100644
index 0000000000..204d7f8070
--- /dev/null
+++ b/lib/chef/audit/control_group_data.rb
@@ -0,0 +1,140 @@
+#
+# Author:: Tyler Ball (<tball@chef.io>)
+#
+# Copyright:: Copyright (c) 2014 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 'securerandom'
+
+class Chef
+ class Audit
+ class AuditData
+ attr_reader :node_name, :run_id, :control_groups
+ attr_accessor :start_time, :end_time
+
+ def initialize(node_name, run_id)
+ @node_name = node_name
+ @run_id = run_id
+ @control_groups = []
+ end
+
+ def add_control_group(control_group)
+ control_groups << control_group
+ end
+
+ def to_hash
+ {
+ :node_name => node_name,
+ :run_id => run_id,
+ :start_time => start_time,
+ :end_time => end_time,
+ :control_groups => control_groups.collect { |c| c.to_hash }
+ }
+ end
+ end
+
+ class ControlGroupData
+ attr_reader :name, :status, :number_succeeded, :number_failed, :controls, :metadata
+
+ def initialize(name, metadata={})
+ @status = "success"
+ @controls = []
+ @number_succeeded = 0
+ @number_failed = 0
+ @name = name
+ @metadata = metadata
+ end
+
+
+ def example_success(control_data)
+ @number_succeeded += 1
+ control = create_control(control_data)
+ control.status = "success"
+ controls << control
+ control
+ end
+
+ def example_failure(control_data, details)
+ @number_failed += 1
+ @status = "failure"
+ control = create_control(control_data)
+ control.details = details if details
+ control.status = "failure"
+ controls << control
+ control
+ end
+
+ def to_hash
+ # We sort it so the examples appear in the output in the same order
+ # they appeared in the recipe
+ controls.sort! {|x,y| x.line_number <=> y.line_number}
+ h = {
+ :name => name,
+ :status => status,
+ :number_succeeded => number_succeeded,
+ :number_failed => number_failed,
+ :controls => controls.collect { |c| c.to_hash }
+ }
+ # If there is a duplicate key, metadata will overwrite it
+ add_display_only_data(h).merge(metadata)
+ end
+
+ private
+
+ def create_control(control_data)
+ ControlData.new(control_data)
+ end
+
+ # The id and control sequence number are ephemeral data - they are not needed
+ # to be persisted and can be regenerated at will. They are only needed
+ # for display purposes.
+ def add_display_only_data(group)
+ group[:id] = SecureRandom.uuid
+ group[:controls].collect!.with_index do |c, i|
+ # i is zero-indexed, and we want the display one-indexed
+ c[:sequence_number] = i+1
+ c
+ end
+ group
+ end
+
+ end
+
+ class ControlData
+ attr_reader :name, :resource_type, :resource_name, :context, :line_number
+ attr_accessor :status, :details
+
+ def initialize(control_data={})
+ control_data.each do |k, v|
+ self.instance_variable_set("@#{k}", v)
+ end
+ end
+
+ def to_hash
+ h = {
+ :name => name,
+ :status => status,
+ :details => details,
+ :resource_type => resource_type,
+ :resource_name => resource_name
+ }
+ h[:context] = context || []
+ h
+ end
+ end
+
+ end
+end
diff --git a/lib/chef/audit/rspec_formatter.rb b/lib/chef/audit/rspec_formatter.rb
new file mode 100644
index 0000000000..074a11bed3
--- /dev/null
+++ b/lib/chef/audit/rspec_formatter.rb
@@ -0,0 +1,37 @@
+#
+# Author:: Serdar Sutay (<serdar@chef.io>)
+# Copyright:: Copyright (c) 2014 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 'rspec/core'
+
+class Chef
+ class Audit
+ class RspecFormatter < RSpec::Core::Formatters::DocumentationFormatter
+ RSpec::Core::Formatters.register self, :close
+
+ # @api public
+ #
+ # Invoked at the very end, `close` allows the formatter to clean
+ # up resources, e.g. open streams, etc.
+ #
+ # @param _notification [NullNotification] (Ignored)
+ def close(_notification)
+ # Normally Rspec closes the streams it's given. We don't want it for Chef.
+ end
+ end
+ end
+end
diff --git a/lib/chef/audit/runner.rb b/lib/chef/audit/runner.rb
new file mode 100644
index 0000000000..e7d1657d69
--- /dev/null
+++ b/lib/chef/audit/runner.rb
@@ -0,0 +1,178 @@
+#
+# Author:: Claire McQuin (<claire@getchef.com>)
+# Copyright:: Copyright (c) 2014 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.
+#
+
+class Chef
+ class Audit
+ class Runner
+
+ attr_reader :run_context
+ private :run_context
+
+ def initialize(run_context)
+ @run_context = run_context
+ end
+
+ def run
+ setup
+ register_control_groups
+ do_run
+ end
+
+ def failed?
+ RSpec.world.reporter.failed_examples.size > 0
+ end
+
+ def num_failed
+ RSpec.world.reporter.failed_examples.size
+ end
+
+ def num_total
+ RSpec.world.reporter.examples.size
+ end
+
+ private
+ # Prepare to run audits:
+ # - Require files
+ # - Configure RSpec
+ # - Configure Specinfra/Serverspec
+ def setup
+ require_deps
+ configure_rspec
+ configure_specinfra
+ end
+
+ # RSpec uses a global configuration object, RSpec.configuration. We found
+ # there was interference between the configuration for audit-mode and
+ # the configuration for our own spec tests in these cases:
+ # 1. Specinfra and Serverspec modify RSpec.configuration when loading.
+ # 2. Setting output/error streams.
+ # 3. Adding formatters.
+ # 4. Defining example group aliases.
+ #
+ # Moreover, Serverspec loads its DSL methods into the global namespace,
+ # which causes conflicts with the Chef namespace for resources and packages.
+ #
+ # We wait until we're in the audit-phase of the chef-client run to load
+ # these files. This helps with the namespacing problems we saw, and
+ # prevents Specinfra and Serverspec from modifying the RSpec configuration
+ # used by our spec tests.
+ def require_deps
+ require 'rspec'
+ require 'rspec/its'
+ require 'specinfra'
+ require 'serverspec/helper'
+ require 'serverspec/matcher'
+ require 'serverspec/subject'
+ require 'chef/audit/audit_event_proxy'
+ require 'chef/audit/rspec_formatter'
+ end
+
+ # Configure RSpec just the way we like it:
+ # - Set location of error and output streams
+ # - Add custom audit-mode formatters
+ # - Explicitly disable :should syntax
+ # - Set :color option according to chef config
+ # - Disable exposure of global DSL
+ def configure_rspec
+ set_streams
+ add_formatters
+ disable_should_syntax
+
+ RSpec.configure do |c|
+ c.color = Chef::Config[:color]
+ c.expose_dsl_globally = false
+ end
+ end
+
+ # Set the error and output streams which audit-mode will use to report
+ # human-readable audit information.
+ #
+ # This should always be called before #add_formatters. RSpec won't allow
+ # the output stream to be changed for a formatter once the formatter has
+ # been added.
+ def set_streams
+ RSpec.configuration.output_stream = Chef::Config[:log_location]
+ RSpec.configuration.error_stream = Chef::Config[:log_location]
+ end
+
+ # Add formatters which we use to
+ # 1. Output human-readable data to the output stream,
+ # 2. Collect JSON data to send back to the analytics server.
+ def add_formatters
+ RSpec.configuration.add_formatter(Chef::Audit::AuditEventProxy)
+ RSpec.configuration.add_formatter(Chef::Audit::RspecFormatter)
+ Chef::Audit::AuditEventProxy.events = run_context.events
+ end
+
+ # Audit-mode uses RSpec 3. :should syntax is deprecated by default in
+ # RSpec 3, so we explicitly disable it here.
+ #
+ # This can be removed once :should is removed from RSpec.
+ def disable_should_syntax
+ RSpec.configure do |config|
+ config.expect_with :rspec do |c|
+ c.syntax = :expect
+ end
+ end
+ end
+
+ # Set up the backend for Specinfra/Serverspec. :exec is the local system.
+ def configure_specinfra
+ Specinfra.configuration.backend = :exec
+ end
+
+ # Iterates through the control groups registered to this run_context, builds an
+ # example group (RSpec::Core::ExampleGroup) object per control group, and
+ # registers the group with the RSpec.world.
+ #
+ # We could just store an array of example groups and not use RSpec.world,
+ # but it may be useful later if we decide to apply our own ordering scheme
+ # or use example group filters.
+ def register_control_groups
+ 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)
+ end
+ end
+
+ # Add example group method aliases to RSpec.
+ #
+ # __control_group__: Used internally to create example groups from the control
+ # groups saved in the run_context.
+ # control: Used within the context of a control group block, like RSpec's
+ # describe or context.
+ def add_example_group_methods
+ RSpec::Core::ExampleGroup.define_example_group_method :__control_group__
+ RSpec::Core::ExampleGroup.define_example_group_method :control
+ end
+
+ # Run the audits!
+ def do_run
+ # RSpec::Core::Runner wants to be initialized with an
+ # RSpec::Core::ConfigurationOptions object, which is used to process
+ # command line configuration arguments. We directly fiddle with the
+ # internal RSpec configuration object, so we give nil here and let
+ # RSpec pick up its own configuration and world.
+ runner = RSpec::Core::Runner.new(nil)
+ runner.run_specs(RSpec.world.ordered_example_groups)
+ end
+
+ end
+ 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 3813d0edb4..4084fb80d3 100644
--- a/lib/chef/chef_fs/chef_fs_data_store.rb
+++ b/lib/chef/chef_fs/chef_fs_data_store.rb
@@ -16,6 +16,7 @@
# limitations under the License.
#
+require 'chef/cookbook_manifest'
require 'chef_zero/data_store/memory_store'
require 'chef_zero/data_store/data_already_exists_error'
require 'chef_zero/data_store/data_not_found_error'
@@ -147,7 +148,7 @@ class Chef
# get /cookbooks/NAME/version
result = nil
begin
- result = entry.chef_object.to_hash
+ result = Chef::CookbookManifest.new(entry.chef_object).to_hash
rescue Chef::ChefFS::FileSystem::NotFoundError => e
raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e)
end
@@ -369,6 +370,11 @@ class Chef
if path.length >= 3
path[2] = "#{path[2]}.json"
end
+ elsif path[0] == 'policies'
+ path = path.dup
+ if path.length >= 3
+ path[2] = "#{path[2]}.json"
+ end
elsif path[0] == 'cookbooks'
if path.length == 2
raise ChefZero::DataStore::DataNotFoundError.new(path)
@@ -445,10 +451,13 @@ class Chef
def with_dir(path)
# Do not automatically create data bags
create = !(path[0] == 'data' && path.size >= 2)
+
begin
yield get_dir(_to_chef_fs_path(path), create)
rescue Chef::ChefFS::FileSystem::NotFoundError => e
- raise ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e)
+ err = ChefZero::DataStore::DataNotFoundError.new(to_zero_path(e.entry), e)
+ err.set_backtrace(e.backtrace)
+ raise err
end
end
diff --git a/lib/chef/chef_fs/config.rb b/lib/chef/chef_fs/config.rb
index fcad6c919f..6666a3deee 100644
--- a/lib/chef/chef_fs/config.rb
+++ b/lib/chef/chef_fs/config.rb
@@ -26,6 +26,25 @@ class Chef
# objects representing the server and local repository, respectively).
#
class Config
+
+ # Not all of our object types pluralize by adding an 's', so we map them
+ # out here:
+ INFLECTIONS = {
+ "acls" => "acl",
+ "clients" => "client",
+ "cookbooks" => "cookbook",
+ "containers" => "container",
+ "data_bags" => "data_bag",
+ "environments" => "environment",
+ "groups" => "group",
+ "nodes" => "node",
+ "roles" => "role",
+ "users" => "user",
+ "policies" => "policy"
+ }
+ INFLECTIONS.each { |k,v| k.freeze; v.freeze }
+ INFLECTIONS.freeze
+
#
# Create a new Config object which can produce a chef_fs and local_fs.
#
@@ -215,14 +234,16 @@ class Chef
result = {}
case @chef_config[:repo_mode]
when 'static'
- object_names = %w(cookbooks data_bags environments roles)
+ object_names = %w(cookbooks data_bags environments roles policies)
when 'hosted_everything'
- object_names = %w(acls clients cookbooks containers data_bags environments groups nodes roles)
+ object_names = %w(acls clients cookbooks containers data_bags environments groups nodes roles policies)
else
- object_names = %w(clients cookbooks data_bags environments nodes roles users)
+ object_names = %w(clients cookbooks data_bags environments nodes roles users policies)
end
object_names.each do |object_name|
- variable_name = "#{object_name[0..-2]}_path" # cookbooks -> cookbook_path
+ # cookbooks -> cookbook_path
+ singular_name = INFLECTIONS[object_name] or raise "Unknown object name #{object_name}"
+ variable_name = "#{singular_name}_path"
paths = Array(@chef_config[variable_name]).flatten
result[object_name] = paths.map { |path| File.expand_path(path) }
end
diff --git a/lib/chef/chef_fs/data_handler/policy_data_handler.rb b/lib/chef/chef_fs/data_handler/policy_data_handler.rb
new file mode 100644
index 0000000000..769c13c364
--- /dev/null
+++ b/lib/chef/chef_fs/data_handler/policy_data_handler.rb
@@ -0,0 +1,15 @@
+require 'chef/chef_fs/data_handler/data_handler_base'
+
+class Chef
+ module ChefFS
+ module DataHandler
+ class PolicyDataHandler < DataHandlerBase
+
+ def normalize(policy, entry)
+ policy
+ end
+ end
+ end
+ end
+end
+
diff --git a/lib/chef/chef_fs/data_handler/user_data_handler.rb b/lib/chef/chef_fs/data_handler/user_data_handler.rb
index 2b50ce38d8..f6859faccd 100644
--- a/lib/chef/chef_fs/data_handler/user_data_handler.rb
+++ b/lib/chef/chef_fs/data_handler/user_data_handler.rb
@@ -8,6 +8,7 @@ class Chef
normalize_hash(user, {
'name' => remove_dot_json(entry.name),
'username' => remove_dot_json(entry.name),
+ 'display_name' => remove_dot_json(entry.name),
'admin' => false,
'json_class' => 'Chef::WebUIUser',
'chef_type' => 'webui_user',
diff --git a/lib/chef/chef_fs/file_system.rb b/lib/chef/chef_fs/file_system.rb
index 730fa0e5cc..3ab59046cc 100644
--- a/lib/chef/chef_fs/file_system.rb
+++ b/lib/chef/chef_fs/file_system.rb
@@ -379,7 +379,7 @@ class Chef
should_copy = true
src_value = nil
else
- are_same, src_value, dest_value = compare(src_entry, dest_entry)
+ are_same, src_value, _dest_value = compare(src_entry, dest_entry)
should_copy = !are_same
end
if should_copy
diff --git a/lib/chef/chef_fs/file_system/base_fs_dir.rb b/lib/chef/chef_fs/file_system/base_fs_dir.rb
index 74038f481b..8cc277facc 100644
--- a/lib/chef/chef_fs/file_system/base_fs_dir.rb
+++ b/lib/chef/chef_fs/file_system/base_fs_dir.rb
@@ -40,6 +40,11 @@ class Chef
true
end
+ # An empty children array is an empty dir
+ def empty?
+ children.empty?
+ end
+
# Abstract: children
end
end
diff --git a/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb b/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb
index 6541b07065..66709ccf68 100644
--- a/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb
+++ b/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb
@@ -53,7 +53,7 @@ class Chef
# Check chefignore
ignorer = parent
- begin
+ loop do
if ignorer.is_a?(ChefRepositoryFileSystemCookbooksDir)
# Grab the path from entry to child
path_to_child = name
@@ -66,7 +66,8 @@ class Chef
return !ignorer.chefignore || !ignorer.chefignore.ignored?(path_to_child)
end
ignorer = ignorer.parent
- end while ignorer
+ break unless ignorer
+ end
true
end
diff --git a/lib/chef/shef/ext.rb b/lib/chef/chef_fs/file_system/chef_repository_file_system_policies_dir.rb
index 8f03de2d04..42768f10b7 100644
--- a/lib/chef/shef/ext.rb
+++ b/lib/chef/chef_fs/file_system/chef_repository_file_system_policies_dir.rb
@@ -1,5 +1,5 @@
-#--
-# Author:: Joshua Timberman (<joshua@opscode.com>)
+#
+# Author:: John Keiser (<jkeiser@opscode.com>)
# Copyright:: Copyright (c) 2012 Opscode, Inc.
# License:: Apache License, Version 2.0
#
@@ -16,4 +16,23 @@
# limitations under the License.
#
-require 'chef/shell/ext'
+require 'chef/chef_fs/file_system/chef_repository_file_system_entry'
+require 'chef/chef_fs/data_handler/policy_data_handler'
+
+class Chef
+ module ChefFS
+ module FileSystem
+
+ class ChefRepositoryFileSystemPoliciesDir < ChefRepositoryFileSystemEntry
+ def initialize(name, parent, path = nil)
+ super(name, parent, path, Chef::ChefFS::DataHandler::PolicyDataHandler.new)
+ end
+
+ def can_have_child?(name, is_dir)
+ is_dir && !name.start_with?('.')
+ end
+ end
+ end
+ end
+end
+
diff --git a/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb b/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb
index ac272d4c1a..d03baf91fe 100644
--- a/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb
+++ b/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb
@@ -21,6 +21,7 @@ require 'chef/chef_fs/file_system/chef_repository_file_system_entry'
require 'chef/chef_fs/file_system/chef_repository_file_system_acls_dir'
require 'chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir'
require 'chef/chef_fs/file_system/chef_repository_file_system_data_bags_dir'
+require 'chef/chef_fs/file_system/chef_repository_file_system_policies_dir'
require 'chef/chef_fs/file_system/multiplexed_dir'
require 'chef/chef_fs/data_handler/client_data_handler'
require 'chef/chef_fs/data_handler/environment_data_handler'
@@ -33,6 +34,7 @@ require 'chef/chef_fs/data_handler/container_data_handler'
class Chef
module ChefFS
module FileSystem
+
#
# Represents the root of a local Chef repository, with directories for
# nodes, cookbooks, roles, etc. under it.
@@ -157,6 +159,8 @@ class Chef
dirs = paths.map { |path| ChefRepositoryFileSystemCookbooksDir.new(name, self, path) }
elsif name == 'data_bags'
dirs = paths.map { |path| ChefRepositoryFileSystemDataBagsDir.new(name, self, path) }
+ elsif name == 'policies'
+ dirs = paths.map { |path| ChefRepositoryFileSystemPoliciesDir.new(name, self, path) }
elsif name == 'acls'
dirs = paths.map { |path| ChefRepositoryFileSystemAclsDir.new(name, self, path) }
else
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index 4f37bd0ee3..3b4f8d4683 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -25,6 +25,7 @@ require 'chef/log'
require 'chef/rest'
require 'chef/api_client'
require 'chef/api_client/registration'
+require 'chef/audit/runner'
require 'chef/node'
require 'chef/role'
require 'chef/file_cache'
@@ -38,11 +39,13 @@ require 'chef/cookbook/remote_file_vendor'
require 'chef/event_dispatch/dispatcher'
require 'chef/event_loggers/base'
require 'chef/event_loggers/windows_eventlog'
+require 'chef/exceptions'
require 'chef/formatters/base'
require 'chef/formatters/doc'
require 'chef/formatters/minimal'
require 'chef/version'
require 'chef/resource_reporter'
+require 'chef/audit/audit_reporter'
require 'chef/run_lock'
require 'chef/policy_builder'
require 'chef/request_id'
@@ -209,6 +212,17 @@ class Chef
end
end
+ # Resource repoters send event information back to the chef server for processing.
+ # Can only be called after we have a @rest object
+ def register_reporters
+ [
+ Chef::ResourceReporter.new(rest),
+ Chef::Audit::AuditReporter.new(rest)
+ ].each do |r|
+ events.register(r)
+ end
+ end
+
# Instantiates a Chef::Node object, possibly loading the node's prior state
# when using chef-client. Delegates to policy_builder
#
@@ -246,7 +260,6 @@ class Chef
@policy_builder ||= Chef::PolicyBuilder.strategy.new(node_name, ohai.data, json_attribs, @override_runlist, events)
end
-
def save_updated_node
if Chef::Config[:solo]
# nothing to do
@@ -260,6 +273,7 @@ class Chef
def run_ohai
ohai.all_plugins
+ @events.ohai_completed(node)
end
def node_name
@@ -295,8 +309,7 @@ class Chef
end
# We now have the client key, and should use it from now on.
@rest = Chef::REST.new(config[:chef_server_url], client_name, config[:client_key])
- @resource_reporter = Chef::ResourceReporter.new(@rest)
- @events.register(@resource_reporter)
+ register_reporters
rescue Exception => e
# TODO: munge exception so a semantic failure message can be given to the
# user
@@ -307,18 +320,56 @@ class Chef
# Converges the node.
#
# === Returns
- # true:: Always returns true
+ # The thrown exception, if there was one. If this returns nil the converge was successful.
def converge(run_context)
- @events.converge_start(run_context)
- Chef::Log.debug("Converging node #{node_name}")
- @runner = Chef::Runner.new(run_context)
- runner.converge
- @events.converge_complete
- true
- rescue Exception
- # TODO: should this be a separate #converge_failed(exception) method?
- @events.converge_complete
- raise
+ converge_exception = nil
+ catch(:end_client_run_early) do
+ begin
+ @events.converge_start(run_context)
+ Chef::Log.debug("Converging node #{node_name}")
+ @runner = Chef::Runner.new(run_context)
+ runner.converge
+ @events.converge_complete
+ rescue Exception => e
+ Chef::Log.error("Converge failed with error message #{e.message}")
+ @events.converge_failed(e)
+ converge_exception = e
+ end
+ end
+ converge_exception
+ end
+
+ # We don't want to change the old API on the `converge` method to have it perform
+ # saving. So we wrap it in this method.
+ def converge_and_save(run_context)
+ converge_exception = converge(run_context)
+ unless converge_exception
+ begin
+ save_updated_node
+ rescue Exception => e
+ converge_exception = e
+ end
+ end
+ converge_exception
+ end
+
+ def run_audits(run_context)
+ audit_exception = nil
+ begin
+ @events.audit_phase_start(run_status)
+ Chef::Log.info("Starting audit phase")
+ auditor = Chef::Audit::Runner.new(run_context)
+ auditor.run
+ if auditor.failed?
+ raise Chef::Exceptions::AuditsFailed.new(auditor.num_failed, auditor.num_total)
+ end
+ @events.audit_phase_complete
+ rescue Exception => e
+ Chef::Log.error("Audit phase failed with error message: #{e.message}")
+ @events.audit_phase_failed(e)
+ audit_exception = e
+ end
+ audit_exception
end
# Expands the run list. Delegates to the policy_builder.
@@ -333,7 +384,6 @@ class Chef
policy_builder.expand_run_list
end
-
def do_windows_admin_check
if Chef::Platform.windows?
Chef::Log.debug("Checking for administrator privileges....")
@@ -370,8 +420,6 @@ class Chef
begin
runlock.save_pid
- check_ssl_config
-
request_id = Chef::RequestID.instance.request_id
run_context = nil
@events.run_start(Chef::VERSION)
@@ -380,7 +428,7 @@ class Chef
Chef::Log.debug("Chef-client request_id: #{request_id}")
enforce_path_sanity
run_ohai
- @events.ohai_completed(node)
+
register unless Chef::Config[:solo]
load_node
@@ -396,11 +444,22 @@ class Chef
run_context = setup_run_context
- catch(:end_client_run_early) do
- converge(run_context)
+ if Chef::Config[:audit_mode] != :audit_only
+ converge_error = converge_and_save(run_context)
+ end
+
+ if Chef::Config[:why_run] == true
+ # why_run should probably be renamed to why_converge
+ Chef::Log.debug("Not running audits in 'why_run' mode - this mode is used to see potential converge changes")
+ elsif Chef::Config[:audit_mode] != :disabled
+ audit_error = run_audits(run_context)
end
- save_updated_node
+ if converge_error || audit_error
+ e = Chef::Exceptions::RunFailedWrappingError.new(converge_error, audit_error)
+ e.fill_backtrace
+ raise e
+ end
run_status.stop_clock
Chef::Log.info("Chef Run complete in #{run_status.elapsed_time} seconds")
@@ -411,6 +470,7 @@ class Chef
Chef::Platform::Rebooter.reboot_if_needed!(node)
true
+
rescue Exception => e
# CHEF-3336: Send the error first in case something goes wrong below and we don't know why
Chef::Log.debug("Re-raising exception: #{e.class} - #{e.message}\n#{e.backtrace.join("\n ")}")
@@ -468,37 +528,6 @@ class Chef
Chef::ReservedNames::Win32::Security.has_admin_privileges?
end
- def check_ssl_config
- if Chef::Config[:ssl_verify_mode] == :verify_none and !Chef::Config[:verify_api_cert]
- Chef::Log.warn(<<-WARN)
-
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-SSL validation of HTTPS requests is disabled. HTTPS connections are still
-encrypted, but chef is not able to detect forged replies or man in the middle
-attacks.
-
-To fix this issue add an entry like this to your configuration file:
-
-```
- # Verify all HTTPS connections (recommended)
- ssl_verify_mode :verify_peer
-
- # OR, Verify only connections to chef-server
- verify_api_cert true
-```
-
-To check your SSL configuration, or troubleshoot errors, you can use the
-`knife ssl check` command like so:
-
-```
- knife ssl check -c #{Chef::Config.config_file}
-```
-
-* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-WARN
- end
- end
-
end
end
diff --git a/lib/chef/config.rb b/lib/chef/config.rb
index 538271de0e..c9e0914c0b 100644
--- a/lib/chef/config.rb
+++ b/lib/chef/config.rb
@@ -203,6 +203,10 @@ class Chef
# Does not apply to Enterprise Chef commands.
default(:user_path) { derive_path_from_chef_repo_path('users') }
+ # Location of policies on disk. String or array of strings.
+ # Defaults to <chef_repo_path>/policies.
+ default(:policy_path) { derive_path_from_chef_repo_path('policies') }
+
# Turn on "path sanity" by default. See also: http://wiki.opscode.com/display/chef/User+Environment+PATH+Sanity
default :enforce_path_sanity, true
@@ -271,7 +275,7 @@ class Chef
# * :fatal
# These work as you'd expect. There is also a special `:auto` setting.
# When set to :auto, Chef will auto adjust the log verbosity based on
- # context. When a tty is available (usually becase the user is running chef
+ # context. When a tty is available (usually because the user is running chef
# in a console), the log level is set to :warn, and output formatters are
# used as the primary mode of output. When a tty is not available, the
# logger is the primary mode of output, and the log level is set to :info
@@ -317,8 +321,17 @@ class Chef
default :why_run, false
default :color, false
default :client_fork, true
+ default :ez, false
default :enable_reporting, true
default :enable_reporting_url_fatals, false
+ # Possible values for :audit_mode
+ # :enabled, :disabled, :audit_only,
+ #
+ # TODO: 11 Dec 2014: Currently audit-mode is an experimental feature
+ # and is disabled by default. When users choose to enable audit-mode,
+ # a warning is issued in application/client#reconfigure.
+ # This can be removed when audit-mode is enabled by default.
+ default :audit_mode, :disabled
# Policyfile is an experimental feature where a node gets its run list and
# cookbook version set from a single document on the server instead of
@@ -486,8 +499,20 @@ class Chef
# Deprecated:
default(:cache_options) { { :path => PathHelper.join(file_cache_path, "checksums") } }
- # Set to false to silence Chef 11 deprecation warnings:
- default :chef11_deprecation_warnings, true
+ # Whether errors should be raised for deprecation warnings. When set to
+ # `false` (the default setting), a warning is emitted but code using
+ # deprecated methods/features/etc. should work normally otherwise. When set
+ # to `true`, usage of deprecated methods/features will raise a
+ # `DeprecatedFeatureError`. This is used by Chef's tests to ensure that
+ # deprecated functionality is not used internally by Chef. End users
+ # should generally leave this at the default setting (especially in
+ # production), but it may be useful when testing cookbooks or other code if
+ # the user wishes to aggressively address deprecations.
+ default(:treat_deprecation_warnings_as_errors) do
+ # Using an environment variable allows this setting to be inherited in
+ # tests that spawn new processes.
+ ENV.key?("CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS")
+ end
# knife configuration data
config_context :knife do
@@ -602,6 +627,13 @@ class Chef
#
default :no_lazy_load, true
+ # Default for the chef_gem compile_time attribute. Nil is the same as false but will emit
+ # warnings on every use of chef_gem prompting the user to be explicit. If the user sets this to
+ # true then the user will get backcompat behavior but with a single nag warning that cookbooks
+ # may break with this setting in the future. The false setting is the recommended setting and
+ # will become the default.
+ default :chef_gem_compile_time, nil
+
# A whitelisted array of attributes you want sent over the wire when node
# data is saved.
# The default setting is nil, which collects all data. Setting to [] will not
diff --git a/lib/chef/cookbook/metadata.rb b/lib/chef/cookbook/metadata.rb
index 54e930135d..781d3b40b0 100644
--- a/lib/chef/cookbook/metadata.rb
+++ b/lib/chef/cookbook/metadata.rb
@@ -227,11 +227,11 @@ class Chef
)
end
- # Sets the current cookbook version, or returns it. Can be two or three digits, seperated
+ # Sets the current cookbook version, or returns it. Can be two or three digits, separated
# by dots. ie: '2.1', '1.5.4' or '0.9'.
#
# === Parameters
- # version<String>:: The curent version, as a string
+ # version<String>:: The current version, as a string
#
# === Returns
# version<String>:: Returns the current version
@@ -246,7 +246,7 @@ class Chef
# Sets the name of the cookbook, or returns it.
#
# === Parameters
- # name<String>:: The curent cookbook name.
+ # name<String>:: The current cookbook name.
#
# === Returns
# name<String>:: Returns the current cookbook name.
diff --git a/lib/chef/cookbook_manifest.rb b/lib/chef/cookbook_manifest.rb
new file mode 100644
index 0000000000..0d21e9725c
--- /dev/null
+++ b/lib/chef/cookbook_manifest.rb
@@ -0,0 +1,275 @@
+# Author:: Daniel DeLeo (<dan@chef.io>)
+# Copyright:: Copyright 2015 Opscode, 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 'forwardable'
+require 'chef/util/path_helper'
+require 'chef/log'
+
+class Chef
+
+ # Handles the details of representing a cookbook in JSON form for uploading
+ # to a Chef Server.
+ class CookbookManifest
+
+ # Duplicates the same constant in CookbookVersion. We cannot remove it
+ # there because it is treated by other code as part of CookbookVersion's
+ # public API (also used in some deprecated methods).
+ COOKBOOK_SEGMENTS = [ :resources, :providers, :recipes, :definitions, :libraries, :attributes, :files, :templates, :root_files ].freeze
+
+ extend Forwardable
+
+ attr_reader :cookbook_version
+
+ def_delegator :@cookbook_version, :root_paths
+ def_delegator :@cookbook_version, :segment_filenames
+ def_delegator :@cookbook_version, :name
+ def_delegator :@cookbook_version, :metadata
+ def_delegator :@cookbook_version, :full_name
+ def_delegator :@cookbook_version, :version
+ def_delegator :@cookbook_version, :frozen_version?
+
+ # Create a new CookbookManifest object for the given `cookbook_version`.
+ # You can subsequently call #to_hash to get a Hash representation of the
+ # cookbook_version in the "manifest" format, or #to_json to get a JSON
+ # representation of the cookbook_version.
+ #
+ # The inferface for this behavior is expected to change as we implement new
+ # manifest formats. The entire class should be considered a private API for
+ # now.
+ #
+ # @api private
+ # @param policy_mode [Boolean] whether to convert cookbooks to Hash/JSON in
+ # the format used by the `cookbook_artifacts` endpoint (for policyfiles).
+ # Setting this option also changes the behavior of #save_url and
+ # #force_save_url such that CookbookVersions will be uploaded to the new
+ # `cookbook_artifacts` API. This endpoint is currently under active
+ # development and the format is expected to change frequently, therefore
+ # the result of #manifest, #to_hash, and #to_json will not be stable when
+ # `policy_mode` is enabled.
+ def initialize(cookbook_version, policy_mode: false)
+ @cookbook_version = cookbook_version
+ @policy_mode = !!policy_mode
+
+ reset!
+ end
+
+ # Resets all lazily computed values.
+ def reset!
+ @manifest = nil
+ @checksums = nil
+ @manifest_records_by_path = nil
+ true
+ end
+
+ # Returns a 'manifest' data structure that can be uploaded to a Chef
+ # Server.
+ #
+ # The format is as follows:
+ #
+ # {
+ # :cookbook_name => name, # String
+ # :metadata => metadata, # Chef::Cookbook::Metadata
+ # :version => version, # Chef::Version
+ # :name => full_name, # String of "#{name}-#{version}"
+ #
+ # :recipes => Array<FileSpec>,
+ # :definitions => Array<FileSpec>,
+ # :libraries => Array<FileSpec>,
+ # :attributes => Array<FileSpec>,
+ # :files => Array<FileSpec>,
+ # :templates => Array<FileSpec>,
+ # :resources => Array<FileSpec>,
+ # :providers => Array<FileSpec>,
+ # :root_files => Array<FileSpec>
+ # }
+ #
+ # Where a `FileSpec` is a Hash of the form:
+ #
+ # {
+ # :name => file_name,
+ # :path => path,
+ # :checksum => csum,
+ # :specificity => specificity
+ # }
+ #
+ def manifest
+ @manifest || generate_manifest
+ @manifest
+ end
+
+ def checksums
+ @manifest || generate_manifest
+ @checksums
+ end
+
+ def manifest_records_by_path
+ @manifest || generate_manifest
+ @manifest_records_by_path
+ end
+
+ def policy_mode?
+ @policy_mode
+ end
+
+ def to_hash
+ result = manifest.dup
+ result['frozen?'] = frozen_version?
+ result['chef_type'] = 'cookbook_version'
+ result.to_hash
+ end
+
+ def to_json(*a)
+ result = to_hash
+ result['json_class'] = "Chef::CookbookVersion"
+ Chef::JSONCompat.to_json(result, *a)
+ end
+
+ # Return the URL to save (PUT) this object to the server via the
+ # REST api. If there is an existing document on the server and it
+ # is marked frozen, a PUT will result in a 409 Conflict.
+ def save_url
+ "#{cookbook_url_path}/#{name}/#{version}"
+ end
+
+ # Adds the `force=true` parameter to the upload URL. This allows
+ # the user to overwrite a frozen cookbook (a PUT against the
+ # normal #save_url raises a 409 Conflict in this case).
+ def force_save_url
+ "#{save_url}?force=true"
+ end
+
+ # Update this CookbookManifest from the contents of another manifest, and
+ # make the corresponding changes to the cookbook_version object. Required
+ # to provide backward compatibility with CookbookVersion#manifest= method.
+ def update_from(new_manifest)
+ @manifest = Mash.new new_manifest
+ @checksums = extract_checksums_from_manifest(@manifest)
+ @manifest_records_by_path = extract_manifest_records_by_path(@manifest)
+
+ COOKBOOK_SEGMENTS.each do |segment|
+ next unless @manifest.has_key?(segment)
+ filenames = @manifest[segment].map{|manifest_record| manifest_record['name']}
+
+ cookbook_version.replace_segment_filenames(segment, filenames)
+ end
+ end
+
+ private
+
+ def cookbook_url_path
+ policy_mode? ? "cookbook_artifacts" : "cookbooks"
+ end
+
+ # See #manifest for a description of the manifest return value.
+ # See #preferred_manifest_record for a description an individual manifest record.
+ def generate_manifest
+ manifest = Mash.new({
+ :recipes => Array.new,
+ :definitions => Array.new,
+ :libraries => Array.new,
+ :attributes => Array.new,
+ :files => Array.new,
+ :templates => Array.new,
+ :resources => Array.new,
+ :providers => Array.new,
+ :root_files => Array.new
+ })
+ @checksums = {}
+
+ if !root_paths || root_paths.size == 0
+ Chef::Log.error("Cookbook #{name} does not have root_paths! Cannot generate manifest.")
+ raise "Cookbook #{name} does not have root_paths! Cannot generate manifest."
+ end
+
+ COOKBOOK_SEGMENTS.each do |segment|
+ segment_filenames(segment).each do |segment_file|
+ next if File.directory?(segment_file)
+
+ path, specificity = parse_segment_file_from_root_paths(segment, segment_file)
+ file_name = File.basename(path)
+
+ csum = checksum_cookbook_file(segment_file)
+ @checksums[csum] = segment_file
+ rs = Mash.new({
+ :name => file_name,
+ :path => path,
+ :checksum => csum,
+ :specificity => specificity
+ })
+
+ manifest[segment] << rs
+ end
+ end
+
+ manifest[:cookbook_name] = name.to_s
+ manifest[:metadata] = metadata
+ manifest[:version] = metadata.version
+ manifest[:name] = full_name
+
+ @manifest_records_by_path = extract_manifest_records_by_path(manifest)
+ @manifest = manifest
+ end
+
+ def parse_segment_file_from_root_paths(segment, segment_file)
+ root_paths.each do |root_path|
+ pathname = Chef::Util::PathHelper.relative_path_from(root_path, segment_file)
+
+ parts = pathname.each_filename.take(2)
+ # Check if path is actually under root_path
+ next if parts[0] == '..'
+ if segment == :templates || segment == :files
+ # Check if pathname looks like files/foo or templates/foo (unscoped)
+ if pathname.each_filename.to_a.length == 2
+ # Use root_default in case the same path exists at root_default and default
+ return [ pathname.to_s, 'root_default' ]
+ else
+ return [ pathname.to_s, parts[1] ]
+ end
+ else
+ return [ pathname.to_s, 'default' ]
+ end
+ end
+ Chef::Log.error("Cookbook file #{segment_file} not under cookbook root paths #{root_paths.inspect}.")
+ raise "Cookbook file #{segment_file} not under cookbook root paths #{root_paths.inspect}."
+ end
+
+ def extract_checksums_from_manifest(manifest)
+ checksums = {}
+ COOKBOOK_SEGMENTS.each do |segment|
+ next unless manifest.has_key?(segment)
+ manifest[segment].each do |manifest_record|
+ checksums[manifest_record[:checksum]] = nil
+ end
+ end
+ checksums
+ end
+
+ def checksum_cookbook_file(filepath)
+ CookbookVersion.checksum_cookbook_file(filepath)
+ end
+
+ def extract_manifest_records_by_path(manifest)
+ manifest_records_by_path = {}
+ COOKBOOK_SEGMENTS.each do |segment|
+ next unless manifest.has_key?(segment)
+ manifest[segment].each do |manifest_record|
+ manifest_records_by_path[manifest_record[:path]] = manifest_record
+ end
+ end
+ manifest_records_by_path
+ end
+ end
+end
diff --git a/lib/chef/cookbook_site_streaming_uploader.rb b/lib/chef/cookbook_site_streaming_uploader.rb
index c444c8251b..9e7a55c772 100644
--- a/lib/chef/cookbook_site_streaming_uploader.rb
+++ b/lib/chef/cookbook_site_streaming_uploader.rb
@@ -18,6 +18,7 @@
# limitations under the License.
#
+require 'uri'
require 'net/http'
require 'mixlib/authentication/signedheaderauth'
require 'openssl'
@@ -34,22 +35,22 @@ class Chef
class << self
- def create_build_dir(cookbook)
- tmp_cookbook_path = Tempfile.new("chef-#{cookbook.name}-build")
- tmp_cookbook_path.close
- tmp_cookbook_dir = tmp_cookbook_path.path
- File.unlink(tmp_cookbook_dir)
- FileUtils.mkdir_p(tmp_cookbook_dir)
- Chef::Log.debug("Staging at #{tmp_cookbook_dir}")
- checksums_to_on_disk_paths = cookbook.checksums
- Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment|
- cookbook.manifest[segment].each do |manifest_record|
- path_in_cookbook = manifest_record[:path]
- on_disk_path = checksums_to_on_disk_paths[manifest_record[:checksum]]
- dest = File.join(tmp_cookbook_dir, cookbook.name.to_s, path_in_cookbook)
- FileUtils.mkdir_p(File.dirname(dest))
- Chef::Log.debug("Staging #{on_disk_path} to #{dest}")
- FileUtils.cp(on_disk_path, dest)
+ def create_build_dir(cookbook)
+ tmp_cookbook_path = Tempfile.new("chef-#{cookbook.name}-build")
+ tmp_cookbook_path.close
+ tmp_cookbook_dir = tmp_cookbook_path.path
+ File.unlink(tmp_cookbook_dir)
+ FileUtils.mkdir_p(tmp_cookbook_dir)
+ Chef::Log.debug("Staging at #{tmp_cookbook_dir}")
+ checksums_to_on_disk_paths = cookbook.checksums
+ Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment|
+ cookbook.manifest[segment].each do |manifest_record|
+ path_in_cookbook = manifest_record[:path]
+ on_disk_path = checksums_to_on_disk_paths[manifest_record[:checksum]]
+ dest = File.join(tmp_cookbook_dir, cookbook.name.to_s, path_in_cookbook)
+ FileUtils.mkdir_p(File.dirname(dest))
+ Chef::Log.debug("Staging #{on_disk_path} to #{dest}")
+ FileUtils.cp(on_disk_path, dest)
end
end
@@ -86,13 +87,13 @@ class Chef
filepath = value.path
filename = File.basename(filepath)
parts << StringPart.new( "--" + boundary + "\r\n" +
- "Content-Disposition: form-data; name=\"" + key.to_s + "\"; filename=\"" + filename + "\"\r\n" +
- "Content-Type: application/octet-stream\r\n\r\n")
+ "Content-Disposition: form-data; name=\"" + key.to_s + "\"; filename=\"" + filename + "\"\r\n" +
+ "Content-Type: application/octet-stream\r\n\r\n")
parts << StreamPart.new(value, File.size(filepath))
parts << StringPart.new("\r\n")
else
parts << StringPart.new( "--" + boundary + "\r\n" +
- "Content-Disposition: form-data; name=\"" + key.to_s + "\"\r\n\r\n")
+ "Content-Disposition: form-data; name=\"" + key.to_s + "\"\r\n\r\n")
parts << StringPart.new(value.to_s + "\r\n")
end
end
@@ -243,10 +244,10 @@ class Chef
@part_offset = 0
next_part = read(how_much_next_part)
result = current_part + if next_part
- next_part
- else
- ''
- end
+ next_part
+ else
+ ''
+ end
else
@part_offset += how_much_current_part
result = current_part
diff --git a/lib/chef/cookbook_uploader.rb b/lib/chef/cookbook_uploader.rb
index 2d8bf5bc7e..f24ce2cd56 100644
--- a/lib/chef/cookbook_uploader.rb
+++ b/lib/chef/cookbook_uploader.rb
@@ -3,6 +3,7 @@ require 'set'
require 'chef/exceptions'
require 'chef/knife/cookbook_metadata'
require 'chef/digester'
+require 'chef/cookbook_manifest'
require 'chef/cookbook_version'
require 'chef/cookbook/syntax_check'
require 'chef/cookbook/file_system_file_vendor'
@@ -40,6 +41,7 @@ class Chef
@cookbooks = Array(cookbooks)
@rest = opts[:rest] || Chef::REST.new(Chef::Config[:chef_server_url])
@concurrency = opts[:concurrency] || 10
+ @policy_mode = opts[:policy_mode] || false
end
def upload_cookbooks
@@ -92,9 +94,12 @@ class Chef
# files are uploaded, so save the manifest
cookbooks.each do |cb|
- save_url = opts[:force] ? cb.force_save_url : cb.save_url
+
+ manifest = Chef::CookbookManifest.new(cb, policy_mode: policy_mode?)
+
+ save_url = opts[:force] ? manifest.force_save_url : manifest.save_url
begin
- rest.put(save_url, cb)
+ rest.put(save_url, manifest)
rescue Net::HTTPServerException => e
case e.response.code
when "409"
@@ -143,5 +148,9 @@ class Chef
end
end
+ def policy_mode?
+ @policy_mode
+ end
+
end
end
diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb
index 505b403e65..b8f32a61bb 100644
--- a/lib/chef/cookbook_version.rb
+++ b/lib/chef/cookbook_version.rb
@@ -23,9 +23,8 @@ require 'chef/log'
require 'chef/cookbook/file_vendor'
require 'chef/cookbook/metadata'
require 'chef/version_class'
-require 'pathname'
-require 'chef/monkey_patches/pathname'
require 'chef/digester'
+require 'chef/cookbook_manifest'
class Chef
@@ -34,10 +33,8 @@ class Chef
# cookbook. Chef supports maintaining multiple versions of a cookbook on a
# single server; each version is represented by a distinct instance of this
# class.
- #--
- # TODO: timh/cw: 5-24-2010: mutators for files (e.g., recipe_filenames=,
- # recipe_filenames.insert) should dirty the manifest so it gets regenerated.
class CookbookVersion
+
include Comparable
COOKBOOK_SEGMENTS = [ :resources, :providers, :recipes, :definitions, :libraries, :attributes, :files, :templates, :root_files ]
@@ -52,7 +49,16 @@ class Chef
attr_accessor :root_filenames
attr_accessor :name
attr_accessor :metadata_filenames
- attr_accessor :status
+
+ def status=(new_status)
+ Chef::Log.deprecation("Deprecated method `status' called from #{caller(1).first}. This method will be removed")
+ @status = new_status
+ end
+
+ def status
+ Chef::Log.deprecation("Deprecated method `status' called from #{caller(1).first}. This method will be removed")
+ @status
+ end
# A Chef::Cookbook::Metadata object. It has a setter that fixes up the
# metadata to add descriptions of the recipes contained in this
@@ -70,6 +76,8 @@ class Chef
attr_reader :recipe_filenames_by_name
attr_reader :attribute_filenames_by_short_filename
+ attr_accessor :chef_server_rest
+
# The first root path is the primary cookbook dir, from which metadata is loaded
def root_dir
root_paths[0]
@@ -92,10 +100,11 @@ class Chef
#
# === Returns
# object<Chef::CookbookVersion>:: Duh. :)
- def initialize(name, *root_paths)
+ def initialize(name, *root_paths, chef_server_rest: nil)
@name = name
@root_paths = root_paths
@frozen = false
+
@attribute_filenames = Array.new
@definition_filenames = Array.new
@template_filenames = Array.new
@@ -107,10 +116,12 @@ class Chef
@provider_filenames = Array.new
@metadata_filenames = Array.new
@root_filenames = Array.new
+
+ # deprecated
@status = :ready
- @manifest = nil
@file_vendor = nil
@metadata = Chef::Cookbook::Metadata.new
+ @chef_server_rest = chef_server_rest
end
def version
@@ -129,66 +140,10 @@ class Chef
end
def version=(new_version)
- manifest["version"] = new_version
+ cookbook_manifest.reset!
metadata.version(new_version)
end
- # A manifest is a Mash that maps segment names to arrays of manifest
- # records (see #preferred_manifest_record for format of manifest records),
- # as well as describing cookbook metadata. The manifest follows a form
- # like the following:
- #
- # {
- # :cookbook_name = "apache2",
- # :version = "1.0",
- # :name = "Apache 2"
- # :metadata = ???TODO: timh/cw: 5-24-2010: describe this format,
- #
- # :files => [
- # {
- # :name => "afile.rb",
- # :path => "files/ubuntu-9.10/afile.rb",
- # :checksum => "2222",
- # :specificity => "ubuntu-9.10"
- # },
- # ],
- # :templates => [ manifest_record1, ... ],
- # ...
- # }
- def manifest
- unless @manifest
- generate_manifest
- end
- @manifest
- end
-
- def manifest=(new_manifest)
- @manifest = Mash.new new_manifest
- @checksums = extract_checksums_from_manifest(@manifest)
- @manifest_records_by_path = extract_manifest_records_by_path(@manifest)
-
- COOKBOOK_SEGMENTS.each do |segment|
- next unless @manifest.has_key?(segment)
- filenames = @manifest[segment].map{|manifest_record| manifest_record['name']}
-
- replace_segment_filenames(segment, filenames)
- end
- end
-
- # Returns a hash of checksums to either nil or the on disk path (which is
- # done by generate_manifest).
- def checksums
- unless @checksums
- generate_manifest
- end
- @checksums
- end
-
- def manifest_records_by_path
- @manifest_records_by_path || generate_manifest
- @manifest_records_by_path
- end
-
def full_name
"#{name}-#{version}"
end
@@ -209,6 +164,24 @@ class Chef
alias :attribute_files :attribute_filenames
alias :attribute_files= :attribute_filenames=
+ def manifest
+ cookbook_manifest.manifest
+ end
+
+ # Returns a hash of checksums to either nil or the on disk path (which is
+ # done by generate_manifest).
+ def checksums
+ cookbook_manifest.checksums
+ end
+
+ def manifest_records_by_path
+ cookbook_manifest.manifest_records_by_path
+ end
+
+ def manifest=(new_manifest)
+ cookbook_manifest.update_from(new_manifest)
+ end
+
# Return recipe names in the form of cookbook_name::recipe_name
def fully_qualified_recipe_names
results = Array.new
@@ -311,7 +284,7 @@ class Chef
def preferred_manifest_record(node, segment, filename)
found_pref = find_preferred_manifest_record(node, segment, filename)
if found_pref
- @manifest_records_by_path[found_pref]
+ manifest_records_by_path[found_pref]
else
if segment == :files || segment == :templates
error_message = "Cookbook '#{name}' (#{version}) does not contain a file at any of these locations:\n"
@@ -472,19 +445,6 @@ class Chef
end
private :preferences_for_path
- def to_hash
- result = manifest.dup
- result['frozen?'] = frozen_version?
- result['chef_type'] = 'cookbook_version'
- result.to_hash
- end
-
- def to_json(*a)
- result = to_hash
- result['json_class'] = self.class.name
- Chef::JSONCompat.to_json(result, *a)
- end
-
def self.json_create(o)
cookbook_version = new(o["cookbook_name"])
# We want the Chef::Cookbook::Metadata object to always be inflated
@@ -498,7 +458,11 @@ class Chef
cookbook_version
end
+ # @deprecated This method was used by the Ruby Chef Server and is no longer
+ # needed. There is no replacement.
def generate_manifest_with_urls(&url_generator)
+ Chef::Log.deprecation("Deprecated method #generate_manifest_with_urls called from #{caller(1).first}")
+
rendered_manifest = manifest.dup
COOKBOOK_SEGMENTS.each do |segment|
if rendered_manifest.has_key?(segment)
@@ -511,6 +475,18 @@ class Chef
rendered_manifest
end
+
+ def to_hash
+ # TODO: this should become deprecated when the API for CookbookManifest becomes stable
+ cookbook_manifest.to_hash
+ end
+
+ def to_json(*a)
+ # TODO: this should become deprecated when the API for CookbookManifest becomes stable
+ cookbook_manifest.to_json
+ end
+
+
def metadata_json_file
File.join(root_paths[0], "metadata.json")
end
@@ -528,26 +504,23 @@ class Chef
##
# REST API
##
- def self.chef_server_rest
- Chef::REST.new(Chef::Config[:chef_server_url])
+
+ def save_url
+ # TODO: this should become deprecated when the API for CookbookManifest becomes stable
+ cookbook_manifest.save_url
end
- def chef_server_rest
- self.class.chef_server_rest
+ def force_save_url
+ # TODO: this should become deprecated when the API for CookbookManifest becomes stable
+ cookbook_manifest.force_save_url
end
- # Return the URL to save (PUT) this object to the server via the
- # REST api. If there is an existing document on the server and it
- # is marked frozen, a PUT will result in a 409 Conflict.
- def save_url
- "cookbooks/#{name}/#{version}"
+ def chef_server_rest
+ @chef_server_rest ||= self.chef_server_rest
end
- # Adds the `force=true` parameter to the upload URL. This allows
- # the user to overwrite a frozen cookbook (a PUT against the
- # normal #save_url raises a 409 Conflict in this case).
- def force_save_url
- "cookbooks/#{name}/#{version}?force=true"
+ def self.chef_server_rest
+ Chef::REST.new(Chef::Config[:chef_server_url])
end
def destroy
@@ -603,15 +576,15 @@ class Chef
private
+ def cookbook_manifest
+ @cookbook_manifest ||= CookbookManifest.new(self)
+ end
+
def find_preferred_manifest_record(node, segment, filename)
preferences = preferences_for_path(node, segment, filename)
- # ensure that we generate the manifest, which will also generate
- # @manifest_records_by_path
- manifest
-
# in order of prefernce, look for the filename in the manifest
- preferences.find {|preferred_filename| @manifest_records_by_path[preferred_filename] }
+ preferences.find {|preferred_filename| manifest_records_by_path[preferred_filename] }
end
# For each filename, produce a mapping of base filename (i.e. recipe name
@@ -620,80 +593,6 @@ class Chef
filenames.select{|filename| filename =~ /\.rb$/}.inject({}){|memo, filename| memo[File.basename(filename, '.rb')] = filename ; memo }
end
- # See #manifest for a description of the manifest return value.
- # See #preferred_manifest_record for a description an individual manifest record.
- def generate_manifest
- manifest = Mash.new({
- :recipes => Array.new,
- :definitions => Array.new,
- :libraries => Array.new,
- :attributes => Array.new,
- :files => Array.new,
- :templates => Array.new,
- :resources => Array.new,
- :providers => Array.new,
- :root_files => Array.new
- })
- checksums_to_on_disk_paths = {}
-
- if !root_paths || root_paths.size == 0
- Chef::Log.error("Cookbook #{name} does not have root_paths! Cannot generate manifest.")
- raise "Cookbook #{name} does not have root_paths! Cannot generate manifest."
- end
-
- COOKBOOK_SEGMENTS.each do |segment|
- segment_filenames(segment).each do |segment_file|
- next if File.directory?(segment_file)
-
- path, specificity = parse_segment_file_from_root_paths(segment, segment_file)
- file_name = File.basename(path)
-
- csum = self.class.checksum_cookbook_file(segment_file)
- checksums_to_on_disk_paths[csum] = segment_file
- rs = Mash.new({
- :name => file_name,
- :path => path,
- :checksum => csum,
- :specificity => specificity
- })
-
- manifest[segment] << rs
- end
- end
-
- manifest[:cookbook_name] = name.to_s
- manifest[:metadata] = metadata
- manifest[:version] = metadata.version
- manifest[:name] = full_name
-
- @checksums = checksums_to_on_disk_paths
- @manifest = manifest
- @manifest_records_by_path = extract_manifest_records_by_path(manifest)
- end
-
- def parse_segment_file_from_root_paths(segment, segment_file)
- root_paths.each do |root_path|
- pathname = Chef::Util::PathHelper.relative_path_from(root_path, segment_file)
-
- parts = pathname.each_filename.take(2)
- # Check if path is actually under root_path
- next if parts[0] == '..'
- if segment == :templates || segment == :files
- # Check if pathname looks like files/foo or templates/foo (unscoped)
- if pathname.each_filename.to_a.length == 2
- # Use root_default in case the same path exists at root_default and default
- return [ pathname.to_s, 'root_default' ]
- else
- return [ pathname.to_s, parts[1] ]
- end
- else
- return [ pathname.to_s, 'default' ]
- end
- end
- Chef::Log.error("Cookbook file #{segment_file} not under cookbook root paths #{root_paths.inspect}.")
- raise "Cookbook file #{segment_file} not under cookbook root paths #{root_paths.inspect}."
- end
-
def file_vendor
unless @file_vendor
@file_vendor = Chef::Cookbook::FileVendor.create_from_manifest(manifest)
@@ -701,27 +600,5 @@ class Chef
@file_vendor
end
- def extract_checksums_from_manifest(manifest)
- checksums = {}
- COOKBOOK_SEGMENTS.each do |segment|
- next unless manifest.has_key?(segment)
- manifest[segment].each do |manifest_record|
- checksums[manifest_record[:checksum]] = nil
- end
- end
- checksums
- end
-
- def extract_manifest_records_by_path(manifest)
- manifest_records_by_path = {}
- COOKBOOK_SEGMENTS.each do |segment|
- next unless manifest.has_key?(segment)
- manifest[segment].each do |manifest_record|
- manifest_records_by_path[manifest_record[:path]] = manifest_record
- end
- end
- manifest_records_by_path
- end
-
end
end
diff --git a/lib/chef/data_bag.rb b/lib/chef/data_bag.rb
index 528be3f2c4..8475774fa1 100644
--- a/lib/chef/data_bag.rb
+++ b/lib/chef/data_bag.rb
@@ -33,6 +33,8 @@ class Chef
VALID_NAME = /^[\.\-[:alnum:]_]+$/
+ attr_accessor :chef_server_rest
+
def self.validate_name!(name)
unless name =~ VALID_NAME
raise Exceptions::InvalidDataBagName, "DataBags must have a name matching #{VALID_NAME.inspect}, you gave #{name.inspect}"
@@ -40,8 +42,9 @@ class Chef
end
# Create a new Chef::DataBag
- def initialize
+ def initialize(chef_server_rest: nil)
@name = ''
+ @chef_server_rest = chef_server_rest
end
def name(arg=nil)
@@ -67,7 +70,7 @@ class Chef
end
def chef_server_rest
- Chef::REST.new(Chef::Config[:chef_server_url])
+ @chef_server_rest ||= Chef::REST.new(Chef::Config[:chef_server_url])
end
def self.chef_server_rest
diff --git a/lib/chef/data_bag_item.rb b/lib/chef/data_bag_item.rb
index 6f0ae65478..9f92e26c50 100644
--- a/lib/chef/data_bag_item.rb
+++ b/lib/chef/data_bag_item.rb
@@ -37,6 +37,8 @@ class Chef
VALID_ID = /^[\.\-[:alnum:]_]+$/
+ attr_accessor :chef_server_rest
+
def self.validate_id!(id_str)
if id_str.nil? || ( id_str !~ VALID_ID )
raise Exceptions::InvalidDataBagItemID, "Data Bag items must have an id matching #{VALID_ID.inspect}, you gave: #{id_str.inspect}"
@@ -49,13 +51,14 @@ class Chef
attr_reader :raw_data
# Create a new Chef::DataBagItem
- def initialize
+ def initialize(chef_server_rest: nil)
@data_bag = nil
@raw_data = Mash.new
+ @chef_server_rest = chef_server_rest
end
def chef_server_rest
- Chef::REST.new(Chef::Config[:chef_server_url])
+ @chef_server_rest ||= Chef::REST.new(Chef::Config[:chef_server_url])
end
def self.chef_server_rest
@@ -158,7 +161,7 @@ class Chef
end
end
- def destroy(data_bag=data_bag, databag_item=name)
+ def destroy(data_bag=data_bag(), databag_item=name)
chef_server_rest.delete_rest("data/#{data_bag}/#{databag_item}")
end
diff --git a/lib/chef/deprecation/warnings.rb b/lib/chef/deprecation/warnings.rb
index 22b28f93b0..34f468ff53 100644
--- a/lib/chef/deprecation/warnings.rb
+++ b/lib/chef/deprecation/warnings.rb
@@ -24,9 +24,11 @@ class Chef
method_names.each do |name|
m = instance_method(name)
define_method(name) do |*args|
- Chef::Log.warn "Method '#{name}' of '#{self.class}' is deprecated. It will be removed in Chef 12."
- Chef::Log.warn "Please update your cookbooks accordingly. Accessed from:"
- caller[0..3].each {|l| Chef::Log.warn l}
+ message = []
+ message << "Method '#{name}' of '#{self.class}' is deprecated. It will be removed in Chef 12."
+ message << "Please update your cookbooks accordingly. Accessed from:"
+ caller[0..3].each {|l| message << l}
+ Chef::Log.deprecation message
super(*args)
end
end
@@ -35,4 +37,3 @@ class Chef
end
end
end
-
diff --git a/lib/chef/dsl/audit.rb b/lib/chef/dsl/audit.rb
new file mode 100644
index 0000000000..d1bf09b313
--- /dev/null
+++ b/lib/chef/dsl/audit.rb
@@ -0,0 +1,51 @@
+#
+# Author:: Tyler Ball (<tball@getchef.com>)
+# Copyright:: Copyright (c) 2014 Opscode, 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/exceptions'
+
+class Chef
+ module DSL
+ module Audit
+
+ # Can encompass tests in a `control` block or `describe` block
+ # Adds the controls group and block (containing controls to execute) to the runner's list of pending examples
+ def control_group(*args, &block)
+ raise Chef::Exceptions::NoAuditsProvided unless block
+
+ name = args[0]
+ if name.nil? || name.empty?
+ raise Chef::Exceptions::AuditNameMissing
+ elsif run_context.audits.has_key?(name)
+ raise Chef::Exceptions::AuditControlGroupDuplicate.new(name)
+ end
+
+ # This DSL will only work in the Recipe class because that exposes the cookbook_name
+ cookbook_name = self.cookbook_name
+ metadata = {
+ cookbook_name: cookbook_name,
+ cookbook_version: self.run_context.cookbook_collection[cookbook_name].version,
+ recipe_name: self.recipe_name,
+ line_number: block.source_location[1]
+ }
+
+ run_context.audits[name] = Struct.new(:args, :block, :metadata).new(args, block, metadata)
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/dsl/include_recipe.rb b/lib/chef/dsl/include_recipe.rb
index fc95e38c75..5ea1075e67 100644
--- a/lib/chef/dsl/include_recipe.rb
+++ b/lib/chef/dsl/include_recipe.rb
@@ -23,11 +23,11 @@ class Chef
module IncludeRecipe
def include_recipe(*recipe_names)
- run_context.include_recipe(*recipe_names)
+ run_context.include_recipe(*recipe_names, current_cookbook: cookbook_name)
end
def load_recipe(recipe_name)
- run_context.load_recipe(recipe_name)
+ run_context.load_recipe(recipe_name, current_cookbook: cookbook_name)
end
def require_recipe(*args)
@@ -42,4 +42,3 @@ end
# **DEPRECATED**
# This used to be part of chef/mixin/language_include_recipe. Load the file to activate the deprecation code.
require 'chef/mixin/language_include_recipe'
-
diff --git a/lib/chef/dsl/reboot_pending.rb b/lib/chef/dsl/reboot_pending.rb
index a81debce99..7af67e94a5 100644
--- a/lib/chef/dsl/reboot_pending.rb
+++ b/lib/chef/dsl/reboot_pending.rb
@@ -47,7 +47,7 @@ class Chef
# Vista + Server 2008 and newer may have reboots pending from CBS
registry_key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired') ||
- # The mere existance of the UpdateExeVolatile key should indicate a pending restart for certain updates
+ # The mere existence of the UpdateExeVolatile key should indicate a pending restart for certain updates
# http://support.microsoft.com/kb/832475
(registry_key_exists?('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile') &&
!registry_get_values('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile').select { |v| v[:name] == "Flags" }[0].nil? &&
diff --git a/lib/chef/dsl/recipe.rb b/lib/chef/dsl/recipe.rb
index d70266c14c..7b467fd867 100644
--- a/lib/chef/dsl/recipe.rb
+++ b/lib/chef/dsl/recipe.rb
@@ -19,6 +19,7 @@
require 'chef/mixin/convert_to_class_name'
require 'chef/exceptions'
+require 'chef/resource_builder'
class Chef
module DSL
@@ -72,10 +73,31 @@ class Chef
new_recipe.instance_eval(&new_def.recipe)
end
+ #
# Instantiates a resource (via #build_resource), then adds it to the
# resource collection. Note that resource classes are looked up directly,
# so this will create the resource you intended even if the method name
# corresponding to that resource has been overridden.
+ #
+ # @param type [Symbol] The type of resource (e.g. `:file` or `:package`)
+ # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2')
+ # @param created_at [String] The caller of the resource. Use `caller[0]`
+ # to get the caller of your function. Defaults to the caller of this
+ # function.
+ # @param resource_attrs_block A block that lets you set attributes of the
+ # resource (it is instance_eval'd on the resource instance).
+ #
+ # @return [Chef::Resource] The new resource.
+ #
+ # @example
+ # declare_resource(:file, '/x/y.txy', caller[0]) do
+ # action :delete
+ # end
+ # # Equivalent to
+ # file '/x/y.txt' do
+ # action :delete
+ # end
+ #
def declare_resource(type, name, created_at=nil, &resource_attrs_block)
created_at ||= caller[0]
@@ -85,44 +107,40 @@ class Chef
resource
end
+ #
# Instantiate a resource of the given +type+ with the given +name+ and
# attributes as given in the +resource_attrs_block+.
#
# The resource is NOT added to the resource collection.
+ #
+ # @param type [Symbol] The type of resource (e.g. `:file` or `:package`)
+ # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2')
+ # @param created_at [String] The caller of the resource. Use `caller[0]`
+ # to get the caller of your function. Defaults to the caller of this
+ # function.
+ # @param resource_attrs_block A block that lets you set attributes of the
+ # resource (it is instance_eval'd on the resource instance).
+ #
+ # @return [Chef::Resource] The new resource.
+ #
+ # @example
+ # build_resource(:file, '/x/y.txy', caller[0]) do
+ # action :delete
+ # end
+ #
def build_resource(type, name, created_at=nil, &resource_attrs_block)
created_at ||= caller[0]
- # Checks the new platform => short_name => resource mapping initially
- # then fall back to the older approach (Chef::Resource.const_get) for
- # backward compatibility
- resource_class = resource_class_for(type)
-
- raise ArgumentError, "You must supply a name when declaring a #{type} resource" if name.nil?
-
- resource = resource_class.new(name, run_context)
- resource.source_line = created_at
- resource.declared_type = type
- # If we have a resource like this one, we want to steal its state
- # This behavior is very counter-intuitive and should be removed.
- # See CHEF-3694, https://tickets.opscode.com/browse/CHEF-3694
- # Moved to this location to resolve CHEF-5052, https://tickets.opscode.com/browse/CHEF-5052
- resource.load_prior_resource(type, name)
- resource.cookbook_name = cookbook_name
- resource.recipe_name = recipe_name
- # Determine whether this resource is being created in the context of an enclosing Provider
- resource.enclosing_provider = self.is_a?(Chef::Provider) ? self : nil
-
- # XXX: This is very crufty, but it's required for resource definitions
- # to work properly :(
- resource.params = @params
-
- # Evaluate resource attribute DSL
- resource.instance_eval(&resource_attrs_block) if block_given?
-
- # Run optional resource hook
- resource.after_created
-
- resource
+ Chef::ResourceBuilder.new(
+ type: type,
+ name: name,
+ created_at: created_at,
+ params: @params,
+ run_context: run_context,
+ cookbook_name: cookbook_name,
+ recipe_name: recipe_name,
+ enclosing_provider: self.is_a?(Chef::Provider) ? self : nil
+ ).build(&resource_attrs_block)
end
def resource_class_for(snake_case_name)
diff --git a/lib/chef/encrypted_data_bag_item/assertions.rb b/lib/chef/encrypted_data_bag_item/assertions.rb
index 0f9416e7b6..ab93f46c10 100644
--- a/lib/chef/encrypted_data_bag_item/assertions.rb
+++ b/lib/chef/encrypted_data_bag_item/assertions.rb
@@ -44,9 +44,6 @@ class Chef::EncryptedDataBagItem
end
def assert_aead_requirements_met!(algorithm)
- unless OpenSSL::Cipher.method_defined?(:auth_data=)
- raise EncryptedDataBagRequirementsFailure, "The used Encrypted Data Bags version requires Ruby >= 2.0"
- end
unless OpenSSL::Cipher.ciphers.include?(algorithm)
raise EncryptedDataBagRequirementsFailure, "The used Encrypted Data Bags version requires an OpenSSL version with \"#{algorithm}\" algorithm support"
end
diff --git a/lib/chef/environment.rb b/lib/chef/environment.rb
index 33dfb52403..7d4b410639 100644
--- a/lib/chef/environment.rb
+++ b/lib/chef/environment.rb
@@ -33,18 +33,21 @@ class Chef
include Chef::Mixin::ParamsValidate
include Chef::Mixin::FromFile
+ attr_accessor :chef_server_rest
+
COMBINED_COOKBOOK_CONSTRAINT = /(.+)(?:[\s]+)((?:#{Chef::VersionConstraint::OPS.join('|')})(?:[\s]+).+)$/.freeze
- def initialize
+ def initialize(chef_server_rest: nil)
@name = ''
@description = ''
@default_attributes = Mash.new
@override_attributes = Mash.new
@cookbook_versions = Hash.new
+ @chef_server_rest = chef_server_rest
end
def chef_server_rest
- Chef::REST.new(Chef::Config[:chef_server_url])
+ @chef_server_rest ||= Chef::REST.new(Chef::Config[:chef_server_url])
end
def self.chef_server_rest
diff --git a/lib/chef/event_dispatch/base.rb b/lib/chef/event_dispatch/base.rb
index bfd4503097..7274105802 100644
--- a/lib/chef/event_dispatch/base.rb
+++ b/lib/chef/event_dispatch/base.rb
@@ -193,7 +193,7 @@ class Chef
def definition_file_load_failed(path, exception)
end
- # Called when resource defintions are done loading
+ # Called when resource definitions are done loading
def definition_load_complete
end
@@ -225,6 +225,41 @@ class Chef
def converge_complete
end
+ # Called if the converge phase fails
+ def converge_failed(exception)
+ end
+
+ ##################################
+ # Audit Mode Events
+ # This phase is currently experimental and these event APIs are subject to change
+ ##################################
+
+ # Called before audit phase starts
+ def audit_phase_start(run_status)
+ end
+
+ # Called when audit phase successfully finishes
+ def audit_phase_complete
+ end
+
+ # Called if there is an uncaught exception during the audit phase. The audit runner should
+ # be catching and handling errors from the examples, so this is only uncaught errors (like
+ # bugs in our handling code)
+ def audit_phase_failed(exception)
+ end
+
+ # Signifies the start of a `control_group` block with a defined name
+ def control_group_started(name)
+ end
+
+ # An example in a `control_group` block completed successfully
+ def control_example_success(control_group_name, example_data)
+ end
+
+ # An example in a `control_group` block failed with the provided error
+ def control_example_failure(control_group_name, example_data, error)
+ end
+
# TODO: need events for notification resolve?
# def notifications_resolved
# end
diff --git a/lib/chef/event_dispatch/dispatcher.rb b/lib/chef/event_dispatch/dispatcher.rb
index c172a406d8..9f43f14311 100644
--- a/lib/chef/event_dispatch/dispatcher.rb
+++ b/lib/chef/event_dispatch/dispatcher.rb
@@ -25,11 +25,9 @@ class Chef
# Define a method that will be forwarded to all
def self.def_forwarding_method(method_name)
- class_eval(<<-END_OF_METHOD, __FILE__, __LINE__)
- def #{method_name}(*args)
- @subscribers.each {|s| s.#{method_name}(*args)}
- end
- END_OF_METHOD
+ define_method(method_name) do |*args|
+ @subscribers.each { |s| s.send(method_name, *args) }
+ end
end
(Base.instance_methods - Object.instance_methods).each do |method_name|
diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb
index 5ef51d5381..ecd84c5ba5 100644
--- a/lib/chef/exceptions.rb
+++ b/lib/chef/exceptions.rb
@@ -45,6 +45,7 @@ class Chef
class FileNotFound < RuntimeError; end
class Package < RuntimeError; end
class Service < RuntimeError; end
+ class Script < RuntimeError; end
class Route < RuntimeError; end
class SearchIndex < RuntimeError; end
class Override < RuntimeError; end
@@ -89,6 +90,7 @@ class Chef
class ConflictingMembersInGroup < ArgumentError; end
class InvalidResourceReference < RuntimeError; end
class ResourceNotFound < RuntimeError; end
+ class VerificationNotFound < RuntimeError; end
# Can't find a Resource of this type that is valid on this platform.
class NoSuchResourceType < NameError
@@ -123,6 +125,7 @@ class Chef
class DuplicateDataBagItem < RuntimeError; end
class PowershellCmdletException < RuntimeError; end
+ class LCMParser < RuntimeError; end
class CannotDetermineHomebrewOwner < Package; end
@@ -210,6 +213,12 @@ class Chef
class NoProviderAvailable < RuntimeError; end
+ class DeprecatedFeatureError < RuntimeError;
+ def initalize(message)
+ super("#{message} (raising error due to treat_deprecation_warnings_as_errors being set)")
+ end
+ end
+
class MissingRole < RuntimeError
NULL = Object.new
@@ -387,5 +396,51 @@ class Chef
super "Found more than one provider for #{resource.resource_name} resource: #{classes}"
end
end
+
+ class AuditControlGroupDuplicate < RuntimeError
+ def initialize(name)
+ super "Audit control group with name '#{name}' has already been defined"
+ end
+ end
+ class AuditNameMissing < RuntimeError; end
+ class NoAuditsProvided < RuntimeError
+ def initialize
+ super "You must provide a block with audits"
+ end
+ end
+ class AuditsFailed < RuntimeError
+ def initialize(num_failed, num_total)
+ super "Audit phase found failures - #{num_failed}/#{num_total} audits failed"
+ end
+ end
+
+ # If a converge or audit fails, we want to wrap the output from those errors into 1 error so we can
+ # see both issues in the output. It is possible that nil will be provided. You must call `fill_backtrace`
+ # to correctly populate the backtrace with the wrapped backtraces.
+ class RunFailedWrappingError < RuntimeError
+ attr_reader :wrapped_errors
+ def initialize(*errors)
+ errors = errors.select {|e| !e.nil?}
+ output = "Found #{errors.size} errors, they are stored in the backtrace"
+ @wrapped_errors = errors
+ super output
+ end
+
+ def fill_backtrace
+ backtrace = []
+ wrapped_errors.each_with_index do |e,i|
+ backtrace << "#{i+1}) #{e.class} - #{e.message}"
+ backtrace += e.backtrace if e.backtrace
+ backtrace << ""
+ end
+ set_backtrace(backtrace)
+ end
+ end
+
+ class PIDFileLockfileMatch < RuntimeError
+ def initialize
+ super "PID file and lockfile are not permitted to match. Specify a different location with --pid or --lockfile"
+ end
+ end
end
end
diff --git a/lib/chef/file_access_control/unix.rb b/lib/chef/file_access_control/unix.rb
index a5d177d47d..472f30b752 100644
--- a/lib/chef/file_access_control/unix.rb
+++ b/lib/chef/file_access_control/unix.rb
@@ -26,6 +26,18 @@ class Chef
UINT = (1 << 32)
UID_MAX = (1 << 32) - 10
+ module ClassMethods
+ # We want to mix these in as class methods
+ def writable?(path)
+ ::File.writable?(path)
+ end
+ end
+
+ def self.included(base)
+ # When this file is mixed in, make sure we also add the class methods
+ base.send :extend, ClassMethods
+ end
+
def set_all!
set_owner!
set_group!
diff --git a/lib/chef/file_access_control/windows.rb b/lib/chef/file_access_control/windows.rb
index 32ac2996bd..1781a6fa63 100644
--- a/lib/chef/file_access_control/windows.rb
+++ b/lib/chef/file_access_control/windows.rb
@@ -18,6 +18,7 @@
#
require 'chef/win32/security'
+require 'chef/win32/file'
class Chef
class FileAccessControl
@@ -29,6 +30,19 @@ class Chef
ACE = Security::ACE
SID = Security::SID
+ module ClassMethods
+ # We want to mix these in as class methods
+ def writable?(path)
+ ::File.exists?(path) && Chef::ReservedNames::Win32::File.file_access_check(
+ path, Chef::ReservedNames::Win32::API::Security::FILE_GENERIC_WRITE)
+ end
+ end
+
+ def self.included(base)
+ # When this file is mixed in, make sure we also add the class methods
+ base.send :extend, ClassMethods
+ end
+
def set_all!
set_owner!
set_group!
diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb
index 4a08b9d095..489888db8f 100644
--- a/lib/chef/formatters/doc.rb
+++ b/lib/chef/formatters/doc.rb
@@ -8,7 +8,9 @@ class Chef
# "specdoc"
class Doc < Formatters::Base
- attr_reader :start_time, :end_time
+ attr_reader :start_time, :end_time, :successful_audits, :failed_audits
+ private :successful_audits, :failed_audits
+
cli_name(:doc)
def initialize(out, err)
@@ -16,6 +18,8 @@ class Chef
@updated_resources = 0
@up_to_date_resources = 0
+ @successful_audits = 0
+ @failed_audits = 0
@start_time = Time.now
@end_time = @start_time
end
@@ -32,12 +36,19 @@ class Chef
@up_to_date_resources + @updated_resources
end
+ def total_audits
+ successful_audits + failed_audits
+ end
+
def run_completed(node)
@end_time = Time.now
if Chef::Config[:why_run]
puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources would have been updated"
else
puts_line "Chef Client finished, #{@updated_resources}/#{total_resources} resources updated in #{elapsed_time} seconds"
+ if total_audits > 0
+ puts_line " #{successful_audits}/#{total_audits} Audits succeeded"
+ end
end
end
@@ -47,6 +58,9 @@ class Chef
puts_line "Chef Client failed. #{@updated_resources} resources would have been updated"
else
puts_line "Chef Client failed. #{@updated_resources} resources updated in #{elapsed_time} seconds"
+ if total_audits > 0
+ puts_line " #{successful_audits} Audits succeeded"
+ end
end
end
@@ -151,6 +165,38 @@ class Chef
unindent if @current_recipe
end
+ def converge_failed(e)
+ # Currently a failed converge is handled the same way as a successful converge
+ converge_complete
+ end
+
+ # Called before audit phase starts
+ def audit_phase_start(run_status)
+ puts_line "Starting audit phase"
+ end
+
+ def audit_phase_complete
+ puts_line "Auditing complete"
+ end
+
+ def audit_phase_failed(error)
+ puts_line ""
+ puts_line "Audit phase exception:"
+ indent
+ puts_line "#{error.message}"
+ error.backtrace.each do |l|
+ puts_line l
+ end
+ end
+
+ def control_example_success(control_group_name, example_data)
+ @successful_audits += 1
+ end
+
+ def control_example_failure(control_group_name, example_data, error)
+ @failed_audits += 1
+ end
+
# Called before action is executed on a resource.
def resource_action_start(resource, action, notification_type=nil, notifier=nil)
if resource.cookbook_name && resource.recipe_name
diff --git a/spec/unit/monkey_patches/string_spec.rb b/lib/chef/guard_interpreter.rb
index 8c6710b38e..b968f273b9 100644
--- a/spec/unit/monkey_patches/string_spec.rb
+++ b/lib/chef/guard_interpreter.rb
@@ -1,6 +1,6 @@
#
-# Author:: Devin Ben-Hur <dbenhur@whitepages.com>
-# Copyright:: Copyright (c) 2008, 2011 Opscode, Inc.
+# Author:: Steven Danna (<steve@chef.io>)
+# Copyright:: Copyright (c) 2015 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,22 +16,17 @@
# limitations under the License.
#
-require 'spec_helper'
-require 'chef/monkey_patches/string'
+require 'chef/guard_interpreter/default_guard_interpreter'
+require 'chef/guard_interpreter/resource_guard_interpreter'
-describe String do
-
- describe "#ord" do
- it "converts each ASCII-8BIT character to corresponding positive Fixnum" do
- (0..0xff).each do |num|
- ch = num.chr
- ch.force_encoding('ASCII-8BIT') if ch.respond_to? :force_encoding
-
- ch.ord.should be_a_kind_of(Fixnum)
- ch.ord.should == num
+class Chef
+ class GuardInterpreter
+ def self.for_resource(resource, command, command_opts)
+ if resource.guard_interpreter == :default
+ Chef::GuardInterpreter::DefaultGuardInterpreter.new(command, command_opts)
+ else
+ Chef::GuardInterpreter::ResourceGuardInterpreter.new(resource, command, command_opts)
end
end
-
end
-
end
diff --git a/lib/chef/guard_interpreter/resource_guard_interpreter.rb b/lib/chef/guard_interpreter/resource_guard_interpreter.rb
index 346b585d8c..1e2a534c18 100644
--- a/lib/chef/guard_interpreter/resource_guard_interpreter.rb
+++ b/lib/chef/guard_interpreter/resource_guard_interpreter.rb
@@ -16,7 +16,7 @@
# limitations under the License.
#
-require 'chef/guard_interpreter/default_guard_interpreter'
+require 'chef/guard_interpreter'
class Chef
class GuardInterpreter
@@ -41,7 +41,7 @@ class Chef
# attribute by checking the type of the resources.
# We need to make sure we check for Script first because any resource
# that can get to here is an Execute resource.
- if @parent_resource.is_a? Chef::Resource::Script
+ if @resource.is_a? Chef::Resource::Script
block_attributes = @command_opts.merge({:code => @command})
else
block_attributes = @command_opts.merge({:command => @command})
@@ -95,6 +95,7 @@ class Chef
empty_events = Chef::EventDispatch::Dispatcher.new
anonymous_run_context = Chef::RunContext.new(parent_resource.node, {}, empty_events)
interpreter_resource = resource_class.new('Guard resource', anonymous_run_context)
+ interpreter_resource.is_guard_interpreter = true
interpreter_resource
end
diff --git a/lib/chef/http.rb b/lib/chef/http.rb
index ee951bd675..5e52337aff 100644
--- a/lib/chef/http.rb
+++ b/lib/chef/http.rb
@@ -25,7 +25,6 @@ require 'tempfile'
require 'net/https'
require 'uri'
require 'chef/http/basic_client'
-require 'chef/monkey_patches/string'
require 'chef/monkey_patches/net_http'
require 'chef/config'
require 'chef/platform/query_helpers'
@@ -204,7 +203,7 @@ class Chef
def create_url(path)
return path if path.is_a?(URI)
- if path =~ /^(http|https):\/\//
+ if path =~ /^(http|https):\/\//i
URI.parse(path)
elsif path.nil? or path.empty?
URI.parse(@url)
diff --git a/lib/chef/knife.rb b/lib/chef/knife.rb
index 9caf863c57..e13f80b5a8 100644
--- a/lib/chef/knife.rb
+++ b/lib/chef/knife.rb
@@ -53,6 +53,7 @@ class Chef
def_delegator :@ui, :format_for_display
def_delegator :@ui, :format_cookbook_list_for_display
def_delegator :@ui, :edit_data
+ def_delegator :@ui, :edit_hash
def_delegator :@ui, :edit_object
def_delegator :@ui, :confirm
@@ -260,7 +261,7 @@ class Chef
OFFICIAL_PLUGINS = %w[ec2 rackspace windows openstack terremark bluebox]
# :nodoc:
- # Error out and print usage. probably becuase the arguments given by the
+ # 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 sub command for: '#{args.join(' ')}'")
@@ -269,7 +270,8 @@ class Chef
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("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
@@ -308,7 +310,7 @@ class Chef
exit 1
end
- # copy Mixlib::CLI over so that it cab be configured in knife.rb
+ # copy Mixlib::CLI over so that it can be configured in knife.rb
# config file
Chef::Config[:verbosity] = config[:verbosity]
end
diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb
index 19a329199d..f23c15fa70 100644
--- a/lib/chef/knife/bootstrap.rb
+++ b/lib/chef/knife/bootstrap.rb
@@ -19,12 +19,17 @@
require 'chef/knife'
require 'chef/knife/data_bag_secret_options'
require 'erubis'
+require 'chef/knife/bootstrap/chef_vault_handler'
+require 'chef/knife/bootstrap/client_builder'
class Chef
class Knife
class Bootstrap < Knife
include DataBagSecretOptions
+ attr_accessor :client_builder
+ attr_accessor :chef_vault_handler
+
deps do
require 'chef/knife/core/bootstrap_context'
require 'chef/json_compat'
@@ -194,10 +199,55 @@ class Chef
:description => "Verify the SSL cert for HTTPS requests to the Chef server API.",
:boolean => true
+ option :bootstrap_vault_file,
+ :long => '--bootstrap-vault-file VAULT_FILE',
+ :description => 'A JSON file with a list of vault(s) and item(s) to be updated'
+
+ option :bootstrap_vault_json,
+ :long => '--bootstrap-vault-json VAULT_JSON',
+ :description => 'A JSON string with the vault(s) and item(s) to be updated'
+
+ option :bootstrap_vault_item,
+ :long => '--bootstrap-vault-item VAULT_ITEM',
+ :description => 'A single vault and item to update as "vault:item"',
+ :proc => Proc.new { |i|
+ (vault, item) = i.split(/:/)
+ Chef::Config[:knife][:bootstrap_vault_item] ||= {}
+ Chef::Config[:knife][:bootstrap_vault_item][vault] ||= []
+ Chef::Config[:knife][:bootstrap_vault_item][vault].push(item)
+ Chef::Config[:knife][:bootstrap_vault_item]
+ }
+
+ def initialize(argv=[])
+ super
+ @client_builder = Chef::Knife::Bootstrap::ClientBuilder.new(
+ chef_config: Chef::Config,
+ knife_config: config,
+ ui: ui,
+ )
+ @chef_vault_handler = Chef::Knife::Bootstrap::ChefVaultHandler.new(
+ knife_config: config,
+ ui: ui
+ )
+ end
+
+ # The default bootstrap template to use to bootstrap a server This is a public API hook
+ # which knife plugins use or inherit and override.
+ #
+ # @return [String] Default bootstrap template
def default_bootstrap_template
"chef-full"
end
+ # The server_name is the DNS or IP we are going to connect to, it is not necessarily
+ # the node name, the fqdn, or the hostname of the server. This is a public API hook
+ # which knife plugins use or inherit and override.
+ #
+ # @return [String] The DNS or IP that bootstrap will connect to
+ def server_name
+ Array(@name_args).first
+ end
+
def bootstrap_template
# The order here is important. We want to check if we have the new Chef 12 option is set first.
# Knife cloud plugins unfortunately all set a default option for the :distro so it should be at
@@ -216,7 +266,7 @@ class Chef
# Otherwise search the template directories until we find the right one
bootstrap_files = []
- bootstrap_files << File.join(File.dirname(__FILE__), 'bootstrap', "#{template}.erb")
+ bootstrap_files << File.join(File.dirname(__FILE__), 'bootstrap/templates', "#{template}.erb")
bootstrap_files << File.join(Knife.chef_config_dir, "bootstrap", "#{template}.erb") if Chef::Knife.chef_config_dir
bootstrap_files << File.join(ENV['HOME'], '.chef', 'bootstrap', "#{template}.erb") if ENV['HOME']
bootstrap_files << Gem.find_files(File.join("chef","knife","bootstrap","#{template}.erb"))
@@ -237,20 +287,45 @@ class Chef
template_file
end
+ def secret
+ @secret ||= encryption_secret_provided_ignore_encrypt_flag? ? read_secret : nil
+ end
+
+ def bootstrap_context
+ @bootstrap_context ||= Knife::Core::BootstrapContext.new(
+ config,
+ config[:run_list],
+ Chef::Config,
+ secret
+ )
+ end
+
def render_template
template_file = find_template
template = IO.read(template_file).chomp
- secret = encryption_secret_provided_ignore_encrypt_flag? ? read_secret : nil
- context = Knife::Core::BootstrapContext.new(config, config[:run_list], Chef::Config, secret)
- Erubis::Eruby.new(template).evaluate(context)
+ Erubis::Eruby.new(template).evaluate(bootstrap_context)
end
def run
validate_name_args!
- @node_name = Array(@name_args).first
$stdout.sync = true
- ui.info("Connecting to #{ui.color(@node_name, :bold)}")
+
+ # chef-vault integration must use the new client-side hawtness, otherwise to use the
+ # new client-side hawtness, just delete your validation key.
+ if chef_vault_handler.doing_chef_vault? || !File.exist?(File.expand_path(Chef::Config[:validation_key]))
+ client_builder.run
+
+ chef_vault_handler.run(node_name: config[:chef_node_name])
+
+ bootstrap_context.client_pem = client_builder.client_path
+ else
+ ui.info("Doing old-style registration with the validation key at #{Chef::Config[:validation_key]}...")
+ ui.info("Delete your validation key in order to use your user credentials instead")
+ ui.info("")
+ end
+
+ ui.info("Connecting to #{ui.color(server_name, :bold)}")
begin
knife_ssh.run
@@ -265,24 +340,19 @@ class Chef
end
def validate_name_args!
- if Array(@name_args).first.nil?
+ if server_name.nil?
ui.error("Must pass an FQDN or ip to bootstrap")
exit 1
- elsif Array(@name_args).first == "windows"
+ elsif server_name == "windows"
+ # catches "knife bootstrap windows" when that command is not installed
ui.warn("Hostname containing 'windows' specified. Please install 'knife-windows' if you are attempting to bootstrap a Windows node via WinRM.")
end
end
- def server_name
- Array(@name_args).first
- end
-
def knife_ssh
ssh = Chef::Knife::Ssh.new
ssh.ui = ui
ssh.name_args = [ server_name, ssh_command ]
-
- # command line arguments and config file values are now merged into config in Chef::Knife#merge_configs
ssh.config[:ssh_user] = config[:ssh_user]
ssh.config[:ssh_password] = config[:ssh_password]
ssh.config[:ssh_port] = config[:ssh_port]
@@ -311,7 +381,6 @@ class Chef
command
end
-
end
end
end
diff --git a/lib/chef/knife/bootstrap/chef_vault_handler.rb b/lib/chef/knife/bootstrap/chef_vault_handler.rb
new file mode 100644
index 0000000000..749f61e6da
--- /dev/null
+++ b/lib/chef/knife/bootstrap/chef_vault_handler.rb
@@ -0,0 +1,165 @@
+#
+# Author:: Lamont Granquist (<lamont@chef.io>)
+# Copyright:: Copyright (c) 2015 Opscode, 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.
+#
+
+class Chef
+ class Knife
+ class Bootstrap < Knife
+ class ChefVaultHandler
+
+ # @return [Hash] knife merged config, typically @config
+ attr_accessor :knife_config
+
+ # @return [Chef::Knife::UI] ui object for output
+ attr_accessor :ui
+
+ # @return [String] name of the node (technically name of the client)
+ attr_reader :node_name
+
+ # @param knife_config [Hash] knife merged config, typically @config
+ # @param ui [Chef::Knife::UI] ui object for output
+ def initialize(knife_config: {}, ui: nil)
+ @knife_config = knife_config
+ @ui = ui
+ end
+
+ # Updates the chef vault items for the newly created node.
+ #
+ # @param node_name [String] name of the node (technically name of the client)
+ # @todo: node_name should be mandatory (ruby 2.0 compat)
+ def run(node_name: nil)
+ return unless doing_chef_vault?
+
+ sanity_check
+
+ @node_name = node_name
+
+ ui.info("Updating Chef Vault, waiting for client to be searchable..") while wait_for_client
+
+ update_bootstrap_vault_json!
+ end
+
+ # Iterate through all the vault items to update. Items may be either a String
+ # or an Array of Strings:
+ #
+ # {
+ # "vault1": "item",
+ # "vault2": [ "item1", "item2", "item2" ]
+ # }
+ #
+ def update_bootstrap_vault_json!
+ vault_json.each do |vault, items|
+ [ items ].flatten.each do |item|
+ update_vault(vault, item)
+ end
+ end
+ end
+
+ # @return [Boolean] if we've got chef vault options to act on or not
+ def doing_chef_vault?
+ !!(bootstrap_vault_json || bootstrap_vault_file || bootstrap_vault_item)
+ end
+
+ private
+
+ # warn if the user has given mutual conflicting options
+ def sanity_check
+ if bootstrap_vault_item && (bootstrap_vault_json || bootstrap_vault_file)
+ ui.warn "--vault-item given with --vault-list or --vault-file, ignoring the latter"
+ end
+
+ if bootstrap_vault_json && bootstrap_vault_file
+ ui.warn "--vault-list given with --vault-file, ignoring the latter"
+ end
+ end
+
+ # @return [String] string with serialized JSON representing the chef vault items
+ def bootstrap_vault_json
+ knife_config[:bootstrap_vault_json]
+ end
+
+ # @return [String] JSON text in a file representing the chef vault items
+ def bootstrap_vault_file
+ knife_config[:bootstrap_vault_file]
+ end
+
+ # @return [Hash] Ruby object representing the chef vault items to create
+ def bootstrap_vault_item
+ knife_config[:bootstrap_vault_item]
+ end
+
+ # Helper to return a ruby object represeting all the data bags and items
+ # to update via chef-vault.
+ #
+ # @return [Hash] deserialized ruby hash with all the vault items
+ def vault_json
+ @vault_json ||=
+ begin
+ if bootstrap_vault_item
+ bootstrap_vault_item
+ else
+ json = bootstrap_vault_json ? bootstrap_vault_json : File.read(bootstrap_vault_file)
+ Chef::JSONCompat.from_json(json)
+ end
+ end
+ end
+
+ # Update an individual vault item and save it
+ #
+ # @param vault [String] name of the chef-vault encrypted data bag
+ # @param item [String] name of the chef-vault encrypted item
+ def update_vault(vault, item)
+ require_chef_vault!
+ bootstrap_vault_item = load_chef_bootstrap_vault_item(vault, item)
+ bootstrap_vault_item.clients("name:#{node_name}")
+ bootstrap_vault_item.save
+ end
+
+ # Hook to stub out ChefVault
+ #
+ # @param vault [String] name of the chef-vault encrypted data bag
+ # @param item [String] name of the chef-vault encrypted item
+ # @returns [ChefVault::Item] ChefVault::Item object
+ def load_chef_bootstrap_vault_item(vault, item)
+ ChefVault::Item.load(vault, item)
+ end
+
+ public :load_chef_bootstrap_vault_item # for stubbing
+
+ # Helper used to spin waiting for the client to appear in search.
+ #
+ # @return [Boolean] true if the client is searchable
+ def wait_for_client
+ sleep 1
+ !Chef::Search::Query.new.search(:client, "name:#{node_name}")[0]
+ end
+
+ # Helper to very lazily require the chef-vault gem
+ def require_chef_vault!
+ @require_chef_vault ||=
+ begin
+ require 'chef-vault'
+ true
+ rescue LoadError
+ raise "Knife bootstrap cannot configure chef vault items when the chef-vault gem is not installed"
+ end
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/knife/bootstrap/client_builder.rb b/lib/chef/knife/bootstrap/client_builder.rb
new file mode 100644
index 0000000000..b9c1d98bec
--- /dev/null
+++ b/lib/chef/knife/bootstrap/client_builder.rb
@@ -0,0 +1,190 @@
+#
+# Author:: Lamont Granquist (<lamont@chef.io>)
+# Copyright:: Copyright (c) 2015 Opscode, 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/node'
+require 'chef/rest'
+require 'chef/api_client/registration'
+require 'chef/api_client'
+require 'tmpdir'
+
+class Chef
+ class Knife
+ class Bootstrap < Knife
+ class ClientBuilder
+
+ # @return [Hash] knife merged config, typically @config
+ attr_accessor :knife_config
+ # @return [Hash] chef config object
+ attr_accessor :chef_config
+ # @return [Chef::Knife::UI] ui object for output
+ attr_accessor :ui
+
+ # @param knife_config [Hash] Hash of knife config settings
+ # @param chef_config [Hash] Hash of chef config settings
+ # @param ui [Chef::Knife::UI] UI object for output
+ def initialize(knife_config: {}, chef_config: {}, ui: nil)
+ @knife_config = knife_config
+ @chef_config = chef_config
+ @ui = ui
+ end
+
+ # Main entry. Prompt the user to clean up any old client or node objects. Then create
+ # the new client, then create the new node.
+ def run
+ sanity_check
+
+ ui.info("Creating new client for #{node_name}")
+
+ create_client!
+
+ ui.info("Creating new node for #{node_name}")
+
+ create_node!
+ end
+
+ # Tempfile to use to write newly created client credentials to.
+ #
+ # This method is public so that the knife bootstrapper can read then and pass the value into
+ # the handler for chef vault which needs the client cert we create here.
+ #
+ # We hang onto the tmpdir as an ivar as well so that it will not get GC'd and removed
+ #
+ # @return [String] path to the generated client.pem
+ def client_path
+ @client_path ||=
+ begin
+ @tmpdir = Dir.mktmpdir
+ File.join(@tmpdir, "#{node_name}.pem")
+ end
+ end
+
+ private
+
+ # @return [String] node name from the knife_config
+ def node_name
+ knife_config[:chef_node_name]
+ end
+
+ # @return [String] enviroment from the knife_config
+ def environment
+ knife_config[:environment]
+ end
+
+ # @return [String] run_list from the knife_config
+ def run_list
+ knife_config[:run_list]
+ end
+
+ # @return [Hash,Array] Object representation of json first-boot attributes from the knife_config
+ def first_boot_attributes
+ knife_config[:first_boot_attributes]
+ end
+
+ # @return [String] chef server url from the Chef::Config
+ def chef_server_url
+ chef_config[:chef_server_url]
+ end
+
+ # Accesses the run_list and coerces it into an Array, changing nils into
+ # the empty Array, and splitting strings representations of run_lists into
+ # Arrays.
+ #
+ # @return [Array] run_list coerced into an array
+ def normalized_run_list
+ case run_list
+ when nil
+ []
+ when String
+ run_list.split(/\s*,\s*/)
+ when Array
+ run_list
+ end
+ end
+
+ # Create the client object and save it to the Chef API
+ def create_client!
+ Chef::ApiClient::Registration.new(node_name, client_path, http_api: rest).run
+ end
+
+ # Create the node object (via the lazy accessor) and save it to the Chef API
+ def create_node!
+ node.save
+ end
+
+ # Create a new Chef::Node. Supports creating the node with its name, run_list, attributes
+ # and environment. This injects a rest object into the Chef::Node which uses the client key
+ # for authentication so that the client creates the node and therefore we get the acls setup
+ # correctly.
+ #
+ # @return [Chef::Node] new chef node to create
+ def node
+ @node ||=
+ begin
+ node = Chef::Node.new(chef_server_rest: client_rest)
+ node.name(node_name)
+ node.run_list(normalized_run_list)
+ node.normal_attrs = first_boot_attributes if first_boot_attributes
+ node.environment(environment) if environment
+ node
+ end
+ end
+
+ # Check for the existence of a node and/or client already on the server. If the node
+ # already exists, we must delete it in order to proceed so that we can create a new node
+ # object with the permissions of the new client. There is a use case for creating a new
+ # client and wiring it up to a precreated node object, but we do currently support that.
+ #
+ # We prompt the user about what to do and will fail hard if we do not get confirmation to
+ # delete any prior node/client objects.
+ def sanity_check
+ if resource_exists?("nodes/#{node_name}")
+ ui.confirm("Node #{node_name} exists, overwrite it")
+ rest.delete("nodes/#{node_name}")
+ end
+ if resource_exists?("clients/#{node_name}")
+ ui.confirm("Client #{node_name} exists, overwrite it")
+ rest.delete("clients/#{node_name}")
+ end
+ end
+
+ # Check if an relative path exists on the chef server
+ #
+ # @param relative_path [String] URI path relative to the chef organization
+ # @return [Boolean] if the relative path exists or returns a 404
+ def resource_exists?(relative_path)
+ rest.get_rest(relative_path)
+ true
+ rescue Net::HTTPServerException => e
+ raise unless e.response.code == "404"
+ false
+ end
+
+ # @return [Chef::REST] REST client using the client credentials
+ def client_rest
+ @client_rest ||= Chef::REST.new(chef_server_url, node_name, client_path)
+ end
+
+ # @return [Chef::REST] REST client using the cli user's knife credentials
+ # this uses the users's credentials
+ def rest
+ @rest ||= Chef::REST.new(chef_server_url)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/knife/bootstrap/README.md b/lib/chef/knife/bootstrap/templates/README.md
index 13a0fe7ada..13a0fe7ada 100644
--- a/lib/chef/knife/bootstrap/README.md
+++ b/lib/chef/knife/bootstrap/templates/README.md
diff --git a/lib/chef/knife/bootstrap/archlinux-gems.erb b/lib/chef/knife/bootstrap/templates/archlinux-gems.erb
index 581293daa3..55d2c0cc12 100644
--- a/lib/chef/knife/bootstrap/archlinux-gems.erb
+++ b/lib/chef/knife/bootstrap/templates/archlinux-gems.erb
@@ -11,10 +11,12 @@ fi
mkdir -p /etc/chef
+<% if validation_key -%>
cat > /etc/chef/validation.pem <<'EOP'
<%= validation_key %>
EOP
chmod 0600 /etc/chef/validation.pem
+<% end -%>
<% if encrypted_data_bag_secret -%>
cat > /etc/chef/encrypted_data_bag_secret <<'EOP'
@@ -39,6 +41,13 @@ EOP
<% end -%>
<% end -%>
+<% if client_pem -%>
+cat > /etc/chef/client.pem <<'EOP'
+<%= ::File.read(::File.expand_path(client_pem)) %>
+EOP
+chmod 0600 /etc/chef/client.pem
+<% end -%>
+
cat > /etc/chef/client.rb <<'EOP'
log_level :info
log_location STDOUT
diff --git a/lib/chef/knife/bootstrap/chef-aix.erb b/lib/chef/knife/bootstrap/templates/chef-aix.erb
index 013ad1decb..45fbba7b48 100644
--- a/lib/chef/knife/bootstrap/chef-aix.erb
+++ b/lib/chef/knife/bootstrap/templates/chef-aix.erb
@@ -24,10 +24,19 @@ fi
mkdir -p /etc/chef
+<% if client_pem -%>
+cat > /etc/chef/client.pem <<'EOP'
+<%= ::File.read(::File.expand_path(client_pem)) %>
+EOP
+chmod 0600 /etc/chef/client.pem
+<% end -%>
+
+<% if validation_key -%>
cat > /etc/chef/validation.pem <<'EOP'
<%= validation_key %>
EOP
chmod 0600 /etc/chef/validation.pem
+<% end -%>
<% if encrypted_data_bag_secret -%>
cat > /etc/chef/encrypted_data_bag_secret <<'EOP'
diff --git a/lib/chef/knife/bootstrap/chef-full.erb b/lib/chef/knife/bootstrap/templates/chef-full.erb
index dfd5df0071..17d7a9e3b5 100644
--- a/lib/chef/knife/bootstrap/chef-full.erb
+++ b/lib/chef/knife/bootstrap/templates/chef-full.erb
@@ -22,7 +22,7 @@ exists() {
<% if knife_config[:bootstrap_install_command] %>
<%= knife_config[:bootstrap_install_command] %>
<% else %>
- install_sh="<%= knife_config[:bootstrap_url] ? knife_config[:bootstrap_url] : "https://www.opscode.com/chef/install.sh" %>"
+ install_sh="<%= knife_config[:bootstrap_url] ? knife_config[:bootstrap_url] : "https://www.chef.io/chef/install.sh" %>"
if ! exists /usr/bin/chef-client; then
echo "Installing Chef Client..."
if exists wget; then
@@ -38,10 +38,19 @@ exists() {
mkdir -p /etc/chef
+<% if client_pem -%>
+cat > /etc/chef/client.pem <<'EOP'
+<%= ::File.read(::File.expand_path(client_pem)) %>
+EOP
+chmod 0600 /etc/chef/client.pem
+<% end -%>
+
+<% if validation_key -%>
cat > /etc/chef/validation.pem <<'EOP'
<%= validation_key %>
EOP
chmod 0600 /etc/chef/validation.pem
+<% end -%>
<% if encrypted_data_bag_secret -%>
cat > /etc/chef/encrypted_data_bag_secret <<'EOP'
diff --git a/lib/chef/knife/client_create.rb b/lib/chef/knife/client_create.rb
index b2bac36081..477a400e8a 100644
--- a/lib/chef/knife/client_create.rb
+++ b/lib/chef/knife/client_create.rb
@@ -54,14 +54,16 @@ class Chef
exit 1
end
- client = Chef::ApiClient.new
- client.name(@client_name)
- client.admin(config[:admin])
- client.validator(config[:validator])
+ client_hash = {
+ "name" => @client_name,
+ "admin" => !!config[:admin],
+ "validator" => !!config[:validator]
+ }
- output = edit_data(client)
+ output = Chef::ApiClient.from_hash(edit_hash(client_hash))
- # Chef::ApiClient.save will try to create a client and if it exists will update it instead silently
+ # Chef::ApiClient.save will try to create a client and if it
+ # exists will update it instead silently.
client = output.save
# We only get a private_key on client creation, not on client update.
@@ -83,4 +85,3 @@ class Chef
end
end
end
-
diff --git a/lib/chef/knife/cookbook_site_download.rb b/lib/chef/knife/cookbook_site_download.rb
index de6e21d0d2..c2d72ef8da 100644
--- a/lib/chef/knife/cookbook_site_download.rb
+++ b/lib/chef/knife/cookbook_site_download.rb
@@ -58,7 +58,7 @@ class Chef
private
def cookbooks_api_url
- 'https://supermarket.getchef.com/api/v1/cookbooks'
+ 'https://supermarket.chef.io/api/v1/cookbooks'
end
def current_cookbook_data
diff --git a/lib/chef/knife/cookbook_site_list.rb b/lib/chef/knife/cookbook_site_list.rb
index 6fcf7e6064..846123c867 100644
--- a/lib/chef/knife/cookbook_site_list.rb
+++ b/lib/chef/knife/cookbook_site_list.rb
@@ -41,7 +41,7 @@ class Chef
end
def get_cookbook_list(items=10, start=0, cookbook_collection={})
- cookbooks_url = "https://supermarket.getchef.com/api/v1/cookbooks?items=#{items}&start=#{start}"
+ cookbooks_url = "https://supermarket.chef.io/api/v1/cookbooks?items=#{items}&start=#{start}"
cr = noauth_rest.get_rest(cookbooks_url)
cr["items"].each do |cookbook|
cookbook_collection[cookbook["cookbook_name"]] = cookbook
diff --git a/lib/chef/knife/cookbook_site_search.rb b/lib/chef/knife/cookbook_site_search.rb
index ec4d196ee3..0baaf90f1c 100644
--- a/lib/chef/knife/cookbook_site_search.rb
+++ b/lib/chef/knife/cookbook_site_search.rb
@@ -29,7 +29,7 @@ class Chef
end
def search_cookbook(query, items=10, start=0, cookbook_collection={})
- cookbooks_url = "https://supermarket.getchef.com/api/v1/search?q=#{query}&items=#{items}&start=#{start}"
+ cookbooks_url = "https://supermarket.chef.io/api/v1/search?q=#{query}&items=#{items}&start=#{start}"
cr = noauth_rest.get_rest(cookbooks_url)
cr["items"].each do |cookbook|
cookbook_collection[cookbook["cookbook_name"]] = cookbook
diff --git a/lib/chef/knife/cookbook_site_share.rb b/lib/chef/knife/cookbook_site_share.rb
index b4a7873c71..560e0669c1 100644
--- a/lib/chef/knife/cookbook_site_share.rb
+++ b/lib/chef/knife/cookbook_site_share.rb
@@ -29,8 +29,11 @@ class Chef
require 'chef/cookbook_loader'
require 'chef/cookbook_uploader'
require 'chef/cookbook_site_streaming_uploader'
+ require 'mixlib/shellout'
end
+ include Chef::Mixin::ShellOut
+
banner "knife cookbook site share COOKBOOK [CATEGORY] (options)"
category "cookbook site"
@@ -70,7 +73,15 @@ class Chef
begin
Chef::Log.debug("Temp cookbook directory is #{tmp_cookbook_dir.inspect}")
ui.info("Making tarball #{cookbook_name}.tgz")
- shell_out!("tar -czf #{cookbook_name}.tgz #{cookbook_name}", :cwd => tmp_cookbook_dir)
+ tar_cmd = "tar"
+ begin
+ # Unix and Mac only - prefer gnutar
+ if shell_out("which gnutar").exitstatus.equal?(0)
+ tar_cmd = "gnutar"
+ end
+ rescue Errno::ENOENT
+ end
+ shell_out!("#{tar_cmd} -czf #{cookbook_name}.tgz #{cookbook_name}", :cwd => tmp_cookbook_dir)
rescue => e
ui.error("Error making tarball #{cookbook_name}.tgz: #{e.message}. Increase log verbosity (-VV) for more information.")
Chef::Log.debug("\n#{e.backtrace.join("\n")}")
@@ -120,33 +131,33 @@ class Chef
end
def do_upload(cookbook_filename, cookbook_category, user_id, user_secret_filename)
- uri = "https://supermarket.getchef.com/api/v1/cookbooks"
-
- category_string = Chef::JSONCompat.to_json({ 'category'=>cookbook_category })
-
- http_resp = Chef::CookbookSiteStreamingUploader.post(uri, user_id, user_secret_filename, {
- :tarball => File.open(cookbook_filename),
- :cookbook => category_string
- })
-
- res = Chef::JSONCompat.from_json(http_resp.body)
- if http_resp.code.to_i != 201
- if res['error_messages']
- if res['error_messages'][0] =~ /Version already exists/
- ui.error "The same version of this cookbook already exists on the Opscode Cookbook Site."
- exit(1)
- else
- ui.error "#{res['error_messages'][0]}"
- exit(1)
- end
- else
- ui.error "Unknown error while sharing cookbook"
- ui.error "Server response: #{http_resp.body}"
- exit(1)
- end
- end
- res
- end
+ uri = "https://supermarket.chef.io/api/v1/cookbooks"
+
+ category_string = Chef::JSONCompat.to_json({ 'category'=>cookbook_category })
+
+ http_resp = Chef::CookbookSiteStreamingUploader.post(uri, user_id, user_secret_filename, {
+ :tarball => File.open(cookbook_filename),
+ :cookbook => category_string
+ })
+
+ res = Chef::JSONCompat.from_json(http_resp.body)
+ if http_resp.code.to_i != 201
+ if res['error_messages']
+ if res['error_messages'][0] =~ /Version already exists/
+ ui.error "The same version of this cookbook already exists on the Opscode Cookbook Site."
+ exit(1)
+ else
+ ui.error "#{res['error_messages'][0]}"
+ exit(1)
+ end
+ else
+ ui.error "Unknown error while sharing cookbook"
+ ui.error "Server response: #{http_resp.body}"
+ exit(1)
+ end
+ end
+ res
+ end
end
end
diff --git a/lib/chef/knife/cookbook_site_show.rb b/lib/chef/knife/cookbook_site_show.rb
index c520c00621..6b65b62570 100644
--- a/lib/chef/knife/cookbook_site_show.rb
+++ b/lib/chef/knife/cookbook_site_show.rb
@@ -31,14 +31,14 @@ class Chef
def get_cookbook_data
case @name_args.length
when 1
- noauth_rest.get_rest("https://supermarket.getchef.com/api/v1/cookbooks/#{@name_args[0]}")
+ noauth_rest.get_rest("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}")
when 2
- noauth_rest.get_rest("https://supermarket.getchef.com/api/v1/cookbooks/#{@name_args[0]}/versions/#{name_args[1].gsub('.', '_')}")
+ noauth_rest.get_rest("https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}/versions/#{name_args[1].gsub('.', '_')}")
end
end
def get_cookbook_list(items=10, start=0, cookbook_collection={})
- cookbooks_url = "https://supermarket.getchef.com/api/v1/cookbooks?items=#{items}&start=#{start}"
+ cookbooks_url = "https://supermarket.chef.io/api/v1/cookbooks?items=#{items}&start=#{start}"
cr = noauth_rest.get_rest(cookbooks_url)
cr["items"].each do |cookbook|
cookbook_collection[cookbook["cookbook_name"]] = cookbook
diff --git a/lib/chef/knife/cookbook_site_unshare.rb b/lib/chef/knife/cookbook_site_unshare.rb
index f095885f15..b34282ec32 100644
--- a/lib/chef/knife/cookbook_site_unshare.rb
+++ b/lib/chef/knife/cookbook_site_unshare.rb
@@ -41,7 +41,7 @@ class Chef
confirm "Do you really want to unshare the cookbook #{@cookbook_name}"
begin
- rest.delete_rest "https://supermarket.getchef.com/api/v1/cookbooks/#{@name_args[0]}"
+ rest.delete_rest "https://supermarket.chef.io/api/v1/cookbooks/#{@name_args[0]}"
rescue Net::HTTPServerException => e
raise e unless e.message =~ /Forbidden/
ui.error "Forbidden: You must be the maintainer of #{@cookbook_name} to unshare it."
diff --git a/lib/chef/knife/cookbook_test.rb b/lib/chef/knife/cookbook_test.rb
index 0ff992b392..91e0b55c47 100644
--- a/lib/chef/knife/cookbook_test.rb
+++ b/lib/chef/knife/cookbook_test.rb
@@ -43,6 +43,7 @@ class Chef
:description => "Test all cookbooks, rather than just a single cookbook"
def run
+ ui.warn("DEPRECATED: Please use ChefSpec or Rubocop to syntax-check cookbooks.")
config[:cookbook_path] ||= Chef::Config[:cookbook_path]
checked_a_cookbook = false
diff --git a/lib/chef/knife/cookbook_upload.rb b/lib/chef/knife/cookbook_upload.rb
index f5002be3a7..b2acd74b4b 100644
--- a/lib/chef/knife/cookbook_upload.rb
+++ b/lib/chef/knife/cookbook_upload.rb
@@ -104,18 +104,23 @@ class Chef
justify_width = @server_side_cookbooks.map {|name| name.size}.max.to_i + 2
if config[:all]
cookbook_repo.load_cookbooks
- cbs = []
+ cookbooks_for_upload = []
cookbook_repo.each do |cookbook_name, cookbook|
- cbs << cookbook
+ cookbooks_for_upload << cookbook
cookbook.freeze_version if config[:freeze]
version_constraints_to_update[cookbook_name] = cookbook.version
end
- begin
- upload(cbs, justify_width)
- rescue Exceptions::CookbookFrozen
- ui.warn("Not updating version constraints for some cookbooks in the environment as the cookbook is frozen.")
+ if cookbooks_for_upload.any?
+ begin
+ upload(cookbooks_for_upload, justify_width)
+ rescue Exceptions::CookbookFrozen
+ ui.warn("Not updating version constraints for some cookbooks in the environment as the cookbook is frozen.")
+ end
+ ui.info("Uploaded all cookbooks.")
+ else
+ cookbook_path = config[:cookbook_path].respond_to?(:join) ? config[:cookbook_path].join(', ') : config[:cookbook_path]
+ ui.warn("Could not find any cookbooks in your cookbook path: #{cookbook_path}. Use --cookbook-path to specify the desired path.")
end
- ui.info("Uploaded all cookbooks.")
else
if @name_args.empty?
show_usage
@@ -204,7 +209,7 @@ class Chef
# because cookbooks are lazy-loaded, we have to force the loader
# to load the cookbooks the user intends to upload here:
cookbooks_to_upload
-
+
unless cookbook_repo.merged_cookbooks.empty?
ui.warn "* " * 40
ui.warn(<<-WARNING)
diff --git a/lib/chef/knife/core/bootstrap_context.rb b/lib/chef/knife/core/bootstrap_context.rb
index 3833182c70..7197653489 100644
--- a/lib/chef/knife/core/bootstrap_context.rb
+++ b/lib/chef/knife/core/bootstrap_context.rb
@@ -23,13 +23,15 @@ class Chef
class Knife
module Core
# Instances of BootstrapContext are the context objects (i.e., +self+) for
- # bootstrap templates. For backwards compatability, they +must+ set the
+ # bootstrap templates. For backwards compatibility, they +must+ set the
# following instance variables:
# * @config - a hash of knife's config values
# * @run_list - the run list for the node to boostrap
#
class BootstrapContext
+ attr_accessor :client_pem
+
def initialize(config, run_list, chef_config, secret = nil)
@config = config
@run_list = run_list
@@ -42,13 +44,19 @@ class Chef
end
def validation_key
- IO.read(File.expand_path(@chef_config[:validation_key]))
+ if File.exist?(File.expand_path(@chef_config[:validation_key]))
+ IO.read(File.expand_path(@chef_config[:validation_key]))
+ else
+ false
+ end
end
def encrypted_data_bag_secret
@secret
end
+ # Contains commands and content, see trusted_certs_content
+ # TODO: Rename to trusted_certs_script
def trusted_certs
@trusted_certs ||= trusted_certs_content
end
@@ -135,7 +143,7 @@ CONFIG
def latest_current_chef_version_string
installer_version_string = nil
if @config[:prerelease]
- installer_version_string = "-p"
+ installer_version_string = ["-p"]
else
chef_version_string = if knife_config[:bootstrap_version]
knife_config[:bootstrap_version]
@@ -159,6 +167,9 @@ CONFIG
end
private
+
+ # Returns a string for copying the trusted certificates on the workstation to the system being bootstrapped
+ # This string should contain both the commands necessary to both create the files, as well as their content
def trusted_certs_content
content = ""
if @chef_config[:trusted_certs_dir]
diff --git a/lib/chef/knife/core/generic_presenter.rb b/lib/chef/knife/core/generic_presenter.rb
index a1aeadb0f3..f3ea0f0d6c 100644
--- a/lib/chef/knife/core/generic_presenter.rb
+++ b/lib/chef/knife/core/generic_presenter.rb
@@ -178,10 +178,13 @@ class Chef
nested_value_spec.split(".").each do |attr|
if data.nil?
nil # don't get no method error on nil
- elsif data.respond_to?(attr.to_sym)
- data = data.send(attr.to_sym)
+ # Must check :[] before attr because spec can include
+ # `keys` - want the key named `keys`, not a list of
+ # available keys.
elsif data.respond_to?(:[])
data = data[attr]
+ elsif data.respond_to?(attr.to_sym)
+ data = data.send(attr.to_sym)
else
data = begin
data.send(attr.to_sym)
diff --git a/lib/chef/knife/core/object_loader.rb b/lib/chef/knife/core/object_loader.rb
index 209f6987d4..698b09ac84 100644
--- a/lib/chef/knife/core/object_loader.rb
+++ b/lib/chef/knife/core/object_loader.rb
@@ -105,7 +105,7 @@ class Chef
end
def file_exists_and_is_readable?(file)
- File.exists?(file) && File.readable?(file)
+ File.exist?(file) && File.readable?(file)
end
end
diff --git a/lib/chef/knife/core/subcommand_loader.rb b/lib/chef/knife/core/subcommand_loader.rb
index d2be1be2d3..f9b8f5008e 100644
--- a/lib/chef/knife/core/subcommand_loader.rb
+++ b/lib/chef/knife/core/subcommand_loader.rb
@@ -22,6 +22,9 @@ class Chef
class Knife
class SubcommandLoader
+ MATCHES_CHEF_GEM = %r{/chef-[\d]+\.[\d]+\.[\d]+}.freeze
+ MATCHES_THIS_CHEF_GEM = %r{/chef-#{Chef::VERSION}/}.freeze
+
attr_reader :chef_config_dir
attr_reader :env
@@ -122,6 +125,14 @@ class Chef
subcommand_files = {}
files.each do |file|
rel_path = file[/(#{Regexp.escape File.join('chef', 'knife', '')}.*)\.rb/, 1]
+
+ # When not installed as a gem (ChefDK/appbundler in particular), AND
+ # a different version of Chef is installed via gems, `files` will
+ # include some files from the 'other' Chef install. If this contains
+ # a knife command that doesn't exist in this version of Chef, we will
+ # get a LoadError later when we try to require it.
+ next if from_different_chef_version?(file)
+
subcommand_files[rel_path] = file
end
@@ -185,6 +196,19 @@ class Chef
Dir[glob].map { |f| f.untaint }
end
+
+ def from_different_chef_version?(path)
+ matches_any_chef_gem?(path) && !matches_this_chef_gem?(path)
+ end
+
+ def matches_any_chef_gem?(path)
+ path =~ MATCHES_CHEF_GEM
+ end
+
+ def matches_this_chef_gem?(path)
+ path =~ MATCHES_THIS_CHEF_GEM
+ end
+
end
end
end
diff --git a/lib/chef/knife/core/ui.rb b/lib/chef/knife/core/ui.rb
index 00a4834638..a54f14afc1 100644
--- a/lib/chef/knife/core/ui.rb
+++ b/lib/chef/knife/core/ui.rb
@@ -163,9 +163,17 @@ class Chef
end
end
+
+ # Hash -> Hash
+ # Works the same as edit_data but
+ # returns a hash rather than a JSON string/Fully infated object
+ def edit_hash(hash)
+ raw = edit_data(hash, false)
+ Chef::JSONCompat.parse(raw)
+ end
+
def edit_data(data, parse_output=true)
output = Chef::JSONCompat.to_json_pretty(data)
-
if (!config[:disable_editing])
Tempfile.open([ 'knife-edit-', '.json' ]) do |tf|
tf.sync = true
diff --git a/lib/chef/knife/node_run_list_remove.rb b/lib/chef/knife/node_run_list_remove.rb
index 8519fd590a..4b8953a264 100644
--- a/lib/chef/knife/node_run_list_remove.rb
+++ b/lib/chef/knife/node_run_list_remove.rb
@@ -27,11 +27,20 @@ class Chef
require 'chef/json_compat'
end
- banner "knife node run_list remove [NODE] [ENTRIES] (options)"
+ banner "knife node run_list remove [NODE] [ENTRY[,ENTRY]] (options)"
def run
node = Chef::Node.load(@name_args[0])
- entries = @name_args[1].split(',')
+
+ if @name_args.size > 2
+ # Check for nested lists and create a single plain one
+ entries = @name_args[1..-1].map do |entry|
+ entry.split(',').map { |e| e.strip }
+ end.flatten
+ else
+ # Convert to array and remove the extra spaces
+ entries = @name_args[1].split(',').map { |e| e.strip }
+ end
entries.each { |e| node.run_list.remove(e) }
@@ -45,4 +54,3 @@ class Chef
end
end
end
-
diff --git a/lib/chef/knife/raw.rb b/lib/chef/knife/raw.rb
index 954d46beee..601cfcef9b 100644
--- a/lib/chef/knife/raw.rb
+++ b/lib/chef/knife/raw.rb
@@ -32,6 +32,12 @@ class Chef
:short => '-i FILE',
:description => "Name of file to use for PUT or POST"
+ option :proxy_auth,
+ :long => '--proxy-auth',
+ :boolean => true,
+ :default => false,
+ :description => "Use webui proxy authentication. Client key must be the webui key."
+
class RawInputServerAPI < Chef::HTTP
def initialize(options = {})
options[:client_name] ||= Chef::Config[:node_name]
@@ -64,15 +70,21 @@ class Chef
begin
method = config[:method].to_sym
+ headers = {'Content-Type' => 'application/json'}
+
+ if config[:proxy_auth]
+ headers['x-ops-request-source'] = 'web'
+ end
+
if config[:pretty]
chef_rest = RawInputServerAPI.new
- result = chef_rest.request(method, name_args[0], {'Content-Type' => 'application/json'}, data)
+ result = chef_rest.request(method, name_args[0], headers, data)
unless result.is_a?(String)
result = Chef::JSONCompat.to_json_pretty(result)
end
else
chef_rest = RawInputServerAPI.new(:raw_output => true)
- result = chef_rest.request(method, name_args[0], {'Content-Type' => 'application/json'}, data)
+ result = chef_rest.request(method, name_args[0], headers, data)
end
output result
rescue Timeout::Error => e
@@ -88,4 +100,3 @@ class Chef
end # class Raw
end
end
-
diff --git a/lib/chef/knife/role_env_run_list_add.rb b/lib/chef/knife/role_env_run_list_add.rb
new file mode 100644
index 0000000000..faf84ccfdb
--- /dev/null
+++ b/lib/chef/knife/role_env_run_list_add.rb
@@ -0,0 +1,86 @@
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: William Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2009 Opscode, 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/knife'
+
+class Chef
+ class Knife
+ class RoleEnvRunListAdd < Knife
+
+ deps do
+ require 'chef/role'
+ require 'chef/json_compat'
+ end
+
+ banner "knife role env_run_list add [ROLE] [ENVIRONMENT] [ENTRY[,ENTRY]] (options)"
+
+ option :after,
+ :short => "-a ITEM",
+ :long => "--after ITEM",
+ :description => "Place the ENTRY in the run list after ITEM"
+
+ def add_to_env_run_list(role, environment, entries, after=nil)
+ if after
+ nlist = []
+ unless role.env_run_lists.key?(environment)
+ role.env_run_lists_add(environment => nlist)
+ end
+ role.run_list_for(environment).each do |entry|
+ nlist << entry
+ if entry == after
+ entries.each { |e| nlist << e }
+ end
+ end
+ role.env_run_lists_add(environment => nlist)
+ else
+ nlist = []
+ unless role.env_run_lists.key?(environment)
+ role.env_run_lists_add(environment => nlist)
+ end
+ role.run_list_for(environment).each do |entry|
+ nlist << entry
+ end
+ entries.each { |e| nlist << e }
+ role.env_run_lists_add(environment => nlist)
+ end
+ end
+
+ def run
+ role = Chef::Role.load(@name_args[0])
+ role.name(@name_args[0])
+ environment = @name_args[1]
+
+ if @name_args.size > 2
+ # Check for nested lists and create a single plain one
+ entries = @name_args[2..-1].map do |entry|
+ entry.split(',').map { |e| e.strip }
+ end.flatten
+ else
+ # Convert to array and remove the extra spaces
+ entries = @name_args[2].split(',').map { |e| e.strip }
+ end
+
+ add_to_env_run_list(role, environment, entries, config[:after])
+ role.save
+ config[:env_run_list] = true
+ output(format_for_display(role))
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/knife/role_env_run_list_clear.rb b/lib/chef/knife/role_env_run_list_clear.rb
new file mode 100644
index 0000000000..4304f29a38
--- /dev/null
+++ b/lib/chef/knife/role_env_run_list_clear.rb
@@ -0,0 +1,55 @@
+#
+# Author:: Mike Fiedler (<miketheman@gmail.com>)
+# Author:: William Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2013 Mike Fiedler
+# 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/knife'
+
+class Chef
+ class Knife
+ class RoleEnvRunListClear < Knife
+
+ deps do
+ require 'chef/role'
+ require 'chef/json_compat'
+ end
+
+ banner "knife role env_run_list clear [ROLE] [ENVIRONMENT]"
+ def clear_env_run_list(role, environment)
+ nlist = []
+ role.env_run_lists_add(environment => nlist)
+ end
+
+ def run
+ if @name_args.size > 2
+ ui.fatal "You must not supply an environment run list."
+ show_usage
+ exit 1
+ end
+ role = Chef::Role.load(@name_args[0])
+ role.name(@name_args[0])
+ environment = @name_args[1]
+
+ clear_env_run_list(role, environment)
+ role.save
+ config[:env_run_list] = true
+ output(format_for_display(role))
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/knife/role_env_run_list_remove.rb b/lib/chef/knife/role_env_run_list_remove.rb
new file mode 100644
index 0000000000..9ffc3f520e
--- /dev/null
+++ b/lib/chef/knife/role_env_run_list_remove.rb
@@ -0,0 +1,57 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Copyright:: Copyright (c) 2009 Opscode, 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/knife'
+
+class Chef
+ class Knife
+ class RoleEnvRunListRemove < Knife
+
+ deps do
+ require 'chef/role'
+ require 'chef/json_compat'
+ end
+
+ banner "knife role env_run_list remove [ROLE] [ENVIRONMENT] [ENTRIES]"
+
+ def remove_from_env_run_list(role, environment, item_to_remove)
+ nlist = []
+ role.run_list_for(environment).each do |entry|
+ nlist << entry unless entry == item_to_remove
+ #unless entry == @name_args[2]
+ # nlist << entry
+ #end
+ end
+ role.env_run_lists_add(environment => nlist)
+ end
+
+ def run
+ role = Chef::Role.load(@name_args[0])
+ role.name(@name_args[0])
+ environment = @name_args[1]
+ item_to_remove = @name_args[2]
+
+ remove_from_env_run_list(role, environment, item_to_remove)
+ role.save
+ config[:env_run_list] = true
+ output(format_for_display(role))
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/knife/role_env_run_list_replace.rb b/lib/chef/knife/role_env_run_list_replace.rb
new file mode 100644
index 0000000000..146d0c4905
--- /dev/null
+++ b/lib/chef/knife/role_env_run_list_replace.rb
@@ -0,0 +1,59 @@
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: William Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2009 Opscode, 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/knife'
+
+class Chef
+ class Knife
+ class RoleEnvRunListReplace < Knife
+
+ deps do
+ require 'chef/role'
+ require 'chef/json_compat'
+ end
+
+ banner "knife role env_run_list replace [ROLE] [ENVIRONMENT] [OLD_ENTRY] [NEW_ENTRY] "
+
+ def replace_in_env_run_list(role, environment, old_entry, new_entry)
+ nlist = []
+ role.run_list_for(environment).each do |entry|
+ if entry == old_entry
+ nlist << new_entry
+ else
+ nlist << entry
+ end
+ end
+ role.env_run_lists_add(environment => nlist)
+ end
+
+ def run
+ role = Chef::Role.load(@name_args[0])
+ role.name(@name_args[0])
+ environment = @name_args[1]
+ old_entry = @name_args[2]
+ new_entry = @name_args[3]
+
+ replace_in_env_run_list(role, environment, old_entry, new_entry)
+ role.save
+ config[:env_run_list] = true
+ output(format_for_display(role))
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/knife/role_env_run_list_set.rb b/lib/chef/knife/role_env_run_list_set.rb
new file mode 100644
index 0000000000..a1618516c0
--- /dev/null
+++ b/lib/chef/knife/role_env_run_list_set.rb
@@ -0,0 +1,70 @@
+#
+# Author:: Mike Fiedler (<miketheman@gmail.com>)
+# Author:: William Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2013 Mike Fiedler
+# 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/knife'
+
+class Chef
+ class Knife
+ class RoleEnvRunListSet < Knife
+
+ deps do
+ require 'chef/role'
+ require 'chef/json_compat'
+ end
+
+ banner "knife role env_run_list set [ROLE] [ENVIRONMENT] [ENTRIES]"
+
+ # Clears out any existing env_run_list_items and sets them to the
+ # specified entries
+ def set_env_run_list(role, environment, entries)
+ nlist = []
+ unless role.env_run_lists.key?(environment)
+ role.env_run_lists_add(environment => nlist)
+ end
+ entries.each { |e| nlist << e }
+ role.env_run_lists_add(environment => nlist)
+ end
+
+ def run
+ role = Chef::Role.load(@name_args[0])
+ role.name(@name_args[0])
+ environment = @name_args[1]
+ if @name_args.size < 2
+ ui.fatal "You must supply both a role name and an environment run list."
+ show_usage
+ exit 1
+ elsif @name_args.size > 2
+ # Check for nested lists and create a single plain one
+ entries = @name_args[2..-1].map do |entry|
+ entry.split(',').map { |e| e.strip }
+ end.flatten
+ else
+ # Convert to array and remove the extra spaces
+ entries = @name_args[2].split(',').map { |e| e.strip }
+ end
+
+ set_env_run_list(role, environment, entries )
+ role.save
+ config[:env_run_list] = true
+ output(format_for_display(role))
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/knife/role_run_list_add.rb b/lib/chef/knife/role_run_list_add.rb
new file mode 100644
index 0000000000..c9d7785bb7
--- /dev/null
+++ b/lib/chef/knife/role_run_list_add.rb
@@ -0,0 +1,86 @@
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: William Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2009 Opscode, 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/knife'
+
+class Chef
+ class Knife
+ class RoleRunListAdd < Knife
+
+ deps do
+ require 'chef/role'
+ require 'chef/json_compat'
+ end
+
+ banner "knife role run_list add [ROLE] [ENTRY[,ENTRY]] (options)"
+
+ option :after,
+ :short => "-a ITEM",
+ :long => "--after ITEM",
+ :description => "Place the ENTRY in the run list after ITEM"
+
+ def add_to_env_run_list(role, environment, entries, after=nil)
+ if after
+ nlist = []
+ unless role.env_run_lists.key?(environment)
+ role.env_run_lists_add(environment => nlist)
+ end
+ role.run_list_for(environment).each do |entry|
+ nlist << entry
+ if entry == after
+ entries.each { |e| nlist << e }
+ end
+ end
+ role.env_run_lists_add(environment => nlist)
+ else
+ nlist = []
+ unless role.env_run_lists.key?(environment)
+ role.env_run_lists_add(environment => nlist)
+ end
+ role.run_list_for(environment).each do |entry|
+ nlist << entry
+ end
+ entries.each { |e| nlist << e }
+ role.env_run_lists_add(environment => nlist)
+ end
+ end
+
+ def run
+ role = Chef::Role.load(@name_args[0])
+ role.name(@name_args[0])
+ environment = "_default"
+
+ if @name_args.size > 1
+ # Check for nested lists and create a single plain one
+ entries = @name_args[1..-1].map do |entry|
+ entry.split(',').map { |e| e.strip }
+ end.flatten
+ else
+ # Convert to array and remove the extra spaces
+ entries = @name_args[1].split(',').map { |e| e.strip }
+ end
+
+ add_to_env_run_list(role, environment, entries, config[:after])
+ role.save
+ config[:env_run_list] = true
+ output(format_for_display(role))
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/knife/role_run_list_clear.rb b/lib/chef/knife/role_run_list_clear.rb
new file mode 100644
index 0000000000..ed6225d83d
--- /dev/null
+++ b/lib/chef/knife/role_run_list_clear.rb
@@ -0,0 +1,55 @@
+#
+# Author:: Mike Fiedler (<miketheman@gmail.com>)
+# Author:: William Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2013 Mike Fiedler
+# 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/knife'
+
+class Chef
+ class Knife
+ class RoleRunListClear < Knife
+
+ deps do
+ require 'chef/role'
+ require 'chef/json_compat'
+ end
+
+ banner "knife role run_list clear [ROLE]"
+ def clear_env_run_list(role, environment)
+ nlist = []
+ role.env_run_lists_add(environment => nlist)
+ end
+
+ def run
+ if @name_args.size > 2
+ ui.fatal "You must not supply an environment run list."
+ show_usage
+ exit 1
+ end
+ role = Chef::Role.load(@name_args[0])
+ role.name(@name_args[0])
+ environment = "_default"
+
+ clear_env_run_list(role, environment)
+ role.save
+ config[:env_run_list] = true
+ output(format_for_display(role))
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/knife/role_run_list_remove.rb b/lib/chef/knife/role_run_list_remove.rb
new file mode 100644
index 0000000000..d783b34ab4
--- /dev/null
+++ b/lib/chef/knife/role_run_list_remove.rb
@@ -0,0 +1,57 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Copyright:: Copyright (c) 2009 Opscode, 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/knife'
+
+class Chef
+ class Knife
+ class RoleRunListRemove < Knife
+
+ deps do
+ require 'chef/role'
+ require 'chef/json_compat'
+ end
+
+ banner "knife role run_list remove [ROLE] [ENTRY]"
+
+ def remove_from_env_run_list(role, environment, item_to_remove)
+ nlist = []
+ role.run_list_for(environment).each do |entry|
+ nlist << entry unless entry == item_to_remove
+ #unless entry == @name_args[2]
+ # nlist << entry
+ #end
+ end
+ role.env_run_lists_add(environment => nlist)
+ end
+
+ def run
+ role = Chef::Role.load(@name_args[0])
+ role.name(@name_args[0])
+ environment = "_default"
+ item_to_remove = @name_args[1]
+
+ remove_from_env_run_list(role, environment, item_to_remove)
+ role.save
+ config[:env_run_list] = true
+ output(format_for_display(role))
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/knife/role_run_list_replace.rb b/lib/chef/knife/role_run_list_replace.rb
new file mode 100644
index 0000000000..1ab94df111
--- /dev/null
+++ b/lib/chef/knife/role_run_list_replace.rb
@@ -0,0 +1,59 @@
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: William Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2009 Opscode, 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/knife'
+
+class Chef
+ class Knife
+ class RoleRunListReplace < Knife
+
+ deps do
+ require 'chef/role'
+ require 'chef/json_compat'
+ end
+
+ banner "knife role run_list replace [ROLE] [OLD_ENTRY] [NEW_ENTRY] "
+
+ def replace_in_env_run_list(role, environment, old_entry, new_entry)
+ nlist = []
+ role.run_list_for(environment).each do |entry|
+ if entry == old_entry
+ nlist << new_entry
+ else
+ nlist << entry
+ end
+ end
+ role.env_run_lists_add(environment => nlist)
+ end
+
+ def run
+ role = Chef::Role.load(@name_args[0])
+ role.name(@name_args[0])
+ environment = "_default"
+ old_entry = @name_args[1]
+ new_entry = @name_args[2]
+
+ replace_in_env_run_list(role, environment, old_entry, new_entry)
+ role.save
+ config[:env_run_list] = true
+ output(format_for_display(role))
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/knife/role_run_list_set.rb b/lib/chef/knife/role_run_list_set.rb
new file mode 100644
index 0000000000..b9675c70dd
--- /dev/null
+++ b/lib/chef/knife/role_run_list_set.rb
@@ -0,0 +1,70 @@
+#
+# Author:: Mike Fiedler (<miketheman@gmail.com>)
+# Author:: William Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2013 Mike Fiedler
+# 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/knife'
+
+class Chef
+ class Knife
+ class RoleRunListSet < Knife
+
+ deps do
+ require 'chef/role'
+ require 'chef/json_compat'
+ end
+
+ banner "knife role run_list set [ROLE] [ENTRIES]"
+
+ # Clears out any existing env_run_list_items and sets them to the
+ # specified entries
+ def set_env_run_list(role, environment, entries)
+ nlist = []
+ unless role.env_run_lists.key?(environment)
+ role.env_run_lists_add(environment => nlist)
+ end
+ entries.each { |e| nlist << e }
+ role.env_run_lists_add(environment => nlist)
+ end
+
+ def run
+ role = Chef::Role.load(@name_args[0])
+ role.name(@name_args[0])
+ environment = "_default"
+ if @name_args.size < 1
+ ui.fatal "You must supply both a role name and an environment run list."
+ show_usage
+ exit 1
+ elsif @name_args.size > 1
+ # Check for nested lists and create a single plain one
+ entries = @name_args[1..-1].map do |entry|
+ entry.split(',').map { |e| e.strip }
+ end.flatten
+ else
+ # Convert to array and remove the extra spaces
+ entries = @name_args[1].split(',').map { |e| e.strip }
+ end
+
+ set_env_run_list(role, environment, entries )
+ role.save
+ config[:env_run_list] = true
+ output(format_for_display(role))
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/knife/search.rb b/lib/chef/knife/search.rb
index 34d12168b6..caca99b4d8 100644
--- a/lib/chef/knife/search.rb
+++ b/lib/chef/knife/search.rb
@@ -53,7 +53,7 @@ class Chef
:short => "-R INT",
:long => "--rows INT",
:description => "The number of rows to return",
- :default => 1000,
+ :default => nil,
:proc => lambda { |i| i.to_i }
option :run_list,
@@ -92,9 +92,9 @@ class Chef
result_count = 0
search_args = Hash.new
- search_args[:sort] = config[:sort]
- search_args[:start] = config[:start]
- search_args[:rows] = config[:rows]
+ search_args[:sort] = config[:sort] if config[:sort]
+ search_args[:start] = config[:start] if config[:start]
+ search_args[:rows] = config[:rows] if config[:rows]
if config[:filter_result]
search_args[:filter_result] = create_result_filter(config[:filter_result])
elsif (not ui.config[:attribute].nil?) && (not ui.config[:attribute].empty?)
diff --git a/lib/chef/knife/serve.rb b/lib/chef/knife/serve.rb
index 870177e0be..84918e2ef2 100644
--- a/lib/chef/knife/serve.rb
+++ b/lib/chef/knife/serve.rb
@@ -4,6 +4,9 @@ require 'chef/local_mode'
class Chef
class Knife
class Serve < Knife
+
+ banner 'knife serve (options)'
+
option :repo_mode,
:long => '--repo-mode MODE',
:description => "Specifies the local repository layout. Values: static (only environments/roles/data_bags/cookbooks), everything (includes nodes/clients/users), hosted_everything (includes acls/groups/etc. for Enterprise/Hosted Chef). Default: everything/hosted_everything"
diff --git a/lib/chef/knife/ssh.rb b/lib/chef/knife/ssh.rb
index de4c60d998..4569cc097e 100644
--- a/lib/chef/knife/ssh.rb
+++ b/lib/chef/knife/ssh.rb
@@ -313,7 +313,7 @@ class Chef
puts
puts "To exit interactive mode, use 'quit!'"
puts
- while 1
+ loop do
command = read_line
case command
when 'quit!'
diff --git a/lib/chef/knife/ssl_check.rb b/lib/chef/knife/ssl_check.rb
index f2d368ff39..c5fe4fc1aa 100644
--- a/lib/chef/knife/ssl_check.rb
+++ b/lib/chef/knife/ssl_check.rb
@@ -162,7 +162,7 @@ We are working on documentation for resolving common issues uncovered here.
server's certificate. By default, the certificate is stored in the following
location on the host where your chef-server runs:
- /var/opt/chef-server/nginx/ca/SERVER_HOSTNAME.crt
+ /var/opt/opscode/nginx/ca/SERVER_HOSTNAME.crt
Copy that file to your trusted_certs_dir (currently: #{configuration.trusted_certs_dir})
using SSH/SCP or some other secure method, then re-run this command to confirm
@@ -191,7 +191,7 @@ configure chef to trust that server's certificate.
By default, the certificate is stored in the following location on the host
where your chef-server runs:
- /var/opt/chef-server/nginx/ca/SERVER_HOSTNAME.crt
+ /var/opt/opscode/nginx/ca/SERVER_HOSTNAME.crt
Copy that file to your trusted_certs_dir (currently: #{configuration.trusted_certs_dir})
using SSH/SCP or some other secure method, then re-run this command to confirm
diff --git a/lib/chef/knife/ssl_fetch.rb b/lib/chef/knife/ssl_fetch.rb
index 5626a5610d..fd7d101fd8 100644
--- a/lib/chef/knife/ssl_fetch.rb
+++ b/lib/chef/knife/ssl_fetch.rb
@@ -16,7 +16,7 @@
# limitations under the License.
#
-require 'chef/knife/ssl_fetch'
+require 'chef/knife'
require 'chef/config'
class Chef
@@ -136,6 +136,19 @@ TRUST_TRUST
remote_cert_chain.each do |cert|
write_cert(cert)
end
+ rescue OpenSSL::SSL::SSLError => e
+ # 'unknown protocol' usually means you tried to connect to a non-ssl
+ # service. We handle that specially here, any other error we let bubble
+ # up (probably a bug of some sort).
+ raise unless e.message.include?("unknown protocol")
+
+ ui.error("The service at the given URI (#{uri}) does not accept SSL connections")
+
+ if uri.scheme == "http"
+ https_uri = uri.to_s.sub(/^http/, 'https')
+ ui.error("Perhaps you meant to connect to '#{https_uri}'?")
+ end
+ exit 1
end
diff --git a/lib/chef/log.rb b/lib/chef/log.rb
index 131d706a5e..682afcea4b 100644
--- a/lib/chef/log.rb
+++ b/lib/chef/log.rb
@@ -19,6 +19,7 @@
require 'logger'
require 'chef/monologger'
+require 'chef/exceptions'
require 'mixlib/log'
class Chef
@@ -34,6 +35,14 @@ class Chef
end
end
+ def self.deprecation(msg=nil, &block)
+ if Chef::Config[:treat_deprecation_warnings_as_errors]
+ error(msg, &block)
+ raise Chef::Exceptions::DeprecatedFeatureError.new(msg)
+ else
+ warn(msg, &block)
+ end
+ end
+
end
end
-
diff --git a/lib/chef/mixin/command.rb b/lib/chef/mixin/command.rb
index c92315e718..d9a9c4f006 100644
--- a/lib/chef/mixin/command.rb
+++ b/lib/chef/mixin/command.rb
@@ -82,7 +82,7 @@ class Chef
end
# works same as above, except that it returns stdout and stderr
- # requirement => platforms like solaris 9,10 has wierd issues where
+ # requirement => platforms like solaris 9,10 has weird issues where
# even in command failure the exit code is zero, so we need to lookup stderr.
def run_command_and_return_stdout_stderr(args={})
command_output = ""
diff --git a/lib/chef/mixin/command/windows.rb b/lib/chef/mixin/command/windows.rb
index e3d0cfdb18..0147d58039 100644
--- a/lib/chef/mixin/command/windows.rb
+++ b/lib/chef/mixin/command/windows.rb
@@ -18,11 +18,7 @@
# limitations under the License.
#
-if RUBY_VERSION =~ /^1\.8/
- require 'win32/open3'
-else
- require 'open3'
-end
+require 'open3'
class Chef
module Mixin
diff --git a/lib/chef/mixin/get_source_from_package.rb b/lib/chef/mixin/get_source_from_package.rb
index 6d5cb56a27..2ed251854a 100644
--- a/lib/chef/mixin/get_source_from_package.rb
+++ b/lib/chef/mixin/get_source_from_package.rb
@@ -29,6 +29,7 @@ class Chef
module GetSourceFromPackage
def initialize(new_resource, run_context)
super
+ return if new_resource.package_name.is_a?(Array)
# if we're passed something that looks like a filesystem path, with no source, use it
# - require at least one '/' in the path to avoid gem_package "foo" breaking if a file named 'foo' exists in the cwd
if new_resource.source.nil? && new_resource.package_name.match(/#{::File::SEPARATOR}/) && ::File.exists?(new_resource.package_name)
diff --git a/lib/chef/mixin/params_validate.rb b/lib/chef/mixin/params_validate.rb
index bedc67f357..78d72dc801 100644
--- a/lib/chef/mixin/params_validate.rb
+++ b/lib/chef/mixin/params_validate.rb
@@ -42,8 +42,8 @@ class Chef
# method names.
# :required:: Raise an exception if this parameter is missing. Valid values are true or false,
# by default, options are not required.
- # :regex:: Match the value of the paramater against a regular expression.
- # :equal_to:: Match the value of the paramater with ==. An array means it can be equal to any
+ # :regex:: Match the value of the parameter against a regular expression.
+ # :equal_to:: Match the value of the parameter with ==. An array means it can be equal to any
# of the values.
def validate(opts, map)
#--
diff --git a/lib/chef/mixin/securable.rb b/lib/chef/mixin/securable.rb
index f77703f21a..aaedf0b9ba 100644
--- a/lib/chef/mixin/securable.rb
+++ b/lib/chef/mixin/securable.rb
@@ -111,13 +111,7 @@ class Chef
# equivalent to something like:
# def rights(permissions=nil, principals=nil, args_hash=nil)
- define_method(name) do |*args|
- # Ruby 1.8 compat: default the arguments
- permissions = args.length >= 1 ? args[0] : nil
- principals = args.length >= 2 ? args[1] : nil
- args_hash = args.length >= 3 ? args[2] : nil
- raise ArgumentError.new("wrong number of arguments (#{args.length} for 3)") if args.length >= 4
-
+ define_method(name) do |permissions=nil, principals=nil, args_hash=nil|
rights = self.instance_variable_get("@#{name.to_s}".to_sym)
unless permissions.nil?
input = {
diff --git a/lib/chef/mixin/shell_out.rb b/lib/chef/mixin/shell_out.rb
index 5b05e788db..d3c14fa408 100644
--- a/lib/chef/mixin/shell_out.rb
+++ b/lib/chef/mixin/shell_out.rb
@@ -36,9 +36,15 @@ class Chef
options[env_key] ||= {}
options[env_key] = options[env_key].dup
options[env_key]['LC_ALL'] ||= Chef::Config[:internal_locale] unless options[env_key].has_key?('LC_ALL')
+ options[env_key]['LANGUAGE'] ||= Chef::Config[:internal_locale] unless options[env_key].has_key?('LANGUAGE')
+ options[env_key]['LANG'] ||= Chef::Config[:internal_locale] unless options[env_key].has_key?('LANG')
args << options
else
- args << { :environment => { 'LC_ALL' => Chef::Config[:internal_locale] } }
+ args << { :environment => {
+ 'LC_ALL' => Chef::Config[:internal_locale],
+ 'LANGUAGE' => Chef::Config[:internal_locale],
+ 'LANG' => Chef::Config[:internal_locale],
+ } }
end
shell_out_command(*args)
diff --git a/lib/chef/mixin/template.rb b/lib/chef/mixin/template.rb
index ae23336581..d705a9e7be 100644
--- a/lib/chef/mixin/template.rb
+++ b/lib/chef/mixin/template.rb
@@ -23,18 +23,6 @@ class Chef
module Mixin
module Template
- # A compatibility wrapper around IO.binread so it works on Ruby 1.8.7.
- # --
- # Used in the TemplateContext class, but that method namespace is shared
- # with user code, so we want to avoid adding methods there when possible.
- def self.binread(file)
- if IO.respond_to?(:binread)
- IO.binread(file)
- else
- File.open(file, "rb") {|f| f.read }
- end
- end
-
# == ChefContext
# ChefContext was previously used to mix behavior into Erubis::Context so
# that it would be available to templates. This behavior has now moved to
@@ -105,11 +93,11 @@ class Chef
partial_context._extend_modules(@_extension_modules)
template_location = @template_finder.find(partial_name, options)
- _render_template(Mixin::Template.binread(template_location), partial_context)
+ _render_template(IO.binread(template_location), partial_context)
end
def render_template(template_location)
- _render_template(Mixin::Template.binread(template_location), self)
+ _render_template(IO.binread(template_location), self)
end
def render_template_from_string(template)
diff --git a/lib/chef/mixin/why_run.rb b/lib/chef/mixin/why_run.rb
index d650e3332f..d3acea5490 100644
--- a/lib/chef/mixin/why_run.rb
+++ b/lib/chef/mixin/why_run.rb
@@ -48,7 +48,7 @@ class Chef
# block/proc that implements the action.
def add_action(descriptions, &block)
@actions << [descriptions, block]
- if !Chef::Config[:why_run]
+ if (@resource.respond_to?(:is_guard_interpreter) && @resource.is_guard_interpreter) || !Chef::Config[:why_run]
block.call
end
events.resource_update_applied(@resource, @action, descriptions)
diff --git a/lib/chef/monkey_patches/fileutils.rb b/lib/chef/monkey_patches/fileutils.rb
deleted file mode 100644
index f18bead144..0000000000
--- a/lib/chef/monkey_patches/fileutils.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# Author:: Stephen Delano (<stephen@opscode.com>)
-# Copyright:: Copyright (c) 2012 Opscode, 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.
-#
-
-# == FileUtils::Entry_ (Patch)
-# On Ruby 1.9.3 and earlier, FileUtils.cp_r(foo, bar, :preserve => true) fails
-# when attempting to copy a directory containing symlinks. This has been
-# patched in the trunk of Ruby, and this is a monkey patch of the offending
-# code.
-
-unless RUBY_VERSION =~ /^2/
- require 'fileutils'
-
- class FileUtils::Entry_
- def copy_metadata(path)
- st = lstat()
- if !st.symlink?
- File.utime st.atime, st.mtime, path
- end
- begin
- if st.symlink?
- begin
- File.lchown st.uid, st.gid, path
- rescue NotImplementedError
- end
- else
- File.chown st.uid, st.gid, path
- end
- rescue Errno::EPERM
- # clear setuid/setgid
- if st.symlink?
- begin
- File.lchmod st.mode & 01777, path
- rescue NotImplementedError
- end
- else
- File.chmod st.mode & 01777, path
- end
- else
- if st.symlink?
- begin
- File.lchmod st.mode, path
- rescue NotImplementedError
- end
- else
- File.chmod st.mode, path
- end
- end
- end
- end
-end
diff --git a/lib/chef/monkey_patches/net_http.rb b/lib/chef/monkey_patches/net_http.rb
index 083db2216b..9c8044a9a7 100644
--- a/lib/chef/monkey_patches/net_http.rb
+++ b/lib/chef/monkey_patches/net_http.rb
@@ -42,6 +42,10 @@ if Net::HTTP.instance_methods.map {|m| m.to_s}.include?("proxy_uri")
# from -e:1:in `<main>'
#
# https://bugs.ruby-lang.org/issues/9129
+ #
+ # NOTE: This should be fixed in Ruby 2.2.0, and backported to Ruby 2.0 and
+ # 2.1 (not yet released so the version/patchlevel required isn't known
+ # yet).
Net::HTTP.new("::1", 80).proxy_uri
rescue URI::InvalidURIError
class Net::HTTP
diff --git a/lib/chef/monkey_patches/numeric.rb b/lib/chef/monkey_patches/numeric.rb
deleted file mode 100644
index f4612fdbf3..0000000000
--- a/lib/chef/monkey_patches/numeric.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-unless 0.respond_to?(:fdiv)
- class Numeric
- def fdiv(other)
- to_f / other
- end
- end
-end
-
-# String elements referenced with [] <= 1.8.6 return a Fixnum. Cheat to allow
-# for the simpler "test"[2].ord construct
-class Numeric
- def ord
- return self
- end
-end
diff --git a/lib/chef/monkey_patches/object.rb b/lib/chef/monkey_patches/object.rb
deleted file mode 100644
index 017a4b7938..0000000000
--- a/lib/chef/monkey_patches/object.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class Object
- unless new.respond_to?(:tap)
- def tap
- yield self
- return self
- end
- end
-end
-
diff --git a/lib/chef/monkey_patches/pathname.rb b/lib/chef/monkey_patches/pathname.rb
deleted file mode 100644
index c0255ae7ea..0000000000
--- a/lib/chef/monkey_patches/pathname.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-require 'pathname'
-
-if RUBY_VERSION.to_f < 1.9
- class Pathname
- @@old_each_filename = instance_method(:each_filename)
-
- def each_filename(&block)
- if block_given?
- EachFilenameEnumerable.new(self).each(&block)
- else
- EachFilenameEnumerable.new(self)
- end
- end
-
- def old_each_filename(&block)
- @@old_each_filename.bind(self).call(&block)
- end
-
- class EachFilenameEnumerable
- include Enumerable
- attr_reader :pathname
-
- def initialize(pathname)
- @pathname = pathname
- end
-
- def each(&block)
- @pathname.old_each_filename(&block)
- end
- end
- end
-end
diff --git a/lib/chef/monkey_patches/regexp.rb b/lib/chef/monkey_patches/regexp.rb
deleted file mode 100644
index 8a7ee77cb5..0000000000
--- a/lib/chef/monkey_patches/regexp.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (c) 2009 Marc-Andre Lafortune
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-class Regexp
- # Standard in Ruby 1.8.7+. See official documentation[http://www.ruby-doc.org/core-1.8.7/classes/Regexp.html]
- class << self
- unless (union(%w(a b)) rescue false)
- alias :union_without_array_argument :union
-
- def union(*arg)
- return union_without_array_argument(*arg) unless arg.size == 1
- union_without_array_argument(*arg.first)
- end
- end
- end
-end
diff --git a/lib/chef/monkey_patches/securerandom.rb b/lib/chef/monkey_patches/securerandom.rb
deleted file mode 100644
index 7a41a1dbb0..0000000000
--- a/lib/chef/monkey_patches/securerandom.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Author:: James Casey <james@opscode.com>
-# Copyright:: Copyright (c) 2013 Opscode, 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.
-#
-
-# == SecureRandom (Patch)
-# On ruby 1.9, SecureRandom has a uuid method which generates a v4 UUID. The
-# backport of SecureRandom to 1.8.7 is missing this method
-
-require 'securerandom'
-
-module SecureRandom
- unless respond_to?(:uuid)
- # SecureRandom.uuid generates a v4 random UUID (Universally Unique IDentifier).
- #
- # p SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
- # p SecureRandom.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
- # p SecureRandom.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"
- #
- # The version 4 UUID is purely random (except the version).
- # It doesn't contain meaningful information such as MAC address, time, etc.
- #
- # See RFC 4122 for details of UUID.
- def self.uuid
- ary = self.random_bytes(16).unpack("NnnnnN")
- ary[2] = (ary[2] & 0x0fff) | 0x4000
- ary[3] = (ary[3] & 0x3fff) | 0x8000
- "%08x-%04x-%04x-%04x-%04x%08x" % ary
- end
- end
-end
diff --git a/lib/chef/monkey_patches/string.rb b/lib/chef/monkey_patches/string.rb
deleted file mode 100644
index f91e27ddc5..0000000000
--- a/lib/chef/monkey_patches/string.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-#
-# Author:: Adam Jacob (<adam@opscode.com>)
-# Copyright:: Copyright (c) 2008 Opscode, 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.
-#
-
-# == String (Patch)
-# On ruby 1.9, Strings are aware of multibyte characters, so +size+ and +length+
-# give the actual number of characters. In Chef::REST, we need the bytesize
-# so we can correctly set the Content-Length headers, but ruby 1.8.6 and lower
-# don't define String#bytesize. Monkey patching time!
-
-begin
- require 'enumerator'
-rescue LoadError
-end
-
-class String
- unless method_defined?(:bytesize)
- alias :bytesize :size
- end
-
- unless method_defined?(:lines)
- def lines
- enum_for(:each)
- end
- end
-end
-
-# <= 1.8.6 needs some ord!
-class String
- unless method_defined?(:ord)
- def ord
- self.unpack('C').first
- end
- end
-end
diff --git a/lib/chef/monkey_patches/tempfile.rb b/lib/chef/monkey_patches/tempfile.rb
deleted file mode 100644
index b9179f182b..0000000000
--- a/lib/chef/monkey_patches/tempfile.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-#
-# Author:: Adam Jacob (<adam@opscode.com>)
-# Copyright:: Copyright (c) 2008 Opscode, 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.
-#
-
-# == Tempfile (Patch)
-# Tempfile has a horrible bug where it causes an IOError: closed stream in its
-# finalizer, leading to intermittent application crashes with confusing stack
-# traces. Here we monkey patch the fix into place. You can track the bug on
-# ruby's redmine: http://redmine.ruby-lang.org/issues/show/3119
-#
-# The patch is slightly different for Ruby 1.8 and Ruby 1.9, both patches are
-# included here.
-class Tempfile # :nodoc:
- # Tempfile has changes between 1.8.x and 1.9.x
- # so we monkey patch separately
- if RUBY_VERSION =~ /^1\.8/
- def unlink
- # keep this order for thread safeness
- begin
- File.unlink(@tmpname) if File.exist?(@tmpname)
- @@cleanlist.delete(@tmpname)
- @tmpname = nil
- ObjectSpace.undefine_finalizer(self)
- rescue Errno::EACCES
- # may not be able to unlink on Windows; just ignore
- end
- end
- alias delete unlink
-
-
- # There is a patch for this, to be merged into 1.9 at some point.
- # When that happens, we'll want to also check the RUBY_PATCHLEVEL
- elsif RUBY_VERSION =~ /^1\.9/
- def unlink
- # keep this order for thread safeness
- return unless @tmpname
- begin
- if File.exist?(@tmpname)
- File.unlink(@tmpname)
- end
- # remove tmpname from remover
- @data[0] = @data[2] = nil
- @tmpname = nil
- rescue Errno::EACCES
- # may not be able to unlink on Windows; just ignore
- end
- end
- alias delete unlink
- end
-end
diff --git a/lib/chef/monkey_patches/uri.rb b/lib/chef/monkey_patches/uri.rb
deleted file mode 100644
index 158285e395..0000000000
--- a/lib/chef/monkey_patches/uri.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-# Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
-# You can redistribute it and/or modify it under either the terms of the
-# 2-clause BSDL (see the file BSDL), or the conditions below:
-#
-# 1. You may make and give away verbatim copies of the source form of the
-# software without restriction, provided that you duplicate all of the
-# original copyright notices and associated disclaimers.
-#
-# 2. You may modify your copy of the software in any way, provided that
-# you do at least ONE of the following:
-#
-# a) place your modifications in the Public Domain or otherwise
-# make them Freely Available, such as by posting said
-# modifications to Usenet or an equivalent medium, or by allowing
-# the author to include your modifications in the software.
-#
-# b) use the modified software only within your corporation or
-# organization.
-#
-# c) give non-standard binaries non-standard names, with
-# instructions on where to get the original software distribution.
-#
-# d) make other distribution arrangements with the author.
-#
-# 3. You may distribute the software in object code or binary form,
-# provided that you do at least ONE of the following:
-#
-# a) distribute the binaries and library files of the software,
-# together with instructions (in the manual page or equivalent)
-# on where to get the original distribution.
-#
-# b) accompany the distribution with the machine-readable source of
-# the software.
-#
-# c) give non-standard binaries non-standard names, with
-# instructions on where to get the original software distribution.
-#
-# d) make other distribution arrangements with the author.
-#
-# 4. You may modify and include the part of the software into any other
-# software (possibly commercial). But some files in the distribution
-# are not written by the author, so that they are not under these terms.
-#
-# For the list of those files and their copying conditions, see the
-# file LEGAL.
-#
-# 5. The scripts and library files supplied as input to or produced as
-# output from the software do not automatically fall under the
-# copyright of the software, but belong to whomever generated them,
-# and may be sold commercially, and may be aggregated with this
-# software.
-#
-# 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE.
-
-require 'uri'
-
-unless URI::Generic.instance_methods.map {|m| m.to_s}.include?("hostname")
-
- class URI::Generic
- # Copied from the MRI source for Ruby 1.9.3
- # File lib/uri/generic.rb, line 659
- def hostname
- v = self.host
- /\A\[(.*)\]\z/ =~ v ? $1 : v
- end
- end
-end
diff --git a/lib/chef/monologger.rb b/lib/chef/monologger.rb
index 464b21bdd3..f7d226f82e 100644
--- a/lib/chef/monologger.rb
+++ b/lib/chef/monologger.rb
@@ -1,5 +1,4 @@
require 'logger'
-
require 'pp'
#== MonoLogger
@@ -89,4 +88,3 @@ class MonoLogger < Logger
end
-
diff --git a/lib/chef/node.rb b/lib/chef/node.rb
index 6055f0e1e9..f9f6416f14 100644
--- a/lib/chef/node.rb
+++ b/lib/chef/node.rb
@@ -47,6 +47,8 @@ class Chef
attr_accessor :recipe_list, :run_state, :override_runlist
+ attr_accessor :chef_server_rest
+
# RunContext will set itself as run_context via this setter when
# initialized. This is needed so DSL::IncludeAttribute (in particular,
# #include_recipe) can access the run_context to determine if an attributes
@@ -62,7 +64,8 @@ class Chef
include Chef::Mixin::ParamsValidate
# Create a new Chef::Node object.
- def initialize
+ def initialize(chef_server_rest: nil)
+ @chef_server_rest = chef_server_rest
@name = nil
@chef_environment = '_default'
@@ -80,7 +83,7 @@ class Chef
end
def chef_server_rest
- Chef::REST.new(Chef::Config[:chef_server_url])
+ @chef_server_rest ||= Chef::REST.new(Chef::Config[:chef_server_url])
end
# Set the name of this Node, or return the current name.
diff --git a/lib/chef/node/attribute.rb b/lib/chef/node/attribute.rb
index 3c48f653eb..45f2ef01ee 100644
--- a/lib/chef/node/attribute.rb
+++ b/lib/chef/node/attribute.rb
@@ -138,11 +138,9 @@ class Chef
:values,
:values_at,
:zip].each do |delegated_method|
- class_eval(<<-METHOD_DEFN)
- def #{delegated_method}(*args, &block)
- merged_attributes.send(:#{delegated_method}, *args, &block)
- end
- METHOD_DEFN
+ define_method(delegated_method) do |*args, &block|
+ merged_attributes.send(delegated_method, *args, &block)
+ end
end
# return the cookbook level default attribute component
@@ -253,7 +251,7 @@ class Chef
if path.nil?
@deep_merge_cache = {}
else
- deep_merge_cache.delete(path)
+ deep_merge_cache.delete(path.to_s)
end
end
@@ -436,12 +434,12 @@ class Chef
end
def [](key)
- if deep_merge_cache.has_key?(key)
+ if deep_merge_cache.has_key?(key.to_s)
# return the cache of the deep merged values by top-level key
- deep_merge_cache[key]
+ deep_merge_cache[key.to_s]
else
# save all the work of computing node[key]
- deep_merge_cache[key] = merged_attributes(key)
+ deep_merge_cache[key.to_s] = merged_attributes(key)
end
end
@@ -477,6 +475,10 @@ class Chef
end
end
+ def to_s
+ merged_attributes.to_s
+ end
+
def inspect
"#<#{self.class} " << (COMPONENTS + [:@merged_attributes, :@properties]).map{|iv|
"#{iv}=#{instance_variable_get(iv).inspect}"
diff --git a/lib/chef/node/attribute_collections.rb b/lib/chef/node/attribute_collections.rb
index 333f4864c6..b912904534 100644
--- a/lib/chef/node/attribute_collections.rb
+++ b/lib/chef/node/attribute_collections.rb
@@ -61,12 +61,10 @@ class Chef
# also invalidate the cached merged_attributes on the root
# Node::Attribute object.
MUTATOR_METHODS.each do |mutator|
- class_eval(<<-METHOD_DEFN, __FILE__, __LINE__)
- def #{mutator}(*args, &block)
- root.reset_cache(root.top_level_breadcrumb)
- super
- end
- METHOD_DEFN
+ define_method(mutator) do |*args, &block|
+ root.reset_cache(root.top_level_breadcrumb)
+ super(*args, &block)
+ end
end
attr_reader :root
@@ -126,12 +124,10 @@ class Chef
# also invalidate the cached `merged_attributes` on the root Attribute
# object.
MUTATOR_METHODS.each do |mutator|
- class_eval(<<-METHOD_DEFN, __FILE__, __LINE__)
- def #{mutator}(*args, &block)
- root.reset_cache(root.top_level_breadcrumb)
- super
- end
- METHOD_DEFN
+ define_method(mutator) do |*args, &block|
+ root.reset_cache(root.top_level_breadcrumb)
+ super(*args, &block)
+ end
end
def initialize(root, data={})
diff --git a/lib/chef/node/immutable_collections.rb b/lib/chef/node/immutable_collections.rb
index 56b8fed3b7..0e2800641a 100644
--- a/lib/chef/node/immutable_collections.rb
+++ b/lib/chef/node/immutable_collections.rb
@@ -75,12 +75,9 @@ class Chef
# Redefine all of the methods that mutate a Hash to raise an error when called.
# This is the magic that makes this object "Immutable"
DISALLOWED_MUTATOR_METHODS.each do |mutator_method_name|
- # Ruby 1.8 blocks can't have block arguments, so we must use string eval:
- class_eval(<<-METHOD_DEFN, __FILE__, __LINE__)
- def #{mutator_method_name}(*args, &block)
- raise Exceptions::ImmutableAttributeModification
- end
- METHOD_DEFN
+ define_method(mutator_method_name) do |*args, &block|
+ raise Exceptions::ImmutableAttributeModification
+ end
end
# For elements like Fixnums, true, nil...
@@ -164,12 +161,9 @@ class Chef
# Redefine all of the methods that mutate a Hash to raise an error when called.
# This is the magic that makes this object "Immutable"
DISALLOWED_MUTATOR_METHODS.each do |mutator_method_name|
- # Ruby 1.8 blocks can't have block arguments, so we must use string eval:
- class_eval(<<-METHOD_DEFN, __FILE__, __LINE__)
- def #{mutator_method_name}(*args, &block)
+ define_method(mutator_method_name) do |*args, &block|
raise Exceptions::ImmutableAttributeModification
end
- METHOD_DEFN
end
def method_missing(symbol, *args)
diff --git a/lib/chef/org.rb b/lib/chef/org.rb
new file mode 100644
index 0000000000..41d74b6186
--- /dev/null
+++ b/lib/chef/org.rb
@@ -0,0 +1,148 @@
+#
+# Author:: Steven Danna (steve@opscode.com)
+# Copyright:: Copyright (c) 2014 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/json_compat'
+require 'chef/mixin/params_validate'
+require 'chef/rest'
+
+class Chef
+ class Org
+
+ include Chef::Mixin::ParamsValidate
+
+ def initialize(name)
+ @name = name
+ @full_name = ''
+ # The Chef API returns the private key of the validator
+ # client on create
+ @private_key = nil
+ @guid = nil
+ end
+
+ def chef_rest
+ @chef_rest ||= Chef::REST.new(Chef::Config[:chef_server_root])
+ end
+
+ def name(arg=nil)
+ set_or_return(:name, arg,
+ :regex => /^[a-z0-9\-_]+$/)
+ end
+
+ def full_name(arg=nil)
+ set_or_return(:full_name,
+ arg, :kind_of => String)
+ end
+
+ def private_key(arg=nil)
+ set_or_return(:private_key,
+ arg, :kind_of => String)
+ end
+
+ def guid(arg=nil)
+ set_or_return(:guid,
+ arg, :kind_of => String)
+ end
+
+ def to_hash
+ result = {
+ "name" => @name,
+ "full_name" => @full_name
+ }
+ result["private_key"] = @private_key if @private_key
+ result["guid"] = @guid if @guid
+ result
+ end
+
+ def to_json(*a)
+ Chef::JSONCompat.to_json(to_hash, *a)
+ end
+
+ def create
+ payload = {:name => self.name, :full_name => self.full_name}
+ new_org = chef_rest.post_rest("organizations", payload)
+ Chef::Org.from_hash(self.to_hash.merge(new_org))
+ end
+
+ def update
+ payload = {:name => self.name, :full_name => self.full_name}
+ new_org = chef_rest.put_rest("organizations/#{name}", payload)
+ Chef::Org.from_hash(self.to_hash.merge(new_org))
+ end
+
+ def destroy
+ chef_rest.delete_rest("organizations/#{@name}")
+ end
+
+ def save
+ begin
+ create
+ rescue Net::HTTPServerException => e
+ if e.response.code == "409"
+ update
+ else
+ raise e
+ end
+ end
+ end
+
+ def associate_user(username)
+ request_body = {:user => username}
+ response = chef_rest.post_rest "organizations/#{@name}/association_requests", request_body
+ association_id = response["uri"].split("/").last
+ chef_rest.put_rest "users/#{username}/association_requests/#{association_id}", { :response => 'accept' }
+ end
+
+ def dissociate_user(username)
+ chef_rest.delete_rest "organizations/#{name}/users/#{username}"
+ end
+
+ # Class methods
+ def self.from_hash(org_hash)
+ org = Chef::Org.new(org_hash['name'])
+ org.full_name org_hash['full_name']
+ org.private_key org_hash['private_key'] if org_hash.key?('private_key')
+ org.guid org_hash['guid'] if org_hash.key?('guid')
+ org
+ end
+
+ def self.from_json(json)
+ Chef::Org.from_hash(Chef::JSONCompat.from_json(json))
+ end
+
+ class <<self
+ alias_method :json_create, :from_json
+ end
+
+ def self.load(org_name)
+ response = Chef::REST.new(Chef::Config[:chef_server_root]).get_rest("organizations/#{org_name}")
+ Chef::Org.from_hash(response)
+ end
+
+ def self.list(inflate=false)
+ orgs = Chef::REST.new(Chef::Config[:chef_server_root]).get_rest('organizations')
+ if inflate
+ orgs.inject({}) do |org_map, (name, _url)|
+ org_map[name] = Chef::Org.load(name)
+ org_map
+ end
+ else
+ orgs
+ end
+ end
+ end
+end
diff --git a/lib/chef/platform/provider_mapping.rb b/lib/chef/platform/provider_mapping.rb
index 382df342f5..3d8212e24f 100644
--- a/lib/chef/platform/provider_mapping.rb
+++ b/lib/chef/platform/provider_mapping.rb
@@ -365,7 +365,9 @@ class Chef
},
:openbsd => {
:default => {
- :group => Chef::Provider::Group::Usermod
+ :group => Chef::Provider::Group::Usermod,
+ :package => Chef::Provider::Package::Openbsd,
+ :service => Chef::Provider::Service::Openbsd
}
},
:hpux => {
@@ -471,7 +473,6 @@ class Chef
def provider_for_node(node, resource_type)
raise NotImplementedError, "#{self.class.name} no longer supports #provider_for_node"
- find_provider_for_node(node, resource_type).new(node, resource_type)
end
def find_provider_for_node(node, resource_type)
diff --git a/lib/chef/platform/provider_priority_map.rb b/lib/chef/platform/provider_priority_map.rb
index 765dd74859..2517f46dfd 100644
--- a/lib/chef/platform/provider_priority_map.rb
+++ b/lib/chef/platform/provider_priority_map.rb
@@ -54,6 +54,7 @@ class Chef
#
priority :service, Chef::Provider::Service::Freebsd, os: [ "freebsd", "netbsd" ]
+ priority :service, Chef::Provider::Service::Openbsd, os: [ "openbsd" ]
#
# Solaris-en
@@ -66,6 +67,7 @@ class Chef
#
priority :service, Chef::Provider::Service::Macosx, os: "darwin"
+ priority :package, Chef::Provider::Package::Homebrew, os: "darwin"
end
def priority_map
diff --git a/lib/chef/platform/query_helpers.rb b/lib/chef/platform/query_helpers.rb
index 334ab278d1..ff83c871fa 100644
--- a/lib/chef/platform/query_helpers.rb
+++ b/lib/chef/platform/query_helpers.rb
@@ -35,14 +35,11 @@ class Chef
# CHEF-4888: Work around ruby #2618, expected to be fixed in Ruby 2.1.0
# https://github.com/ruby/ruby/commit/588504b20f5cc880ad51827b93e571e32446e5db
# https://github.com/ruby/ruby/commit/27ed294c7134c0de582007af3c915a635a6506cd
- WIN32OLE.ole_initialize
wmi = WmiLite::Wmi.new
host = wmi.first_of('Win32_OperatingSystem')
is_server_2003 = (host['version'] && host['version'].start_with?("5.2"))
- WIN32OLE.ole_uninitialize
-
is_server_2003
end
diff --git a/lib/chef/policy_builder/policyfile.rb b/lib/chef/policy_builder/policyfile.rb
index 0df3dd5dd2..d368b055f7 100644
--- a/lib/chef/policy_builder/policyfile.rb
+++ b/lib/chef/policy_builder/policyfile.rb
@@ -237,7 +237,12 @@ class Chef
end
def policyfile_location
- "data/policyfiles/#{deployment_group}"
+ if Chef::Config[:policy_document_native_api]
+ validate_policy_config!
+ "policies/#{policy_group}/#{policy_name}"
+ else
+ "data/policyfiles/#{deployment_group}"
+ end
end
# Do some mimimal validation of the policyfile we fetched from the
@@ -281,6 +286,22 @@ class Chef
raise ConfigurationError, "Setting `deployment_group` is not configured."
end
+ def validate_policy_config!
+ policy_group or
+ raise ConfigurationError, "Setting `policy_group` is not configured."
+
+ policy_name or
+ raise ConfigurationError, "Setting `policy_name` is not configured."
+ end
+
+ def policy_group
+ Chef::Config[:policy_group]
+ end
+
+ def policy_name
+ Chef::Config[:policy_name]
+ end
+
# Builds a 'cookbook_hash' map of the form
# "COOKBOOK_NAME" => "IDENTIFIER"
#
@@ -314,13 +335,11 @@ class Chef
# cookbooks are fetched by the "dotted_decimal_identifier": a
# representation of a SHA1 in the traditional x.y.z version format.
def manifest_for(cookbook_name, lock_data)
- xyz_version = lock_data["dotted_decimal_identifier"]
- http_api.get("cookbooks/#{cookbook_name}/#{xyz_version}")
- rescue Exception => e
- message = "Error loading cookbook #{cookbook_name} at version #{xyz_version}: #{e.class} - #{e.message}"
- err = Chef::Exceptions::CookbookNotFound.new(message)
- err.set_backtrace(e.backtrace)
- raise err
+ if Chef::Config[:policy_document_native_api]
+ artifact_manifest_for(cookbook_name, lock_data)
+ else
+ compat_mode_manifest_for(cookbook_name, lock_data)
+ end
end
def cookbook_locks
@@ -335,6 +354,30 @@ class Chef
Chef::Config
end
+ private
+
+ def compat_mode_manifest_for(cookbook_name, lock_data)
+ xyz_version = lock_data["dotted_decimal_identifier"]
+ rel_url = "cookbooks/#{cookbook_name}/#{xyz_version}"
+ http_api.get(rel_url)
+ rescue Exception => e
+ message = "Error loading cookbook #{cookbook_name} at version #{xyz_version} from #{rel_url}: #{e.class} - #{e.message}"
+ err = Chef::Exceptions::CookbookNotFound.new(message)
+ err.set_backtrace(e.backtrace)
+ raise err
+ end
+
+ def artifact_manifest_for(cookbook_name, lock_data)
+ xyz_version = lock_data["dotted_decimal_identifier"]
+ rel_url = "cookbook_artifacts/#{cookbook_name}/#{xyz_version}"
+ http_api.get(rel_url)
+ rescue Exception => e
+ message = "Error loading cookbook #{cookbook_name} at version #{xyz_version} from #{rel_url}: #{e.class} - #{e.message}"
+ err = Chef::Exceptions::CookbookNotFound.new(message)
+ err.set_backtrace(e.backtrace)
+ raise err
+ end
+
end
end
end
diff --git a/lib/chef/provider/deploy.rb b/lib/chef/provider/deploy.rb
index b30f7ed17e..19e7c01ab1 100644
--- a/lib/chef/provider/deploy.rb
+++ b/lib/chef/provider/deploy.rb
@@ -18,7 +18,6 @@
require "chef/mixin/command"
require "chef/mixin/from_file"
-require "chef/monkey_patches/fileutils"
require "chef/provider/git"
require "chef/provider/subversion"
require "chef/dsl/recipe"
@@ -126,7 +125,7 @@ class Chef
# * Move release_path directory before deploy and move it back when error occurs
# * Rollback to previous commit
# * Do nothing - because deploy is force, it will be retried in short time
- # Because last is simpliest, keep it
+ # Because last is simplest, keep it
deploy
end
diff --git a/lib/chef/provider/directory.rb b/lib/chef/provider/directory.rb
index c9c3d466b9..416393ac60 100644
--- a/lib/chef/provider/directory.rb
+++ b/lib/chef/provider/directory.rb
@@ -61,7 +61,7 @@ class Chef
is_parent_writable = lambda do |base_dir|
base_dir = ::File.dirname(base_dir)
if ::File.exists?(base_dir)
- ::File.writable?(base_dir)
+ Chef::FileAccessControl.writable?(base_dir)
else
is_parent_writable.call(base_dir)
end
@@ -71,7 +71,7 @@ class Chef
# in why run mode & parent directory does not exist no permissions check is required
# If not in why run, permissions must be valid and we rely on prior assertion that dir exists
if !whyrun_mode? || ::File.exists?(parent_directory)
- ::File.writable?(parent_directory)
+ Chef::FileAccessControl.writable?(parent_directory)
else
true
end
@@ -84,7 +84,7 @@ class Chef
requirements.assert(:delete) do |a|
a.assertion do
if ::File.exists?(@new_resource.path)
- ::File.directory?(@new_resource.path) && ::File.writable?(@new_resource.path)
+ ::File.directory?(@new_resource.path) && Chef::FileAccessControl.writable?(@new_resource.path)
else
true
end
diff --git a/lib/chef/provider/dsc_script.rb b/lib/chef/provider/dsc_script.rb
index 5db50e74b3..a75e68a475 100644
--- a/lib/chef/provider/dsc_script.rb
+++ b/lib/chef/provider/dsc_script.rb
@@ -32,11 +32,11 @@ class Chef
@dsc_resource = dsc_resource
@resource_converged = false
@operations = {
- :set => Proc.new { |config_manager, document|
- config_manager.set_configuration(document)
+ :set => Proc.new { |config_manager, document, shellout_flags|
+ config_manager.set_configuration(document, shellout_flags)
},
- :test => Proc.new { |config_manager, document|
- config_manager.test_configuration(document)
+ :test => Proc.new { |config_manager, document, shellout_flags|
+ config_manager.test_configuration(document, shellout_flags)
}}
end
@@ -89,9 +89,15 @@ class Chef
config_manager = Chef::Util::DSC::LocalConfigurationManager.new(@run_context.node, config_directory)
+ shellout_flags = {
+ :cwd => @dsc_resource.cwd,
+ :environment => @dsc_resource.environment,
+ :timeout => @dsc_resource.timeout
+ }
+
begin
configuration_document = generate_configuration_document(config_directory, configuration_flags)
- @operations[operation].call(config_manager, configuration_document)
+ @operations[operation].call(config_manager, configuration_document, shellout_flags)
rescue Exception => e
Chef::Log.error("DSC operation failed: #{e.message.to_s}")
raise e
@@ -123,7 +129,7 @@ class Chef
else
# If code is also not provided, we mimic what the other script resources do (execute nothing)
Chef::Log.warn("Neither code or command were provided for dsc_resource[#{@dsc_resource.name}].") unless @dsc_resource.code
- generator.configuration_document_from_script_code(@dsc_resource.code || '', configuration_flags, shellout_flags)
+ generator.configuration_document_from_script_code(@dsc_resource.code || '', configuration_flags, @dsc_resource.imports, shellout_flags)
end
end
@@ -161,7 +167,7 @@ class Chef
cleaned_messages = resource.change_log[0..-2].map { |c| c.sub(/^#{Regexp.escape(resource.name)}/, '').strip }
"converge DSC resource #{resource.name} by #{cleaned_messages.find_all{ |c| c != ''}.join("\n")}"
else
- # This is needed because a dsc script can have resouces that are both converged and not
+ # This is needed because a dsc script can have resources that are both converged and not
"converge DSC resource #{resource.name} by doing nothing because it is already converged"
end
end
diff --git a/lib/chef/provider/env.rb b/lib/chef/provider/env.rb
index 600cac1e6b..815a19bc0c 100644
--- a/lib/chef/provider/env.rb
+++ b/lib/chef/provider/env.rb
@@ -61,9 +61,12 @@ class Chef
def requires_modify_or_create?
if @new_resource.delim
#e.g. check for existing value within PATH
- not new_values.all? do |val|
- current_values.include? val
+ new_values.inject(0) do |index, val|
+ next_index = current_values.find_index val
+ return true if next_index.nil? || next_index < index
+ next_index
end
+ false
else
@new_resource.value != @current_resource.value
end
@@ -99,9 +102,9 @@ class Chef
return true #do not delete the key
else
new_value =
- current_values.select { |item|
+ current_values.select do |item|
not new_values.include?(item)
- }.join(@new_resource.delim)
+ end.join(@new_resource.delim)
if new_value.empty?
return false #nothing left here, delete the key
@@ -145,10 +148,7 @@ class Chef
def modify_env
if @new_resource.delim
- values = new_values.reject do |v|
- current_values.include?(v)
- end
- @new_resource.value((values + [@current_resource.value]).join(@new_resource.delim))
+ @new_resource.value((new_values + current_values).uniq.join(@new_resource.delim))
end
create_env
end
diff --git a/lib/chef/provider/execute.rb b/lib/chef/provider/execute.rb
index 48b2a344d1..b44112c19e 100644
--- a/lib/chef/provider/execute.rb
+++ b/lib/chef/provider/execute.rb
@@ -18,67 +18,86 @@
require 'chef/log'
require 'chef/provider'
+require 'forwardable'
class Chef
class Provider
class Execute < Chef::Provider
+ extend Forwardable
provides :execute
+ def_delegators :@new_resource, :command, :returns, :environment, :user, :group, :cwd, :umask, :creates
+
def load_current_resource
- true
+ current_resource = Chef::Resource::Execute.new(new_resource.name)
+ current_resource
end
def whyrun_supported?
true
end
- def action_run
- opts = {}
-
- if sentinel_file = sentinel_file_if_exists
- Chef::Log.debug("#{@new_resource} sentinel file #{sentinel_file} exists - nothing to do")
- return false
- end
+ def define_resource_requirements
+ # @todo: this should change to raise in some appropriate major version bump.
+ if creates && creates_relative? && !cwd
+ Chef::Log.warn "Providing a relative path for the creates attribute without the cwd is deprecated and will be changed to fail (CHEF-3819)"
+ end
+ end
+ def timeout
# original implementation did not specify a timeout, but ShellOut
# *always* times out. So, set a very long default timeout
- opts[:timeout] = @new_resource.timeout || 3600
- opts[:returns] = @new_resource.returns if @new_resource.returns
- opts[:environment] = @new_resource.environment if @new_resource.environment
- opts[:user] = @new_resource.user if @new_resource.user
- opts[:group] = @new_resource.group if @new_resource.group
- opts[:cwd] = @new_resource.cwd if @new_resource.cwd
- opts[:umask] = @new_resource.umask if @new_resource.umask
- opts[:log_level] = :info
- opts[:log_tag] = @new_resource.to_s
- if STDOUT.tty? && !Chef::Config[:daemon] && Chef::Log.info? && !@new_resource.sensitive
- opts[:live_stream] = STDOUT
+ new_resource.timeout || 3600
+ end
+
+ def action_run
+ if creates && sentinel_file.exist?
+ Chef::Log.debug("#{new_resource} sentinel file #{sentinel_file} exists - nothing to do")
+ return false
end
- description = @new_resource.sensitive ? "sensitive resource" : @new_resource.command
+
converge_by("execute #{description}") do
- result = shell_out!(@new_resource.command, opts)
- Chef::Log.info("#{@new_resource} ran successfully")
+ result = shell_out!(command, opts)
+ Chef::Log.info("#{new_resource} ran successfully")
end
end
private
- def sentinel_file_if_exists
- if sentinel_file = @new_resource.creates
- relative = Pathname(sentinel_file).relative?
- cwd = @new_resource.cwd
- if relative && !cwd
- Chef::Log.warn "You have provided relative path for execute#creates (#{sentinel_file}) without execute#cwd (see CHEF-3819)"
- end
-
- if ::File.exists?(sentinel_file)
- sentinel_file
- elsif cwd && relative
- sentinel_file = ::File.join(cwd, sentinel_file)
- sentinel_file if ::File.exists?(sentinel_file)
- end
+ def sensitive?
+ !!new_resource.sensitive
+ end
+
+ def opts
+ opts = {}
+ opts[:timeout] = timeout
+ opts[:returns] = returns if returns
+ opts[:environment] = environment if environment
+ opts[:user] = user if user
+ opts[:group] = group if group
+ opts[:cwd] = cwd if cwd
+ opts[:umask] = umask if umask
+ opts[:log_level] = :info
+ opts[:log_tag] = new_resource.to_s
+ if STDOUT.tty? && !Chef::Config[:daemon] && Chef::Log.info? && !sensitive?
+ opts[:live_stream] = STDOUT
end
+ opts
+ end
+
+ def description
+ sensitive? ? "sensitive resource" : command
+ end
+
+ def creates_relative?
+ Pathname(creates).relative?
+ end
+
+ def sentinel_file
+ Pathname.new(Chef::Util::PathHelper.cleanpath(
+ ( cwd && creates_relative? ) ? ::File.join(cwd, creates) : creates
+ ))
end
end
end
diff --git a/lib/chef/provider/file.rb b/lib/chef/provider/file.rb
index a9390cc45c..c070d29458 100644
--- a/lib/chef/provider/file.rb
+++ b/lib/chef/provider/file.rb
@@ -345,6 +345,14 @@ class Chef
if new_resource.checksum && tempfile && ( new_resource.checksum != tempfile_checksum )
raise Chef::Exceptions::ChecksumMismatch.new(short_cksum(new_resource.checksum), short_cksum(tempfile_checksum))
end
+
+ if tempfile
+ new_resource.verify.each do |v|
+ if ! v.verify(tempfile.path)
+ raise Chef::Exceptions::ValidationFailed.new "Proposed content for #{new_resource.path} failed verification #{v}"
+ end
+ end
+ end
end
def do_unlink
diff --git a/lib/chef/provider/group.rb b/lib/chef/provider/group.rb
index 35a16c870c..29738cc046 100644
--- a/lib/chef/provider/group.rb
+++ b/lib/chef/provider/group.rb
@@ -17,12 +17,14 @@
#
require 'chef/provider'
+require 'chef/mixin/shell_out'
require 'chef/mixin/command'
require 'etc'
class Chef
class Provider
class Group < Chef::Provider
+ include Chef::Mixin::ShellOut
include Chef::Mixin::Command
attr_accessor :group_exists
attr_accessor :change_desc
diff --git a/lib/chef/provider/group/dscl.rb b/lib/chef/provider/group/dscl.rb
index e06c090f50..a59a94aa98 100644
--- a/lib/chef/provider/group/dscl.rb
+++ b/lib/chef/provider/group/dscl.rb
@@ -24,10 +24,9 @@ class Chef
def dscl(*args)
host = "."
stdout_result = ""; stderr_result = ""; cmd = "dscl #{host} -#{args.join(' ')}"
- status = popen4(cmd) do |pid, stdin, stdout, stderr|
- stdout.each { |line| stdout_result << line }
- stderr.each { |line| stderr_result << line }
- end
+ status = shell_out(cmd)
+ status.stdout.each_line { |line| stdout_result << line }
+ status.stderr.each_line { |line| stderr_result << line }
return [cmd, status, stdout_result, stderr_result]
end
diff --git a/lib/chef/provider/ifconfig.rb b/lib/chef/provider/ifconfig.rb
index ac52100b56..06080c90c3 100644
--- a/lib/chef/provider/ifconfig.rb
+++ b/lib/chef/provider/ifconfig.rb
@@ -18,6 +18,7 @@
require 'chef/log'
require 'chef/mixin/command'
+require 'chef/mixin/shell_out'
require 'chef/provider'
require 'chef/resource/file'
require 'chef/exceptions'
@@ -38,6 +39,7 @@ require 'erb'
class Chef
class Provider
class Ifconfig < Chef::Provider
+ include Chef::Mixin::ShellOut
include Chef::Mixin::Command
attr_accessor :config_template
@@ -59,32 +61,30 @@ class Chef
@ifconfig_success = true
@interfaces = {}
- @status = popen4("ifconfig") do |pid, stdin, stdout, stderr|
- stdout.each do |line|
-
- if !line[0..9].strip.empty?
- @int_name = line[0..9].strip
- @interfaces[@int_name] = {"hwaddr" => (line =~ /(HWaddr)/ ? ($') : "nil").strip.chomp }
- else
- @interfaces[@int_name]["inet_addr"] = (line =~ /inet addr:(\S+)/ ? ($1) : "nil") if line =~ /inet addr:/
- @interfaces[@int_name]["bcast"] = (line =~ /Bcast:(\S+)/ ? ($1) : "nil") if line =~ /Bcast:/
- @interfaces[@int_name]["mask"] = (line =~ /Mask:(\S+)/ ? ($1) : "nil") if line =~ /Mask:/
- @interfaces[@int_name]["mtu"] = (line =~ /MTU:(\S+)/ ? ($1) : "nil") if line =~ /MTU:/
- @interfaces[@int_name]["metric"] = (line =~ /Metric:(\S+)/ ? ($1) : "nil") if line =~ /Metric:/
- end
+ @status = shell_out("ifconfig")
+ @status.stdout.each_line do |line|
+ if !line[0..9].strip.empty?
+ @int_name = line[0..9].strip
+ @interfaces[@int_name] = {"hwaddr" => (line =~ /(HWaddr)/ ? ($') : "nil").strip.chomp }
+ else
+ @interfaces[@int_name]["inet_addr"] = (line =~ /inet addr:(\S+)/ ? ($1) : "nil") if line =~ /inet addr:/
+ @interfaces[@int_name]["bcast"] = (line =~ /Bcast:(\S+)/ ? ($1) : "nil") if line =~ /Bcast:/
+ @interfaces[@int_name]["mask"] = (line =~ /Mask:(\S+)/ ? ($1) : "nil") if line =~ /Mask:/
+ @interfaces[@int_name]["mtu"] = (line =~ /MTU:(\S+)/ ? ($1) : "nil") if line =~ /MTU:/
+ @interfaces[@int_name]["metric"] = (line =~ /Metric:(\S+)/ ? ($1) : "nil") if line =~ /Metric:/
+ end
- if @interfaces.has_key?(@new_resource.device)
- @interface = @interfaces.fetch(@new_resource.device)
-
- @current_resource.target(@new_resource.target)
- @current_resource.device(@new_resource.device)
- @current_resource.inet_addr(@interface["inet_addr"])
- @current_resource.hwaddr(@interface["hwaddr"])
- @current_resource.bcast(@interface["bcast"])
- @current_resource.mask(@interface["mask"])
- @current_resource.mtu(@interface["mtu"])
- @current_resource.metric(@interface["metric"])
- end
+ if @interfaces.has_key?(@new_resource.device)
+ @interface = @interfaces.fetch(@new_resource.device)
+
+ @current_resource.target(@new_resource.target)
+ @current_resource.device(@new_resource.device)
+ @current_resource.inet_addr(@interface["inet_addr"])
+ @current_resource.hwaddr(@interface["hwaddr"])
+ @current_resource.bcast(@interface["bcast"])
+ @current_resource.mask(@interface["mask"])
+ @current_resource.mtu(@interface["mtu"])
+ @current_resource.metric(@interface["metric"])
end
end
@current_resource
diff --git a/lib/chef/provider/ifconfig/aix.rb b/lib/chef/provider/ifconfig/aix.rb
index 460b1ba7f2..8fead44bc6 100644
--- a/lib/chef/provider/ifconfig/aix.rb
+++ b/lib/chef/provider/ifconfig/aix.rb
@@ -30,35 +30,33 @@ class Chef
found_interface = false
interface = {}
- @status = popen4("ifconfig -a") do |pid, stdin, stdout, stderr|
- stdout.each do |line|
-
- if !found_interface
- if line =~ /^(\S+):\sflags=(\S+)/
- # We have interface name, if this is the interface for @current_resource, load info else skip till next interface is found.
- if $1 == @new_resource.device
- # Found interface
- found_interface = true
- @interface_exists = true
- @current_resource.target(@new_resource.target)
- @current_resource.device($1)
- interface[:flags] = $2
- @current_resource.metric($1) if line =~ /metric\s(\S+)/
- end
+ @status = shell_out("ifconfig -a")
+ @status.stdout.each_line do |line|
+ if !found_interface
+ if line =~ /^(\S+):\sflags=(\S+)/
+ # We have interface name, if this is the interface for @current_resource, load info else skip till next interface is found.
+ if $1 == @new_resource.device
+ # Found interface
+ found_interface = true
+ @interface_exists = true
+ @current_resource.target(@new_resource.target)
+ @current_resource.device($1)
+ interface[:flags] = $2
+ @current_resource.metric($1) if line =~ /metric\s(\S+)/
end
+ end
+ else
+ # parse interface related information, stop when next interface is found.
+ if line =~ /^(\S+):\sflags=(\S+)/
+ # we are done parsing interface info and hit another one, so stop.
+ found_interface = false
+ break
else
- # parse interface related information, stop when next interface is found.
- if line =~ /^(\S+):\sflags=(\S+)/
- # we are done parsing interface info and hit another one, so stop.
- found_interface = false
- break
- else
- if found_interface
- # read up interface info
- @current_resource.inet_addr($1) if line =~ /inet\s(\S+)\s/
- @current_resource.bcast($1) if line =~ /broadcast\s(\S+)/
- @current_resource.mask(hex_to_dec_netmask($1)) if line =~ /netmask\s(\S+)\s/
- end
+ if found_interface
+ # read up interface info
+ @current_resource.inet_addr($1) if line =~ /inet\s(\S+)\s/
+ @current_resource.bcast($1) if line =~ /broadcast\s(\S+)/
+ @current_resource.mask(hex_to_dec_netmask($1)) if line =~ /netmask\s(\S+)\s/
end
end
end
diff --git a/lib/chef/provider/lwrp_base.rb b/lib/chef/provider/lwrp_base.rb
index 121abf5fdb..492ddda6da 100644
--- a/lib/chef/provider/lwrp_base.rb
+++ b/lib/chef/provider/lwrp_base.rb
@@ -86,7 +86,7 @@ class Chef
class_name = convert_to_class_name(provider_name)
- if Chef::Provider.const_defined?(class_name)
+ if Chef::Provider.const_defined?(class_name, false)
Chef::Log.info("#{class_name} light-weight provider is already initialized -- Skipping loading #{filename}!")
Chef::Log.debug("Overriding already defined LWRPs is not supported anymore starting with Chef 12.")
provider_class = Chef::Provider.const_get(class_name)
diff --git a/lib/chef/provider/mount.rb b/lib/chef/provider/mount.rb
index b46604260e..1631d87033 100644
--- a/lib/chef/provider/mount.rb
+++ b/lib/chef/provider/mount.rb
@@ -18,14 +18,14 @@
#
require 'chef/log'
-require 'chef/mixin/command'
+require 'chef/mixin/shell_out'
require 'chef/provider'
class Chef
class Provider
class Mount < Chef::Provider
- include Chef::Mixin::Command
+ include Chef::Mixin::ShellOut
attr_accessor :unmount_retries
diff --git a/lib/chef/provider/mount/mount.rb b/lib/chef/provider/mount/mount.rb
index c1d4fb2223..0a6e269d2d 100644
--- a/lib/chef/provider/mount/mount.rb
+++ b/lib/chef/provider/mount/mount.rb
@@ -213,10 +213,9 @@ class Chef
@real_device = @new_resource.device
else
@real_device = ""
- status = popen4("/sbin/findfs #{device_fstab}") do |pid, stdin, stdout, stderr|
- device_line = stdout.first # stdout.first consumes
- @real_device = device_line.chomp unless device_line.nil?
- end
+ ret = shell_out("/sbin/findfs #{device_fstab}")
+ device_line = ret.stdout.lines.first # stdout.first consumes
+ @real_device = device_line.chomp unless device_line.nil?
end
end
@real_device
diff --git a/lib/chef/provider/mount/solaris.rb b/lib/chef/provider/mount/solaris.rb
index cf04150322..d8cec24138 100644
--- a/lib/chef/provider/mount/solaris.rb
+++ b/lib/chef/provider/mount/solaris.rb
@@ -88,7 +88,7 @@ class Chef
# FIXME: Should remount always do the remount or only if the options change?
actual_options = options || []
actual_options.delete('noauto')
- mount_options = actual_options.empty? ? '' : ",#{actual_options.join(',')}"
+ mount_options = actual_options.empty? ? '' : ",#{actual_options.join(',')}"
shell_out!("mount -o remount#{mount_options} #{mount_point}")
end
diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb
index a4a056dfec..de6d399ee3 100644
--- a/lib/chef/provider/package.rb
+++ b/lib/chef/provider/package.rb
@@ -16,6 +16,7 @@
# limitations under the License.
#
+require 'chef/mixin/shell_out'
require 'chef/mixin/command'
require 'chef/log'
require 'chef/file_cache'
@@ -24,10 +25,14 @@ require 'chef/platform'
class Chef
class Provider
class Package < Chef::Provider
+ include Chef::Mixin::ShellOut
- include Chef::Mixin::Command
-
+ #
+ # Hook that subclasses use to populate the candidate_version(s)
+ #
+ # @return [Array, String] candidate_version(s) may be a string or array
attr_accessor :candidate_version
+
def initialize(new_resource, run_context)
super
@candidate_version = nil
@@ -41,63 +46,89 @@ class Chef
end
def define_resource_requirements
+ # XXX: upgrade with a specific version doesn't make a whole lot of sense, but why don't we throw this anyway if it happens?
+ # if not, shouldn't we raise to tell the user to use install instead of upgrade if they want to pin a version?
requirements.assert(:install) do |a|
- a.assertion { ((@new_resource.version != nil) && !(target_version_already_installed?)) \
- || !(@current_resource.version.nil? && candidate_version.nil?) }
- a.failure_message(Chef::Exceptions::Package, "No version specified, and no candidate version available for #{@new_resource.package_name}")
- a.whyrun("Assuming a repository that offers #{@new_resource.package_name} would have been configured")
+ a.assertion { candidates_exist_for_all_forced_changes? }
+ a.failure_message(Chef::Exceptions::Package, "No version specified, and no candidate version available for #{forced_packages_missing_candidates.join(", ")}")
+ a.whyrun("Assuming a repository that offers #{forced_packages_missing_candidates.join(", ")} would have been configured")
end
- requirements.assert(:upgrade) do |a|
- # Can't upgrade what we don't have
- a.assertion { !(@current_resource.version.nil? && candidate_version.nil?) }
- a.failure_message(Chef::Exceptions::Package, "No candidate version available for #{@new_resource.package_name}")
- a.whyrun("Assuming a repository that offers #{@new_resource.package_name} would have been configured")
+ requirements.assert(:upgrade, :install) do |a|
+ a.assertion { candidates_exist_for_all_uninstalled? }
+ a.failure_message(Chef::Exceptions::Package, "No candidate version available for #{packages_missing_candidates.join(", ")}")
+ a.whyrun("Assuming a repository that offers #{packages_missing_candidates.join(", ")} would have been configured")
end
end
def action_install
- # If we specified a version, and it's not the current version, move to the specified version
- if !@new_resource.version.nil? && !(target_version_already_installed?)
- install_version = @new_resource.version
- # If it's not installed at all, install it
- elsif @current_resource.version.nil?
- install_version = candidate_version
- else
+ unless target_version_array.any?
Chef::Log.debug("#{@new_resource} is already installed - nothing to do")
return
end
- # We need to make sure we handle the preseed file
+ # @todo: move the preseed code out of the base class (and complete the fix for Array of preseeds? ugh...)
if @new_resource.response_file
- if preseed_file = get_preseed_file(@new_resource.package_name, install_version)
- converge_by("preseed package #{@new_resource.package_name}") do
+ if preseed_file = get_preseed_file(package_names_for_targets, versions_for_targets)
+ converge_by("preseed package #{package_names_for_targets}") do
preseed_package(preseed_file)
end
end
end
- description = install_version ? "version #{install_version} of" : ""
- converge_by("install #{description} package #{@new_resource.package_name}") do
- @new_resource.version(install_version)
- install_package(@new_resource.package_name, install_version)
+
+ # XXX: mutating the new resource is generally bad
+ @new_resource.version(versions_for_new_resource)
+
+ converge_by(install_description) do
+ install_package(package_names_for_targets, versions_for_targets)
+ Chef::Log.info("#{@new_resource} installed #{package_names_for_targets} at #{versions_for_targets}")
+ end
+ end
+
+ def install_description
+ description = []
+ target_version_array.each_with_index do |target_version, i|
+ next if target_version.nil?
+ package_name = package_name_array[i]
+ description << "install version #{target_version} of package #{package_name}"
end
+ description
end
+ private :install_description
+
def action_upgrade
- if candidate_version.nil?
- Chef::Log.debug("#{@new_resource} no candidate version - nothing to do")
- elsif @current_resource.version == candidate_version
- Chef::Log.debug("#{@new_resource} is at the latest version - nothing to do")
- else
- @new_resource.version(candidate_version)
- orig_version = @current_resource.version || "uninstalled"
- converge_by("upgrade package #{@new_resource.package_name} from #{orig_version} to #{candidate_version}") do
- upgrade_package(@new_resource.package_name, candidate_version)
- Chef::Log.info("#{@new_resource} upgraded from #{orig_version} to #{candidate_version}")
- end
+ if !target_version_array.any?
+ Chef::Log.debug("#{@new_resource} no versions to upgrade - nothing to do")
+ return
+ end
+
+ # XXX: mutating the new resource is generally bad
+ @new_resource.version(versions_for_new_resource)
+
+ converge_by(upgrade_description) do
+ upgrade_package(package_names_for_targets, versions_for_targets)
+ log_allow_downgrade = allow_downgrade ? '(allow_downgrade)' : ''
+ Chef::Log.info("#{@new_resource} upgraded#{log_allow_downgrade} #{package_names_for_targets} to #{versions_for_targets}")
end
end
+ def upgrade_description
+ log_allow_downgrade = allow_downgrade ? '(allow_downgrade)' : ''
+ description = []
+ target_version_array.each_with_index do |target_version, i|
+ next if target_version.nil?
+ package_name = package_name_array[i]
+ candidate_version = candidate_version_array[i]
+ current_version = current_version_array[i] || "uninstalled"
+ description << "upgrade#{log_allow_downgrade} package #{package_name} from #{current_version} to #{candidate_version}"
+ end
+ description
+ end
+
+ private :upgrade_description
+
+ # @todo: ability to remove an array of packages
def action_remove
if removing_package?
description = @new_resource.version ? "version #{@new_resource.version} of " : ""
@@ -110,18 +141,28 @@ class Chef
end
end
+ def have_any_matching_version?
+ f = []
+ new_version_array.each_with_index do |item, index|
+ f << (item == current_version_array[index])
+ end
+ f.any?
+ end
+
def removing_package?
- if @current_resource.version.nil?
- false # nothing to remove
- elsif @new_resource.version.nil?
- true # remove any version of a package
- elsif @new_resource.version == @current_resource.version
+ if !current_version_array.any?
+ # ! any? means it's all nil's, which means nothing is installed
+ false
+ elsif !new_version_array.any?
+ true # remove any version of all packages
+ elsif have_any_matching_version?
true # remove the version we have
else
false # we don't have the version we want to remove
end
end
+ # @todo: ability to purge an array of packages
def action_purge
if removing_package?
description = @new_resource.version ? "version #{@new_resource.version} of" : ""
@@ -132,6 +173,7 @@ class Chef
end
end
+ # @todo: ability to reconfigure an array of packages
def action_reconfig
if @current_resource.version == nil then
Chef::Log.debug("#{@new_resource} is NOT installed - nothing to do")
@@ -154,6 +196,7 @@ class Chef
end
end
+ # @todo use composition rather than inheritance
def install_package(name, version)
raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :install"
end
@@ -178,6 +221,17 @@ class Chef
raise( Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reconfig" )
end
+ # this is heavily used by subclasses
+ def expand_options(options)
+ options ? " #{options}" : ""
+ end
+
+ # this is public and overridden by subclasses (rubygems package implements '>=' and '~>' operators)
+ def target_version_already_installed?(current_version, new_version)
+ new_version == current_version
+ end
+
+ # @todo: extract apt/dpkg specific preseeding to a helper class
def get_preseed_file(name, version)
resource = preseed_resource(name, version)
resource.run_action(:create)
@@ -190,6 +244,7 @@ class Chef
end
end
+ # @todo: extract apt/dpkg specific preseeding to a helper class
def preseed_resource(name, version)
# A directory in our cache to store this cookbook's preseed files in
file_cache_dir = Chef::FileCache.create_cache_path("preseed/#{@new_resource.cookbook_name}")
@@ -216,24 +271,218 @@ class Chef
remote_file
end
- def expand_options(options)
- options ? " #{options}" : ""
+ # helper method used by subclasses
+ #
+ def as_array(thing)
+ [ thing ].flatten
end
- def target_version_already_installed?
- @new_resource.version == @current_resource.version
+ private
+
+ # Returns the package names which need to be modified. If the resource was called with an array of packages
+ # then this will return an array of packages to update (may have 0 or 1 entries). If the resource was called
+ # with a non-array package_name to manage then this will return a string rather than an Array. The output
+ # of this is meant to be fed into subclass interfaces to install/upgrade packages and not all of them are
+ # Array-aware.
+ #
+ # @return [String, Array<String>] package_name(s) to actually update/install
+ def package_names_for_targets
+ package_names_for_targets = []
+ target_version_array.each_with_index do |target_version, i|
+ next if target_version.nil?
+ package_name = package_name_array[i]
+ package_names_for_targets.push(package_name)
+ end
+ multipackage? ? package_names_for_targets : package_names_for_targets[0]
end
- private
+ # Returns the package versions which need to be modified. If the resource was called with an array of packages
+ # then this will return an array of versions to update (may have 0 or 1 entries). If the resource was called
+ # with a non-array package_name to manage then this will return a string rather than an Array. The output
+ # of this is meant to be fed into subclass interfaces to install/upgrade packages and not all of them are
+ # Array-aware.
+ #
+ # @return [String, Array<String>] package version(s) to actually update/install
+ def versions_for_targets
+ versions_for_targets = []
+ target_version_array.each_with_index do |target_version, i|
+ next if target_version.nil?
+ versions_for_targets.push(target_version)
+ end
+ multipackage? ? versions_for_targets : versions_for_targets[0]
+ end
+
+ # We need to mutate @new_resource.version() for some reason and this is a helper so that we inject the right
+ # class (String or Array) into that attribute based on if we're handling an array of package names or not.
+ #
+ # @return [String, Array<String>] target_versions coerced into the correct type for back-compat
+ def versions_for_new_resource
+ if multipackage?
+ target_version_array
+ else
+ target_version_array[0]
+ end
+ end
+
+ # Return an array indexed the same as *_version_array which contains either the target version to install/upgrade to
+ # or else nil if the package is not being modified.
+ #
+ # @return [Array<String,NilClass>] array of package versions which need to be upgraded (nil = not being upgraded)
+ def target_version_array
+ @target_version_array ||=
+ begin
+ target_version_array = []
+
+ each_package do |package_name, new_version, current_version, candidate_version|
+ case action
+ when :upgrade
+
+ if !candidate_version
+ Chef::Log.debug("#{new_resource} #{package_name} has no candidate_version to upgrade to")
+ target_version_array.push(nil)
+ elsif current_version == candidate_version
+ Chef::Log.debug("#{new_resource} #{package_name} the #{candidate_version} is already installed")
+ target_version_array.push(nil)
+ else
+ Chef::Log.debug("#{new_resource} #{package_name} is out of date, will upgrade to #{candidate_version}")
+ target_version_array.push(candidate_version)
+ end
+
+ when :install
+
+ if new_version
+ if target_version_already_installed?(current_version, new_version)
+ Chef::Log.debug("#{new_resource} #{package_name} #{current_version} satisifies #{new_version} requirement")
+ target_version_array.push(nil)
+ else
+ Chef::Log.debug("#{new_resource} #{package_name} #{current_version} needs updating to #{new_version}")
+ target_version_array.push(new_version)
+ end
+ elsif current_version.nil?
+ Chef::Log.debug("#{new_resource} #{package_name} not installed, installing #{candidate_version}")
+ target_version_array.push(candidate_version)
+ else
+ Chef::Log.debug("#{new_resource} #{package_name} #{current_version} already installed")
+ target_version_array.push(nil)
+ end
+
+ else
+ # in specs please test the public interface provider.run_action(:install) instead of provider.action_install
+ raise "internal error - target_version_array in package provider does not understand this action"
+ end
+ end
+
+ target_version_array
+ end
+ end
+
+ # Check the list of current_version_array and candidate_version_array. For any of the
+ # packages if both versions are missing (uninstalled and no candidate) this will be an
+ # unsolvable error.
+ #
+ # @return [Boolean] valid candidates exist for all uninstalled packages
+ def candidates_exist_for_all_uninstalled?
+ packages_missing_candidates.empty?
+ end
+
+ # Returns array of all packages which are missing candidate versions.
+ #
+ # @return [Array<String>] names of packages missing candidates
+ def packages_missing_candidates
+ @packages_missing_candidates ||=
+ begin
+ missing = []
+ each_package do |package_name, new_version, current_version, candidate_version|
+ missing.push(package_name) if candidate_version.nil? && current_version.nil?
+ end
+ missing
+ end
+ end
+
+ # This looks for packages which have a new_version and a current_version, and they are
+ # different (a "forced change") and for which there is no candidate. This is an edge
+ # condition that candidates_exist_for_all_uninstalled? does not catch since in this case
+ # it is not uninstalled but must be installed anyway and no version exists.
+ #
+ # @return [Boolean] valid candidates exist for all uninstalled packages
+ def candidates_exist_for_all_forced_changes?
+ forced_packages_missing_candidates.empty?
+ end
+
+ # Returns an array of all forced packages which are missing candidate versions
+ #
+ # @return [Array] names of packages missing candidates
+ def forced_packages_missing_candidates
+ @forced_packages_missing_candidates ||=
+ begin
+ missing = []
+ each_package do |package_name, new_version, current_version, candidate_version|
+ next if new_version.nil? || current_version.nil?
+ if candidate_version.nil? && !target_version_already_installed?(current_version, new_version)
+ missing.push(package_name)
+ end
+ end
+ missing
+ end
+ end
+
+ # Helper to iterate over all the indexed *_array's in sync
+ #
+ # @yield [package_name, new_version, current_version, candidate_version] Description of block
+ def each_package
+ package_name_array.each_with_index do |package_name, i|
+ candidate_version = candidate_version_array[i]
+ current_version = current_version_array[i]
+ new_version = new_version_array[i]
+ yield package_name, new_version, current_version, candidate_version
+ end
+ end
+
+ # @return [Boolean] if we're doing a multipackage install or not
+ def multipackage?
+ new_resource.package_name.is_a?(Array)
+ end
+
+ # @return [Array] package_name(s) as an array
+ def package_name_array
+ [ new_resource.package_name ].flatten
+ end
+
+ # @return [Array] candidate_version(s) as an array
+ def candidate_version_array
+ [ candidate_version ].flatten
+ end
+ # @return [Array] current_version(s) as an array
+ def current_version_array
+ [ current_resource.version ].flatten
+ end
+
+ # @return [Array] new_version(s) as an array
+ def new_version_array
+ @new_version_array ||=
+ [ new_resource.version ].flatten.map do |v|
+ ( v.nil? || v.empty? ) ? nil : v
+ end
+ end
+
+ # @todo: extract apt/dpkg specific preseeding to a helper class
def template_available?(path)
- run_context.has_template_in_cookbook?(@new_resource.cookbook_name, path)
+ run_context.has_template_in_cookbook?(new_resource.cookbook_name, path)
end
+ # @todo: extract apt/dpkg specific preseeding to a helper class
def cookbook_file_available?(path)
- run_context.has_cookbook_file_in_cookbook?(@new_resource.cookbook_name, path)
+ run_context.has_cookbook_file_in_cookbook?(new_resource.cookbook_name, path)
end
+ def allow_downgrade
+ if @new_resource.respond_to?("allow_downgrade")
+ @new_resource.allow_downgrade
+ else
+ false
+ end
+ end
end
end
end
diff --git a/lib/chef/provider/package/aix.rb b/lib/chef/provider/package/aix.rb
index 88de4679ba..107f914c05 100644
--- a/lib/chef/provider/package/aix.rb
+++ b/lib/chef/provider/package/aix.rb
@@ -52,34 +52,30 @@ class Chef
@package_source_found = ::File.exists?(@new_resource.source)
if @package_source_found
Chef::Log.debug("#{@new_resource} checking pkg status")
- status = popen4("installp -L -d #{@new_resource.source}") do |pid, stdin, stdout, stderr|
- package_found = false
- stdout.each do |line|
- case line
- when /#{@new_resource.package_name}:/
- package_found = true
- fields = line.split(":")
- @new_resource.version(fields[2])
- end
+ ret = shell_out("installp -L -d #{@new_resource.source}")
+ ret.stdout.each_line do | line |
+ case line
+ when /#{@new_resource.package_name}:/
+ fields = line.split(":")
+ @new_resource.version(fields[2])
end
end
end
end
Chef::Log.debug("#{@new_resource} checking install state")
- status = popen4("lslpp -lcq #{@current_resource.package_name}") do |pid, stdin, stdout, stderr|
- stdout.each do |line|
- case line
- when /#{@current_resource.package_name}/
- fields = line.split(":")
- Chef::Log.debug("#{@new_resource} version #{fields[2]} is already installed")
- @current_resource.version(fields[2])
- end
+ ret = shell_out("lslpp -lcq #{@current_resource.package_name}")
+ ret.stdout.each_line do | line |
+ case line
+ when /#{@current_resource.package_name}/
+ fields = line.split(":")
+ Chef::Log.debug("#{@new_resource} version #{fields[2]} is already installed")
+ @current_resource.version(fields[2])
end
end
- unless status.exitstatus == 0 || status.exitstatus == 1
- raise Chef::Exceptions::Package, "lslpp failed - #{status.inspect}!"
+ unless ret.exitstatus == 0 || ret.exitstatus == 1
+ raise Chef::Exceptions::Package, "lslpp failed - #{ret.format_for_exception}!"
end
@current_resource
@@ -87,19 +83,18 @@ class Chef
def candidate_version
return @candidate_version if @candidate_version
- status = popen4("installp -L -d #{@new_resource.source}") do |pid, stdin, stdout, stderr|
- stdout.each_line do |line|
- case line
- when /\w:#{Regexp.escape(@new_resource.package_name)}:(.*)/
- fields = line.split(":")
- @candidate_version = fields[2]
- @new_resource.version(fields[2])
- Chef::Log.debug("#{@new_resource} setting install candidate version to #{@candidate_version}")
- end
+ ret = shell_out("installp -L -d #{@new_resource.source}")
+ ret.stdout.each_line do | line |
+ case line
+ when /\w:#{Regexp.escape(@new_resource.package_name)}:(.*)/
+ fields = line.split(":")
+ @candidate_version = fields[2]
+ @new_resource.version(fields[2])
+ Chef::Log.debug("#{@new_resource} setting install candidate version to #{@candidate_version}")
end
end
- unless status.exitstatus == 0
- raise Chef::Exceptions::Package, "installp -L -d #{@new_resource.source} - #{status.inspect}!"
+ unless ret.exitstatus == 0
+ raise Chef::Exceptions::Package, "installp -L -d #{@new_resource.source} - #{ret.format_for_exception}!"
end
@candidate_version
end
diff --git a/lib/chef/provider/package/apt.rb b/lib/chef/provider/package/apt.rb
index fd132c817c..e426b51992 100644
--- a/lib/chef/provider/package/apt.rb
+++ b/lib/chef/provider/package/apt.rb
@@ -27,12 +27,18 @@ class Chef
provides :apt_package, os: "linux"
+ # return [Hash] mapping of package name to Boolean value
attr_accessor :is_virtual_package
+ def initialize(new_resource, run_context)
+ super
+ @is_virtual_package = {}
+ end
+
def load_current_resource
@current_resource = Chef::Resource::Package.new(@new_resource.name)
@current_resource.package_name(@new_resource.package_name)
- check_package_state(@new_resource.package_name)
+ check_all_packages_state(@new_resource.package_name)
@current_resource
end
@@ -50,31 +56,31 @@ class Chef
"-o APT::Default-Release=#{@new_resource.default_release}" if @new_resource.respond_to?(:default_release) && @new_resource.default_release
end
- def check_package_state(package)
- Chef::Log.debug("#{@new_resource} checking package status for #{package}")
- installed = false
+ def check_package_state(pkg)
+ is_virtual_package = false
+ installed = false
+ installed_version = nil
+ candidate_version = nil
- shell_out!("apt-cache#{expand_options(default_release_options)} policy #{package}", :timeout => @new_resource.timeout).stdout.each_line do |line|
+ shell_out!("apt-cache#{expand_options(default_release_options)} policy #{pkg}", {:timeout=>900}).stdout.each_line do |line|
case line
when /^\s{2}Installed: (.+)$/
installed_version = $1
if installed_version == '(none)'
Chef::Log.debug("#{@new_resource} current version is nil")
- @current_resource.version(nil)
+ installed_version = nil
else
Chef::Log.debug("#{@new_resource} current version is #{installed_version}")
- @current_resource.version(installed_version)
installed = true
end
when /^\s{2}Candidate: (.+)$/
candidate_version = $1
if candidate_version == '(none)'
# This may not be an appropriate assumption, but it shouldn't break anything that already worked -- btm
- @is_virtual_package = true
- showpkg = shell_out!("apt-cache showpkg #{package}", :timeout => @new_resource.timeout).stdout
+ is_virtual_package = true
+ showpkg = shell_out!("apt-cache showpkg #{pkg}", {:timeout => 900}).stdout
providers = Hash.new
- # Returns all lines after 'Reverse Provides:'
- showpkg.rpartition(/Reverse Provides:\s*#{$/}/)[2].each_line do |line|
+ showpkg.rpartition(/Reverse Provides: ?#{$/}/)[2].each_line do |line|
provider, version = line.split
providers[provider] = version
end
@@ -85,20 +91,56 @@ class Chef
raise Chef::Exceptions::Package, "#{@new_resource.package_name} is a virtual package provided by #{num_providers} packages, you must explicitly select one to install" if num_providers > 1
# Check if the package providing this virtual package is installed
Chef::Log.info("#{@new_resource} is a virtual package, actually acting on package[#{providers.keys.first}]")
- installed = check_package_state(providers.keys.first)
+ ret = check_package_state(providers.keys.first)
+ installed = ret[:installed]
+ installed_version = ret[:installed_version]
else
Chef::Log.debug("#{@new_resource} candidate version is #{$1}")
- @candidate_version = $1
end
end
end
- return installed
+ return {
+ installed_version: installed_version,
+ installed: installed,
+ candidate_version: candidate_version,
+ is_virtual_package: is_virtual_package,
+ }
+ end
+
+ def check_all_packages_state(package)
+ installed_version = {}
+ candidate_version = {}
+ installed = {}
+
+ [package].flatten.each do |pkg|
+ ret = check_package_state(pkg)
+ is_virtual_package[pkg] = ret[:is_virtual_package]
+ installed[pkg] = ret[:installed]
+ installed_version[pkg] = ret[:installed_version]
+ candidate_version[pkg] = ret[:candidate_version]
+ end
+
+ if package.is_a?(Array)
+ @candidate_version = []
+ final_installed_version = []
+ [package].flatten.each do |pkg|
+ @candidate_version << candidate_version[pkg]
+ final_installed_version << installed_version[pkg]
+ end
+ @current_resource.version(final_installed_version)
+ else
+ @candidate_version = candidate_version[package]
+ @current_resource.version(installed_version[package])
+ end
end
def install_package(name, version)
- package_name = "#{name}=#{version}"
- package_name = name if @is_virtual_package
+ name_array = [ name ].flatten
+ version_array = [ version ].flatten
+ package_name = name_array.zip(version_array).map do |n, v|
+ is_virtual_package[n] ? n : "#{n}=#{v}"
+ end.join(' ')
run_noninteractive("apt-get -q -y#{expand_options(default_release_options)}#{expand_options(@new_resource.options)} install #{package_name}")
end
@@ -107,12 +149,13 @@ class Chef
end
def remove_package(name, version)
- package_name = "#{name}"
+ package_name = [ name ].flatten.join(' ')
run_noninteractive("apt-get -q -y#{expand_options(@new_resource.options)} remove #{package_name}")
end
def purge_package(name, version)
- run_noninteractive("apt-get -q -y#{expand_options(@new_resource.options)} purge #{@new_resource.package_name}")
+ package_name = [ name ].flatten.join(' ')
+ run_noninteractive("apt-get -q -y#{expand_options(@new_resource.options)} purge #{package_name}")
end
def preseed_package(preseed_file)
@@ -121,8 +164,9 @@ class Chef
end
def reconfig_package(name, version)
+ package_name = [ name ].flatten.join(' ')
Chef::Log.info("#{@new_resource} reconfiguring")
- run_noninteractive("dpkg-reconfigure #{name}")
+ run_noninteractive("dpkg-reconfigure #{package_name}")
end
private
diff --git a/lib/chef/provider/package/dpkg.rb b/lib/chef/provider/package/dpkg.rb
index 3a9cecc660..11691a2479 100644
--- a/lib/chef/provider/package/dpkg.rb
+++ b/lib/chef/provider/package/dpkg.rb
@@ -61,12 +61,12 @@ class Chef
if @source_exists
# Get information from the package if supplied
Chef::Log.debug("#{@new_resource} checking dpkg status")
- status = popen4("dpkg-deb -W #{@new_resource.source}") do |pid, stdin, stdout, stderr|
- stdout.each_line do |line|
- if pkginfo = DPKG_INFO.match(line)
- @current_resource.package_name(pkginfo[1])
- @new_resource.version(pkginfo[2])
- end
+
+ shell_out("dpkg-deb -W #{@new_resource.source}").stdout.each_line do |line|
+ if pkginfo = DPKG_INFO.match(line)
+ @current_resource.package_name(pkginfo[1])
+ @new_resource.version(pkginfo[2])
+ @candidate_version = pkginfo[2]
end
end
else
@@ -79,16 +79,15 @@ class Chef
# Check to see if it is installed
package_installed = nil
Chef::Log.debug("#{@new_resource} checking install state")
- status = popen4("dpkg -s #{@current_resource.package_name}") do |pid, stdin, stdout, stderr|
- stdout.each_line do |line|
- case line
- when DPKG_INSTALLED
- package_installed = true
- when DPKG_VERSION
- if package_installed
- Chef::Log.debug("#{@new_resource} current version is #{$1}")
- @current_resource.version($1)
- end
+ status = shell_out("dpkg -s #{@current_resource.package_name}")
+ status.stdout.each_line do |line|
+ case line
+ when DPKG_INSTALLED
+ package_installed = true
+ when DPKG_VERSION
+ if package_installed
+ Chef::Log.debug("#{@new_resource} current version is #{$1}")
+ @current_resource.version($1)
end
end
end
diff --git a/lib/chef/provider/package/macports.rb b/lib/chef/provider/package/macports.rb
index cd142eca42..b252344c99 100644
--- a/lib/chef/provider/package/macports.rb
+++ b/lib/chef/provider/package/macports.rb
@@ -3,7 +3,8 @@ class Chef
class Package
class Macports < Chef::Provider::Package
- provides :macports_package, os: "mac_os_x"
+ provides :macports_package
+ provides :package, os: "darwin"
def load_current_resource
@current_resource = Chef::Resource::Package.new(@new_resource.name)
@@ -82,12 +83,11 @@ class Chef
private
def get_response_from_command(command)
output = nil
- status = popen4(command) do |pid, stdin, stdout, stderr|
- begin
- output = stdout.read
- rescue Exception
- raise Chef::Exceptions::Package, "Could not read from STDOUT on command: #{command}"
- end
+ status = shell_out(command)
+ begin
+ output = status.stdout
+ rescue Exception
+ raise Chef::Exceptions::Package, "Could not read from STDOUT on command: #{command}"
end
unless status.exitstatus == 0 || status.exitstatus == 1
raise Chef::Exceptions::Package, "#{command} failed - #{status.insect}!"
diff --git a/lib/chef/provider/package/openbsd.rb b/lib/chef/provider/package/openbsd.rb
new file mode 100644
index 0000000000..f0931d7555
--- /dev/null
+++ b/lib/chef/provider/package/openbsd.rb
@@ -0,0 +1,107 @@
+#
+# Authors:: Bryan McLellan (btm@loftninjas.org)
+# Matthew Landauer (matthew@openaustralia.org)
+# Richard Manyanza (liseki@nyikacraftsmen.com)
+# Scott Bonds (scott@ggr.com)
+# Copyright:: Copyright (c) 2009 Bryan McLellan, Matthew Landauer
+# Copyright:: Copyright (c) 2014 Richard Manyanza, Scott Bonds
+# 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/package'
+require 'chef/provider/package'
+require 'chef/mixin/shell_out'
+require 'chef/mixin/get_source_from_package'
+
+class Chef
+ class Provider
+ class Package
+ class Openbsd < Chef::Provider::Package
+
+ provides :package, os: "openbsd"
+
+ include Chef::Mixin::ShellOut
+ include Chef::Mixin::GetSourceFromPackage
+
+ def initialize(*args)
+ super
+ @current_resource = Chef::Resource::Package.new(@new_resource.name)
+ @new_resource.source(pkg_path) if !@new_resource.source
+ end
+
+ def load_current_resource
+ @current_resource.package_name(@new_resource.package_name)
+ @current_resource.version(installed_version)
+ @current_resource
+ end
+
+ def install_package(name, version)
+ unless @current_resource.version
+ version_string = ''
+ version_string += "-#{version}" if version
+ if parts = name.match(/^(.+?)--(.+)/) # use double-dash for stems with flavors, see man page for pkg_add
+ name = parts[1]
+ end
+ shell_out!("pkg_add -r #{name}#{version_string}", :env => {"PKG_PATH" => @new_resource.source}).status
+ Chef::Log.debug("#{@new_resource} installed from: #{@new_resource.source}")
+ end
+ end
+
+ def remove_package(name, version)
+ version_string = ''
+ version_string += "-#{version}" if version
+ if parts = name.match(/^(.+?)--(.+)/)
+ name = parts[1]
+ end
+ shell_out!("pkg_delete #{name}#{version_string}", :env => nil).status
+ end
+
+ private
+
+ def installed_version
+ if parts = @new_resource.package_name.match(/^(.+?)--(.+)/)
+ name = parts[1]
+ else
+ name = @new_resource.package_name
+ end
+ pkg_info = shell_out!("pkg_info -e \"#{name}->0\"", :env => nil, :returns => [0,1])
+ result = pkg_info.stdout[/^inst:#{Regexp.escape(name)}-(.+?)\s/, 1]
+ Chef::Log.debug("installed_version of '#{@new_resource.package_name}' is '#{result}'")
+ result
+ end
+
+ def candidate_version
+ @candidate_version ||= begin
+ version_string = ''
+ version_string += "-#{version}" if @new_resource.version
+ pkg_info = shell_out!("pkg_info -I \"#{@new_resource.package_name}#{version_string}\"", :env => nil, :returns => [0,1])
+ if parts = @new_resource.package_name.match(/^(.+?)--(.+)/)
+ result = pkg_info.stdout[/^#{Regexp.escape(parts[1])}-(.+?)\s/, 1]
+ else
+ result = pkg_info.stdout[/^#{Regexp.escape(@new_resource.package_name)}-(.+?)\s/, 1]
+ end
+ Chef::Log.debug("candidate_version of '#{@new_resource.package_name}' is '#{result}'")
+ result
+ end
+ end
+
+ def pkg_path
+ ENV['PKG_PATH'] || "http://ftp.OpenBSD.org/pub/#{node.kernel.name}/#{node.kernel.release}/packages/#{node.kernel.machine}/"
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/package/pacman.rb b/lib/chef/provider/package/pacman.rb
index 45edda5c5d..f16fc811f5 100644
--- a/lib/chef/provider/package/pacman.rb
+++ b/lib/chef/provider/package/pacman.rb
@@ -34,13 +34,12 @@ class Chef
@current_resource.version(nil)
Chef::Log.debug("#{@new_resource} checking pacman for #{@new_resource.package_name}")
- status = popen4("pacman -Qi #{@new_resource.package_name}") do |pid, stdin, stdout, stderr|
- stdout.each do |line|
- case line
- when /^Version(\s?)*: (.+)$/
- Chef::Log.debug("#{@new_resource} current version is #{$2}")
- @current_resource.version($2)
- end
+ status = shell_out("pacman -Qi #{@new_resource.package_name}")
+ status.stdout.each_line do |line|
+ case line
+ when /^Version(\s?)*: (.+)$/
+ Chef::Log.debug("#{@new_resource} current version is #{$2}")
+ @current_resource.version($2)
end
end
@@ -63,14 +62,13 @@ class Chef
package_repos = repos.map {|r| Regexp.escape(r) }.join('|')
- status = popen4("pacman -Sl") do |pid, stdin, stdout, stderr|
- stdout.each do |line|
- case line
- when /^(#{package_repos}) #{Regexp.escape(@new_resource.package_name)} (.+)$/
- # $2 contains a string like "4.4.0-1" or "3.10-4 [installed]"
- # simply split by space and use first token
- @candidate_version = $2.split(" ").first
- end
+ status = shell_out("pacman -Sl")
+ status.stdout.each_line do |line|
+ case line
+ when /^(#{package_repos}) #{Regexp.escape(@new_resource.package_name)} (.+)$/
+ # $2 contains a string like "4.4.0-1" or "3.10-4 [installed]"
+ # simply split by space and use first token
+ @candidate_version = $2.split(" ").first
end
end
diff --git a/lib/chef/provider/package/portage.rb b/lib/chef/provider/package/portage.rb
index 816e262ab0..bb047ad2fa 100644
--- a/lib/chef/provider/package/portage.rb
+++ b/lib/chef/provider/package/portage.rb
@@ -92,10 +92,9 @@ class Chef
def candidate_version
return @candidate_version if @candidate_version
- status = popen4("emerge --color n --nospinner --search #{@new_resource.package_name.split('/').last}") do |pid, stdin, stdout, stderr|
- available, installed = parse_emerge(@new_resource.package_name, stdout.read)
- @candidate_version = available
- end
+ status = shell_out("emerge --color n --nospinner --search #{@new_resource.package_name.split('/').last}")
+ available, installed = parse_emerge(@new_resource.package_name, status.stdout)
+ @candidate_version = available
unless status.exitstatus == 0
raise Chef::Exceptions::Package, "emerge --search failed - #{status.inspect}!"
diff --git a/lib/chef/provider/package/rpm.rb b/lib/chef/provider/package/rpm.rb
index 131587e066..f10fe23c71 100644
--- a/lib/chef/provider/package/rpm.rb
+++ b/lib/chef/provider/package/rpm.rb
@@ -17,6 +17,7 @@
#
require 'chef/provider/package'
require 'chef/mixin/command'
+require 'chef/mixin/shell_out'
require 'chef/resource/package'
require 'chef/mixin/get_source_from_package'
@@ -53,20 +54,18 @@ class Chef
@new_resource.version(nil)
if @new_resource.source
- unless ::File.exists?(@new_resource.source)
+ unless uri_scheme?(@new_resource.source) || ::File.exists?(@new_resource.source)
@package_source_exists = false
return
end
Chef::Log.debug("#{@new_resource} checking rpm status")
- status = popen4("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@new_resource.source}") do |pid, stdin, stdout, stderr|
- stdout.each do |line|
- case line
- when /^([\w\d+_.-]+)\s([\w\d_.-]+)$/
- @current_resource.package_name($1)
- @new_resource.version($2)
- @candidate_version = $2
- end
+ shell_out!("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@new_resource.source}").stdout.each_line do |line|
+ case line
+ when /^([\w\d+_.-]+)\s([\w\d_.-]+)$/
+ @current_resource.package_name($1)
+ @new_resource.version($2)
+ @candidate_version = $2
end
end
else
@@ -77,13 +76,12 @@ class Chef
end
Chef::Log.debug("#{@new_resource} checking install state")
- @rpm_status = popen4("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@current_resource.package_name}") do |pid, stdin, stdout, stderr|
- stdout.each do |line|
- case line
- when /^([\w\d+_.-]+)\s([\w\d_.-]+)$/
- Chef::Log.debug("#{@new_resource} current version is #{$2}")
- @current_resource.version($2)
- end
+ @rpm_status = shell_out("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@current_resource.package_name}")
+ @rpm_status.stdout.each_line do |line|
+ case line
+ when /^([\w\d+_.-]+)\s([\w\d_.-]+)$/
+ Chef::Log.debug("#{@new_resource} current version is #{$2}")
+ @current_resource.version($2)
end
end
@@ -94,7 +92,11 @@ class Chef
unless @current_resource.version
shell_out!( "rpm #{@new_resource.options} -i #{@new_resource.source}" )
else
- shell_out!( "rpm #{@new_resource.options} -U #{@new_resource.source}" )
+ if allow_downgrade
+ shell_out!( "rpm #{@new_resource.options} -U --oldpackage #{@new_resource.source}" )
+ else
+ shell_out!( "rpm #{@new_resource.options} -U #{@new_resource.source}" )
+ end
end
end
@@ -108,6 +110,15 @@ class Chef
end
end
+ private
+
+ def uri_scheme?(str)
+ scheme = URI.split(str).first
+ return false unless scheme
+ %w(http https ftp file).include?(scheme.downcase)
+ rescue URI::InvalidURIError
+ return false
+ end
end
end
end
diff --git a/lib/chef/provider/package/rubygems.rb b/lib/chef/provider/package/rubygems.rb
index 3c0ca40693..ff1e346cd1 100644
--- a/lib/chef/provider/package/rubygems.rb
+++ b/lib/chef/provider/package/rubygems.rb
@@ -17,6 +17,7 @@
# limitations under the License.
#
+require 'uri'
require 'chef/provider/package'
require 'chef/mixin/command'
require 'chef/resource/package'
@@ -130,7 +131,7 @@ class Chef
##
# Determines the candidate version for a gem from a .gem file on disk
- # and checks if it matches the version contraints in +gem_dependency+
+ # and checks if it matches the version constraints in +gem_dependency+
# === Returns
# Gem::Version a singular gem version object is returned if the gem
# is available
@@ -483,7 +484,7 @@ class Chef
def candidate_version
@candidate_version ||= begin
- if target_version_already_installed?
+ if target_version_already_installed?(@current_resource.version, @new_resource.version)
nil
elsif source_is_remote?
@gem_env.candidate_version_from_remote(gem_dependency, *gem_sources).to_s
@@ -493,12 +494,11 @@ class Chef
end
end
- def target_version_already_installed?
- return false unless @current_resource && @current_resource.version
- return false if @current_resource.version.nil?
- return false if @new_resource.version.nil?
+ def target_version_already_installed?(current_version, new_version)
+ return false unless current_version
+ return false if new_version.nil?
- Gem::Requirement.new(@new_resource.version).satisfied_by?(Gem::Version.new(@current_resource.version))
+ Gem::Requirement.new(new_version).satisfied_by?(Gem::Version.new(current_version))
end
##
@@ -534,9 +534,9 @@ class Chef
if @new_resource.source =~ /\.gem$/i
name = @new_resource.source
else
- src = @new_resource.source && " --source=#{@new_resource.source} --source=http://rubygems.org"
+ src = @new_resource.source && " --source=#{@new_resource.source} --source=https://rubygems.org"
end
- if version
+ if !version.nil? && version.length > 0
shell_out!("#{gem_binary_path} install #{name} -q --no-rdoc --no-ri -v \"#{version}\"#{src}#{opts}", :env=>nil)
else
shell_out!("#{gem_binary_path} install \"#{name}\" -q --no-rdoc --no-ri #{src}#{opts}", :env=>nil)
diff --git a/lib/chef/provider/package/solaris.rb b/lib/chef/provider/package/solaris.rb
index 53dd00dd07..a2cfd93ef6 100644
--- a/lib/chef/provider/package/solaris.rb
+++ b/lib/chef/provider/package/solaris.rb
@@ -55,25 +55,22 @@ class Chef
@package_source_found = ::File.exists?(@new_resource.source)
if @package_source_found
Chef::Log.debug("#{@new_resource} checking pkg status")
- status = popen4("pkginfo -l -d #{@new_resource.source} #{@new_resource.package_name}") do |pid, stdin, stdout, stderr|
- stdout.each do |line|
- case line
- when /VERSION:\s+(.+)/
- @new_resource.version($1)
- end
+ shell_out("pkginfo -l -d #{@new_resource.source} #{@new_resource.package_name}").stdout.each_line do |line|
+ case line
+ when /VERSION:\s+(.+)/
+ @new_resource.version($1)
end
end
end
end
Chef::Log.debug("#{@new_resource} checking install state")
- status = popen4("pkginfo -l #{@current_resource.package_name}") do |pid, stdin, stdout, stderr|
- stdout.each do |line|
- case line
- when /VERSION:\s+(.+)/
- Chef::Log.debug("#{@new_resource} version #{$1} is already installed")
- @current_resource.version($1)
- end
+ status = shell_out("pkginfo -l #{@current_resource.package_name}")
+ status.stdout.each_line do |line|
+ case line
+ when /VERSION:\s+(.+)/
+ Chef::Log.debug("#{@new_resource} version #{$1} is already installed")
+ @current_resource.version($1)
end
end
@@ -90,14 +87,13 @@ class Chef
def candidate_version
return @candidate_version if @candidate_version
- status = popen4("pkginfo -l -d #{@new_resource.source} #{new_resource.package_name}") do |pid, stdin, stdout, stderr|
- stdout.each_line do |line|
- case line
- when /VERSION:\s+(.+)/
- @candidate_version = $1
- @new_resource.version($1)
- Chef::Log.debug("#{@new_resource} setting install candidate version to #{@candidate_version}")
- end
+ status = shell_out("pkginfo -l -d #{@new_resource.source} #{new_resource.package_name}")
+ status.stdout.each_line do |line|
+ case line
+ when /VERSION:\s+(.+)/
+ @candidate_version = $1
+ @new_resource.version($1)
+ Chef::Log.debug("#{@new_resource} setting install candidate version to #{@candidate_version}")
end
end
unless status.exitstatus == 0
diff --git a/lib/chef/provider/package/windows/msi.rb b/lib/chef/provider/package/windows/msi.rb
index e43a307cca..938452945e 100644
--- a/lib/chef/provider/package/windows/msi.rb
+++ b/lib/chef/provider/package/windows/msi.rb
@@ -42,7 +42,7 @@ class Chef
def installed_version
Chef::Log.debug("#{@new_resource} getting product code for package at #{@new_resource.source}")
product_code = get_product_property(@new_resource.source, "ProductCode")
- Chef::Log.debug("#{@new_resource} checking package status and verion for #{product_code}")
+ Chef::Log.debug("#{@new_resource} checking package status and version for #{product_code}")
get_installed_version(product_code)
end
diff --git a/lib/chef/provider/package/yum-dump.py b/lib/chef/provider/package/yum-dump.py
index 8b09dedbf0..c9f6a1fcea 100644
--- a/lib/chef/provider/package/yum-dump.py
+++ b/lib/chef/provider/package/yum-dump.py
@@ -23,7 +23,7 @@
# and dump the results to stdout.
#
# yum-dump invokes yum similarly to the command line interface which makes it
-# subject to most of the configuration paramaters in yum.conf. yum-dump will
+# subject to most of the configuration parameters in yum.conf. yum-dump will
# also load yum plugins in the same manor as yum - these can affect the output.
#
# Can be run as non root, but that won't update the cache.
@@ -70,7 +70,7 @@ def setup(yb, options):
else:
yb.doConfigSetup(errorlevel=0, debuglevel=0)
except yum.Errors.ConfigError, e:
- # supresses an ignored exception at exit
+ # suppresses an ignored exception at exit
yb.preconf = None
print >> sys.stderr, "yum-dump Config Error: %s" % e
return 1
diff --git a/lib/chef/provider/package/yum.rb b/lib/chef/provider/package/yum.rb
index 505f5fd6a3..405e4177ab 100644
--- a/lib/chef/provider/package/yum.rb
+++ b/lib/chef/provider/package/yum.rb
@@ -18,7 +18,7 @@
require 'chef/config'
require 'chef/provider/package'
-require 'chef/mixin/command'
+require 'chef/mixin/command' # handle_command_failures
require 'chef/mixin/shell_out'
require 'chef/resource/package'
require 'singleton'
@@ -976,14 +976,6 @@ class Chef
end
end
- def allow_downgrade
- if @new_resource.respond_to?("allow_downgrade")
- @new_resource.allow_downgrade
- else
- false
- end
- end
-
# Helpers
#
@@ -1018,7 +1010,7 @@ class Chef
if status.exitstatus > 0
command_output = "STDOUT: #{stdout}"
command_output << "STDERR: #{stderr}"
- handle_command_failures(status, command_output, {})
+ Chef::Mixin::Command.handle_command_failures(status, command_output, {})
end
end
@@ -1054,9 +1046,20 @@ class Chef
# 3) or a dependency, eg: "foo >= 1.1"
# Check if we have name or name+arch which has a priority over a dependency
- unless @yum.package_available?(@new_resource.package_name)
- # If they aren't in the installed packages they could be a dependency
- parse_dependency
+ package_name_array.each_with_index do |n, index|
+ unless @yum.package_available?(n)
+ # If they aren't in the installed packages they could be a dependency
+ dep = parse_dependency(n, new_version_array[index])
+ if dep
+ if @new_resource.package_name.is_a?(Array)
+ @new_resource.package_name(package_name_array - [n] + [dep.first])
+ @new_resource.version(new_version_array - [new_version_array[index]] + [dep.last]) if dep.last
+ else
+ @new_resource.package_name(dep.first)
+ @new_resource.version(dep.last) if dep.last
+ end
+ end
+ end
end
# Don't overwrite an existing arch
@@ -1090,10 +1093,18 @@ class Chef
Chef::Log.debug("#{@new_resource} checking yum info for #{new_resource}")
- installed_version = @yum.installed_version(@new_resource.package_name, arch)
- @current_resource.version(installed_version)
-
- @candidate_version = @yum.candidate_version(@new_resource.package_name, arch)
+ installed_version = []
+ @candidate_version = []
+ package_name_array.each do |pkg|
+ installed_version << @yum.installed_version(pkg, arch)
+ @candidate_version << @yum.candidate_version(pkg, arch)
+ end
+ if installed_version.size == 1
+ @current_resource.version(installed_version[0])
+ @candidate_version = @candidate_version[0]
+ else
+ @current_resource.version(installed_version)
+ end
Chef::Log.debug("#{@new_resource} installed version: #{installed_version || "(none)"} candidate version: " +
"#{@candidate_version || "(none)"}")
@@ -1101,43 +1112,77 @@ class Chef
@current_resource
end
- def install_package(name, version)
- if @new_resource.source
- yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} localinstall #{@new_resource.source}")
- else
- # Work around yum not exiting with an error if a package doesn't exist for CHEF-2062
- if @yum.version_available?(name, version, arch)
+ def install_remote_package(name, version)
+ # Work around yum not exiting with an error if a package doesn't exist
+ # for CHEF-2062
+ all_avail = as_array(name).zip(as_array(version)).any? do |n, v|
+ @yum.version_available?(n, v, arch)
+ end
+ method = log_method = nil
+ methods = []
+ if all_avail
+ # More Yum fun:
+ #
+ # yum install of an old name+version will exit(1)
+ # yum install of an old name+version+arch will exit(0) for some reason
+ #
+ # Some packages can be installed multiple times like the kernel
+ as_array(name).zip(as_array(version)).each do |n, v|
method = "install"
log_method = "installing"
-
- # More Yum fun:
- #
- # yum install of an old name+version will exit(1)
- # yum install of an old name+version+arch will exit(0) for some reason
- #
- # Some packages can be installed multiple times like the kernel
- unless @yum.allow_multi_install.include?(name)
- if RPMVersion.parse(@current_resource.version) > RPMVersion.parse(version)
- # Unless they want this...
+ idx = package_name_array.index(n)
+ unless @yum.allow_multi_install.include?(n)
+ if RPMVersion.parse(current_version_array[idx]) > RPMVersion.parse(v)
+ # We allow downgrading only in the evenit of single-package
+ # rules where the user explicitly allowed it
if allow_downgrade
method = "downgrade"
log_method = "downgrading"
else
# we bail like yum when the package is older
- raise Chef::Exceptions::Package, "Installed package #{name}-#{@current_resource.version} is newer " +
- "than candidate package #{name}-#{version}"
+ raise Chef::Exceptions::Package, "Installed package #{n}-#{current_version_array[idx]} is newer " +
+ "than candidate package #{n}-#{v}"
end
end
end
+ # methods don't count for packages we won't be touching
+ next if RPMVersion.parse(current_version_array[idx]) == RPMVersion.parse(v)
+ methods << method
+ end
- repo = @yum.package_repository(name, version, arch)
- Chef::Log.info("#{@new_resource} #{log_method} #{name}-#{version}#{yum_arch} from #{repo} repository")
+ # We could split this up into two commands if we wanted to, but
+ # for now, just don't support this.
+ if methods.uniq.length > 1
+ raise Chef::Exceptions::Package, "Multipackage rule #{name} has a mix of upgrade and downgrade packages. Cannot proceed."
+ end
- yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} #{method} #{name}-#{version}#{yum_arch}")
- else
- raise Chef::Exceptions::Package, "Version #{version} of #{name} not found. Did you specify both version " +
- "and release? (version-release, e.g. 1.84-10.fc6)"
+ repos = []
+ pkg_string_bits = []
+ index = 0
+ as_array(name).zip(as_array(version)).each do |n, v|
+ s = ''
+ unless v == current_version_array[index]
+ s = "#{n}-#{v}#{yum_arch}"
+ repo = @yum.package_repository(n, v, arch)
+ repos << "#{s} from #{repo} repository"
+ pkg_string_bits << s
+ end
+ index += 1
end
+ pkg_string = pkg_string_bits.join(' ')
+ Chef::Log.info("#{@new_resource} #{log_method} #{repos.join(' ')}")
+ yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} #{method} #{pkg_string}")
+ else
+ raise Chef::Exceptions::Package, "Version #{version} of #{name} not found. Did you specify both version " +
+ "and release? (version-release, e.g. 1.84-10.fc6)"
+ end
+ end
+
+ def install_package(name, version)
+ if @new_resource.source
+ yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} localinstall #{@new_resource.source}")
+ else
+ install_remote_package(name, version)
end
if flush_cache[:after]
@@ -1156,10 +1201,11 @@ class Chef
# Hacky - better overall solution? Custom compare in Package provider?
def action_upgrade
# Could be uninstalled or have no candidate
- if @current_resource.version.nil? || candidate_version.nil?
+ if @current_resource.version.nil? || !candidate_version_array.any?
super
- # Ensure the candidate is newer
- elsif RPMVersion.parse(candidate_version) > RPMVersion.parse(@current_resource.version)
+ elsif candidate_version_array.zip(current_version_array).any? do |c, i|
+ RPMVersion.parse(c) > RPMVersion.parse(i)
+ end
super
else
Chef::Log.debug("#{@new_resource} is at the latest version - nothing to do")
@@ -1172,10 +1218,13 @@ class Chef
def remove_package(name, version)
if version
- yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} remove #{name}-#{version}#{yum_arch}")
+ remove_str = as_array(name).zip(as_array(version)).map do |x|
+ "#{x.join('-')}#{yum_arch}"
+ end.join(' ')
else
- yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} remove #{name}#{yum_arch}")
+ remove_str = as_array(name).map { |n| "#{n}#{yum_arch}" }.join(' ')
end
+ yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} remove #{remove_str}")
if flush_cache[:after]
@yum.reload
@@ -1218,9 +1267,19 @@ class Chef
# matching them up with an actual package so the standard resource handling can apply.
#
# There is currently no support for filename matching.
- def parse_dependency
+ def parse_dependency(name,version)
# Transform the package_name into a requirement
- yum_require = RPMRequire.parse(@new_resource.package_name)
+
+ # If we are passed a version or a version constraint we have to assume it's a requirement first. If it can't be
+ # parsed only yum_require.name will be set and @new_resource.version will be left intact
+ if version
+ require_string = "#{name} #{version}"
+ else
+ # Transform the package_name into a requirement, might contain a version, could just be
+ # a match for virtual provides
+ require_string = name
+ end
+ yum_require = RPMRequire.parse(require_string)
# and gather all the packages that have a Provides feature satisfying the requirement.
# It could be multiple be we can only manage one
packages = @yum.packages_from_require(yum_require)
@@ -1238,8 +1297,11 @@ class Chef
unless packages.empty?
new_package_name = packages.first.name
- Chef::Log.debug("#{@new_resource} no package found for #{@new_resource.package_name} " +
- "but matched Provides for #{new_package_name}")
+ new_package_version = packages.first.version.to_s
+ debug_msg = "#{name}: Unable to match package '#{name}' but matched #{packages.size} "
+ debug_msg << packages.size == 1 ? "package" : "packages"
+ debug_msg << ", selected '#{new_package_name}' version '#{new_package_version}'"
+ Chef::Log.debug(debug_msg)
# Ensure it's not the same package under a different architecture
unique_names = []
@@ -1254,7 +1316,11 @@ class Chef
"specific version.")
end
- @new_resource.package_name(new_package_name)
+ if yum_require.version.to_s.nil?
+ new_package_version = nil
+ end
+
+ [new_package_name,new_package_version]
end
end
diff --git a/lib/chef/provider/package/zypper.rb b/lib/chef/provider/package/zypper.rb
index b00bef0f92..2cd321660b 100644
--- a/lib/chef/provider/package/zypper.rb
+++ b/lib/chef/provider/package/zypper.rb
@@ -38,24 +38,23 @@ class Chef
version=''
oud_version=''
Chef::Log.debug("#{@new_resource} checking zypper")
- status = popen4("zypper --non-interactive info #{@new_resource.package_name}") do |pid, stdin, stdout, stderr|
- stdout.each do |line|
- case line
- when /^Version: (.+)$/
- version = $1
- Chef::Log.debug("#{@new_resource} version #{$1}")
- when /^Installed: Yes$/
- is_installed=true
- Chef::Log.debug("#{@new_resource} is installed")
-
- when /^Installed: No$/
- is_installed=false
- Chef::Log.debug("#{@new_resource} is not installed")
- when /^Status: out-of-date \(version (.+) installed\)$/
- is_out_of_date=true
- oud_version=$1
- Chef::Log.debug("#{@new_resource} out of date version #{$1}")
- end
+ status = shell_out("zypper --non-interactive info #{@new_resource.package_name}")
+ status.stdout.each_line do |line|
+ case line
+ when /^Version: (.+)$/
+ version = $1
+ Chef::Log.debug("#{@new_resource} version #{$1}")
+ when /^Installed: Yes$/
+ is_installed=true
+ Chef::Log.debug("#{@new_resource} is installed")
+
+ when /^Installed: No$/
+ is_installed=false
+ Chef::Log.debug("#{@new_resource} is not installed")
+ when /^Status: out-of-date \(version (.+) installed\)$/
+ is_out_of_date=true
+ oud_version=$1
+ Chef::Log.debug("#{@new_resource} out of date version #{$1}")
end
end
diff --git a/lib/chef/provider/powershell_script.rb b/lib/chef/provider/powershell_script.rb
index 0e76cd1656..8c79b384e9 100644
--- a/lib/chef/provider/powershell_script.rb
+++ b/lib/chef/provider/powershell_script.rb
@@ -24,8 +24,8 @@ class Chef
protected
EXIT_STATUS_EXCEPTION_HANDLER = "\ntrap [Exception] {write-error -exception ($_.Exception.Message);exit 1}".freeze
- EXIT_STATUS_NORMALIZATION_SCRIPT = "\nif ($? -ne $true) { if ( $LASTEXITCODE -ne 0) {exit $LASTEXITCODE} else { exit 1 }}".freeze
- EXIT_STATUS_RESET_SCRIPT = "\n$LASTEXITCODE=0".freeze
+ EXIT_STATUS_NORMALIZATION_SCRIPT = "\nif ($? -ne $true) { if ( $LASTEXITCODE ) {exit $LASTEXITCODE} else { exit 1 }}".freeze
+ EXIT_STATUS_RESET_SCRIPT = "\n$global:LASTEXITCODE=$null".freeze
# Process exit codes are strange with PowerShell. Unless you
# explicitly call exit in Powershell, the powershell.exe
@@ -43,7 +43,7 @@ class Chef
code.to_s +
EXIT_STATUS_NORMALIZATION_SCRIPT )
convert_boolean_return = @new_resource.convert_boolean_return
- @code = <<EOH
+ self.code = <<EOH
new-variable -name interpolatedexitcode -visibility private -value $#{convert_boolean_return}
new-variable -name chefscriptresult -visibility private
$chefscriptresult = {
@@ -52,7 +52,7 @@ $chefscriptresult = {
if ($interpolatedexitcode -and $chefscriptresult.gettype().name -eq 'boolean') { exit [int32](!$chefscriptresult) } else { exit 0 }
EOH
Chef::Log.debug("powershell_script provider called with script code:\n\n#{code}\n")
- Chef::Log.debug("powershell_script provider will execute transformed code:\n\n#{@code}\n")
+ Chef::Log.debug("powershell_script provider will execute transformed code:\n\n#{self.code}\n")
end
public
diff --git a/lib/chef/provider/registry_key.rb b/lib/chef/provider/registry_key.rb
index 01ee57895e..94f4e2655b 100644
--- a/lib/chef/provider/registry_key.rb
+++ b/lib/chef/provider/registry_key.rb
@@ -60,9 +60,9 @@ class Chef
@registry ||= Chef::Win32::Registry.new(@run_context, @new_resource.architecture)
end
- def values_to_hash(values)
+ def values_to_hash(values)
if values
- @name_hash = Hash[values.map { |val| [val[:name], val] }]
+ @name_hash = Hash[values.map { |val| [val[:name], val] }]
else
@name_hash = {}
end
diff --git a/lib/chef/provider/remote_directory.rb b/lib/chef/provider/remote_directory.rb
index 9a7416e318..eaccce46cf 100644
--- a/lib/chef/provider/remote_directory.rb
+++ b/lib/chef/provider/remote_directory.rb
@@ -44,7 +44,7 @@ class Chef
# Transfer files
files_to_transfer.each do |cookbook_file_relative_path|
create_cookbook_file(cookbook_file_relative_path)
- # parent directories and file being transfered are removed from the purge list
+ # parent directories and file being transferred are removed from the purge list
Pathname.new(Chef::Util::PathHelper.cleanpath(::File.join(@new_resource.path, cookbook_file_relative_path))).descend do |d|
files_to_purge.delete(d.to_s)
end
diff --git a/lib/chef/provider/script.rb b/lib/chef/provider/script.rb
index 1615517553..e8b5235b7a 100644
--- a/lib/chef/provider/script.rb
+++ b/lib/chef/provider/script.rb
@@ -18,10 +18,13 @@
require 'tempfile'
require 'chef/provider/execute'
+require 'forwardable'
class Chef
class Provider
class Script < Chef::Provider::Execute
+ extend Forwardable
+
provides :bash
provides :csh
provides :perl
@@ -29,30 +32,43 @@ class Chef
provides :ruby
provides :script
+ def_delegators :@new_resource, :interpreter, :flags
+
+ attr_accessor :code
+
def initialize(new_resource, run_context)
super
- @code = @new_resource.code
+ self.code = new_resource.code
+ end
+
+ def command
+ "\"#{interpreter}\" #{flags} \"#{script_file.path}\""
+ end
+
+ def load_current_resource
+ super
+ # @todo Chef-13: change this to an exception
+ if code.nil?
+ Chef::Log.warn "#{@new_resource}: No code attribute was given, resource does nothing, this behavior is deprecated and will be removed in Chef-13"
+ end
end
def action_run
- script_file.puts(@code)
+ script_file.puts(code)
script_file.close
set_owner_and_group
- @new_resource.command("\"#{interpreter}\" #{flags} \"#{script_file.path}\"")
super
- converge_by(nil) do
- # ensure script is unlinked at end of converge!
- unlink_script_file
- end
+
+ unlink_script_file
end
def set_owner_and_group
# FileUtils itself implements a no-op if +user+ or +group+ are nil
# You can prove this by running FileUtils.chown(nil,nil,'/tmp/file')
# as an unprivileged user.
- FileUtils.chown(@new_resource.user, @new_resource.group, script_file.path)
+ FileUtils.chown(new_resource.user, new_resource.group, script_file.path)
end
def script_file
@@ -60,16 +76,9 @@ class Chef
end
def unlink_script_file
- @script_file && @script_file.close!
+ script_file && script_file.close!
end
- def interpreter
- @new_resource.interpreter
- end
-
- def flags
- @new_resource.flags
- end
end
end
end
diff --git a/lib/chef/provider/service.rb b/lib/chef/provider/service.rb
index 968f9bff9c..75da2ddb31 100644
--- a/lib/chef/provider/service.rb
+++ b/lib/chef/provider/service.rb
@@ -150,7 +150,7 @@ class Chef
end
def reload_service
- raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :restart"
+ raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reload"
end
protected
diff --git a/lib/chef/provider/service/freebsd.rb b/lib/chef/provider/service/freebsd.rb
index 49ba0d7d16..9204e3ef92 100644
--- a/lib/chef/provider/service/freebsd.rb
+++ b/lib/chef/provider/service/freebsd.rb
@@ -180,7 +180,7 @@ class Chef
def set_service_enable(value)
lines = read_rc_conf
# Remove line that set the old value
- lines.delete_if { |line| line =~ /^#{Regexp.escape(service_enable_variable_name)}=/ }
+ lines.delete_if { |line| line =~ /^\#?\s*#{Regexp.escape(service_enable_variable_name)}=/ }
# And append the line that sets the new value at the end
lines << "#{service_enable_variable_name}=\"#{value}\""
write_rc_conf(lines)
diff --git a/lib/chef/provider/service/openbsd.rb b/lib/chef/provider/service/openbsd.rb
new file mode 100644
index 0000000000..d509ee10ff
--- /dev/null
+++ b/lib/chef/provider/service/openbsd.rb
@@ -0,0 +1,216 @@
+#
+# Author:: Scott Bonds (<scott@ggr.com>)
+# Copyright:: Copyright (c) 2014 Scott Bonds
+# 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/mixin/command'
+require 'chef/mixin/shell_out'
+require 'chef/provider/service/init'
+require 'chef/resource/service'
+
+class Chef
+ class Provider
+ class Service
+ class Openbsd < Chef::Provider::Service::Init
+
+ provides :service, os: [ "openbsd" ]
+
+ include Chef::Mixin::ShellOut
+
+ attr_reader :init_command, :rc_conf, :rc_conf_local, :enabled_state_found
+
+ RC_CONF_PATH = '/etc/rc.conf'
+ RC_CONF_LOCAL_PATH = '/etc/rc.conf.local'
+
+ def initialize(new_resource, run_context)
+ super
+ @rc_conf = ::File.read(RC_CONF_PATH) rescue ''
+ @rc_conf_local = ::File.read(RC_CONF_LOCAL_PATH) rescue ''
+ @init_command = ::File.exist?(rcd_script_path) ? rcd_script_path : nil
+ new_resource.supports[:status] = true
+ new_resource.status_command("#{default_init_command} check")
+ end
+
+ def load_current_resource
+ @current_resource = Chef::Resource::Service.new(new_resource.name)
+ current_resource.service_name(new_resource.service_name)
+
+ Chef::Log.debug("#{current_resource} found at #{init_command}")
+
+ determine_current_status!
+ determine_enabled_status!
+ current_resource
+ end
+
+ def define_resource_requirements
+ shared_resource_requirements
+
+ requirements.assert(:start, :enable, :reload, :restart) do |a|
+ a.assertion { init_command }
+ a.failure_message Chef::Exceptions::Service, "#{new_resource}: unable to locate the rc.d script"
+ end
+
+ requirements.assert(:all_actions) do |a|
+ a.assertion { enabled_state_found }
+ # for consistency with original behavior, this will not fail in non-whyrun mode;
+ # rather it will silently set enabled state=>false
+ a.whyrun "Unable to determine enabled/disabled state, assuming this will be correct for an actual run. Assuming disabled."
+ end
+
+ requirements.assert(:start, :enable, :reload, :restart) do |a|
+ a.assertion { init_command && builtin_service_enable_variable_name != nil }
+ a.failure_message Chef::Exceptions::Service, "Could not find the service name in #{init_command} and rcvar"
+ # No recovery in whyrun mode - the init file is present but not correct.
+ end
+ end
+
+ def enable_service
+ if !is_enabled?
+ if is_builtin?
+ if is_enabled_by_default?
+ update_rcl rc_conf_local.sub(/^#{Regexp.escape(builtin_service_enable_variable_name)}=.*/, '')
+ else
+ # add line with blank string, which means enable
+ update_rcl rc_conf_local + "\n" + "#{builtin_service_enable_variable_name}=\"\"\n"
+ end
+ else
+ # add to pkg_scripts, most recent addition goes last
+ old_services_list = rc_conf_local.match(/^pkg_scripts="(.*)"/)
+ old_services_list = old_services_list ? old_services_list[1].split(' ') : []
+ new_services_list = old_services_list + [new_resource.service_name]
+ if rc_conf_local.match(/^pkg_scripts="(.*)"/)
+ new_rcl = rc_conf_local.sub(/^pkg_scripts="(.*)"/, "pkg_scripts=\"#{new_services_list.join(' ')}\"")
+ else
+ new_rcl = rc_conf_local + "\n" + "pkg_scripts=\"#{new_services_list.join(' ')}\"\n"
+ end
+ update_rcl new_rcl
+ end
+ end
+ end
+
+ def disable_service
+ if is_enabled?
+ if is_builtin?
+ if is_enabled_by_default?
+ # add line to disable
+ update_rcl rc_conf_local + "\n" + "#{builtin_service_enable_variable_name}=\"NO\"\n"
+ else
+ # remove line to disable
+ update_rcl rc_conf_local.sub(/^#{Regexp.escape(builtin_service_enable_variable_name)}=.*/, '')
+ end
+ else
+ # remove from pkg_scripts
+ old_list = rc_conf_local.match(/^pkg_scripts="(.*)"/)
+ old_list = old_list ? old_list[1].split(' ') : []
+ new_list = old_list - [new_resource.service_name]
+ update_rcl rc_conf_local.sub(/^pkg_scripts="(.*)"/, pkg_scripts="#{new_list.join(' ')}")
+ end
+ end
+ end
+
+ private
+
+ def rcd_script_found?
+ !init_command.nil?
+ end
+
+ def rcd_script_path
+ "/etc/rc.d/#{new_resource.service_name}"
+ end
+
+ def update_rcl(value)
+ FileUtils.touch RC_CONF_LOCAL_PATH if !::File.exists? RC_CONF_LOCAL_PATH
+ ::File.write(RC_CONF_LOCAL_PATH, value)
+ @rc_conf_local = value
+ end
+
+ # The variable name used in /etc/rc.conf.local for enabling this service
+ def builtin_service_enable_variable_name
+ @bsevn ||= begin
+ result = nil
+ if rcd_script_found?
+ ::File.open(init_command) do |rcscript|
+ if m = rcscript.read.match(/^# \$OpenBSD: (\w+)[(.rc),]?/)
+ result = m[1] + "_flags"
+ end
+ end
+ end
+ # Fallback allows us to keep running in whyrun mode when
+ # the script does not exist.
+ result || new_resource.service_name
+ end
+ end
+
+ def is_builtin?
+ result = false
+ var_name = builtin_service_enable_variable_name
+ if var_name
+ if rc_conf.match(/^#{Regexp.escape(var_name)}=(.*)/)
+ result = true
+ end
+ end
+ result
+ end
+
+ def is_enabled_by_default?
+ result = false
+ var_name = builtin_service_enable_variable_name
+ if var_name
+ if m = rc_conf.match(/^#{Regexp.escape(var_name)}=(.*)/)
+ if !(m[1] =~ /"?[Nn][Oo]"?/)
+ result = true
+ end
+ end
+ end
+ result
+ end
+
+ def determine_enabled_status!
+ result = false # Default to disabled if the service doesn't currently exist at all
+ @enabled_state_found = false
+ if is_builtin?
+ var_name = builtin_service_enable_variable_name
+ if var_name
+ if m = rc_conf_local.match(/^#{Regexp.escape(var_name)}=(.*)/)
+ @enabled_state_found = true
+ if !(m[1] =~ /"?[Nn][Oo]"?/) # e.g. looking for httpd_flags=NO
+ result = true
+ end
+ end
+ end
+ if !@enabled_state_found
+ result = is_enabled_by_default?
+ end
+ else
+ var_name = @new_resource.service_name
+ if var_name
+ if m = rc_conf_local.match(/^pkg_scripts="(.*)"/)
+ @enabled_state_found = true
+ if m[1].include?(var_name) # e.g. looking for 'gdm' in pkg_scripts="gdm unbound"
+ result = true
+ end
+ end
+ end
+ end
+
+ current_resource.enabled result
+ end
+ alias :is_enabled? :determine_enabled_status!
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/service/upstart.rb b/lib/chef/provider/service/upstart.rb
index 3a3ddb2385..8d4aa41035 100644
--- a/lib/chef/provider/service/upstart.rb
+++ b/lib/chef/provider/service/upstart.rb
@@ -41,7 +41,7 @@ class Chef
# In chef, when we ask a service to start, we expect it to have started before performing the next step
# since we have top down dependencies. Which is to say we may follow witha resource next that requires
# that service to be running. According to [2] we can trust that sending a 'goal' such as start will not
- # return until that 'goal' is reached, or some error has occured.
+ # return until that 'goal' is reached, or some error has occurred.
#
# [1] http://upstart.ubuntu.com/wiki/JobStates
# [2] http://www.netsplit.com/2008/04/27/upstart-05-events/
diff --git a/lib/chef/provider/service/windows.rb b/lib/chef/provider/service/windows.rb
index d4c272354e..ba53f0a3c3 100644
--- a/lib/chef/provider/service/windows.rb
+++ b/lib/chef/provider/service/windows.rb
@@ -20,6 +20,7 @@
require 'chef/provider/service/simple'
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
+ require 'chef/win32/error'
require 'win32/service'
end
@@ -29,6 +30,7 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
provides :windows_service, os: "windows"
include Chef::Mixin::ShellOut
+ include Chef::ReservedNames::Win32::API::Error rescue LoadError
#Win32::Service.get_start_type
AUTO_START = 'auto start'
@@ -67,6 +69,22 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
def start_service
if Win32::Service.exists?(@new_resource.service_name)
+ # reconfiguration is idempotent, so just do it.
+ new_config = {
+ service_name: @new_resource.service_name,
+ service_start_name: @new_resource.run_as_user,
+ password: @new_resource.run_as_password,
+ }.reject { |k,v| v.nil? || v.length == 0 }
+
+ Win32::Service.configure(new_config)
+ Chef::Log.info "#{@new_resource} configured with #{new_config.inspect}"
+
+ # it would be nice to check if the user already has the logon privilege, but that turns out to be
+ # nontrivial.
+ if new_config.has_key?(:service_start_name)
+ grant_service_logon(new_config[:service_start_name])
+ end
+
state = current_state
if state == RUNNING
Chef::Log.debug "#{@new_resource} already started - nothing to do"
@@ -79,7 +97,17 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
shell_out!(@new_resource.start_command)
else
spawn_command_thread do
- Win32::Service.start(@new_resource.service_name)
+ begin
+ Win32::Service.start(@new_resource.service_name)
+ rescue SystemCallError => ex
+ if ex.errno == ERROR_SERVICE_LOGON_FAILED
+ Chef::Log.error ex.message
+ raise Chef::Exceptions::Service,
+ "Service #{@new_resource} did not start due to a logon failure (error #{ERROR_SERVICE_LOGON_FAILED}): possibly the specified user '#{@new_resource.run_as_user}' does not have the 'log on as a service' privilege, or the password is incorrect."
+ else
+ raise ex
+ end
+ end
end
wait_for_state(RUNNING)
end
@@ -209,6 +237,76 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
end
private
+ def make_policy_text(username)
+ text = <<-EOS
+[Unicode]
+Unicode=yes
+[Privilege Rights]
+SeServiceLogonRight = \\\\#{canonicalize_username(username)},*S-1-5-80-0
+[Version]
+signature="$CHICAGO$"
+Revision=1
+EOS
+ end
+
+ def grant_logfile_name(username)
+ Chef::Util::PathHelper.canonical_path("#{Dir.tmpdir}/logon_grant-#{clean_username_for_path(username)}-#{$$}.log", prefix=false)
+ end
+
+ def grant_policyfile_name(username)
+ Chef::Util::PathHelper.canonical_path("#{Dir.tmpdir}/service_logon_policy-#{clean_username_for_path(username)}-#{$$}.inf", prefix=false)
+ end
+
+ def grant_dbfile_name(username)
+ "#{ENV['TEMP']}\\secedit.sdb"
+ end
+
+ def grant_service_logon(username)
+ logfile = grant_logfile_name(username)
+ policy_file = ::File.new(grant_policyfile_name(username), 'w')
+ policy_text = make_policy_text(username)
+ dbfile = grant_dbfile_name(username) # this is just an audit file.
+
+ begin
+ Chef::Log.debug "Policy file text:\n#{policy_text}"
+ policy_file.puts(policy_text)
+ policy_file.close # need to flush the buffer.
+
+ # it would be nice to do this with APIs instead, but the LSA_* APIs are
+ # particularly onerous and life is short.
+ cmd = %Q{secedit.exe /configure /db "#{dbfile}" /cfg "#{policy_file.path}" /areas USER_RIGHTS SECURITYPOLICY SERVICES /log "#{logfile}"}
+ Chef::Log.debug "Granting logon-as-service privilege with: #{cmd}"
+ runner = shell_out(cmd)
+
+ if runner.exitstatus != 0
+ Chef::Log.fatal "Logon-as-service grant failed with output: #{runner.stdout}"
+ raise Chef::Exceptions::Service, <<-EOS
+Logon-as-service grant failed with policy file #{policy_file.path}.
+You can look at #{logfile} for details, or do `secedit /analyze #{dbfile}`.
+The failed command was `#{cmd}`.
+EOS
+ end
+
+ Chef::Log.info "Grant logon-as-service to user '#{username}' successful."
+
+ ::File.delete(dbfile) rescue nil
+ ::File.delete(policy_file)
+ ::File.delete(logfile) rescue nil # logfile is not always present at end.
+ end
+ true
+ end
+
+ # remove characters that make for broken or wonky filenames.
+ def clean_username_for_path(username)
+ username.gsub(/[\/\\. ]+/, '_')
+ end
+
+ # the security policy file only seems to accept \\username, so fix .\username or .\\username.
+ # TODO: this probably has to be fixed to handle various valid Windows names correctly.
+ def canonicalize_username(username)
+ username.sub(/^\.?\\+/, '')
+ end
+
def current_state
Win32::Service.status(@new_resource.service_name).current_state
end
diff --git a/lib/chef/provider/user.rb b/lib/chef/provider/user.rb
index e554dc7f2f..f6ac72448e 100644
--- a/lib/chef/provider/user.rb
+++ b/lib/chef/provider/user.rb
@@ -67,7 +67,7 @@ class Chef
@current_resource.shell(user_info.shell)
@current_resource.password(user_info.passwd)
- if @new_resource.comment && user_info.gecos.respond_to?(:force_encoding)
+ if @new_resource.comment
user_info.gecos.force_encoding(@new_resource.comment.encoding)
end
@current_resource.comment(user_info.gecos)
diff --git a/lib/chef/provider/user/dscl.rb b/lib/chef/provider/user/dscl.rb
index 84f5145c52..debf36f771 100644
--- a/lib/chef/provider/user/dscl.rb
+++ b/lib/chef/provider/user/dscl.rb
@@ -39,7 +39,7 @@ class Chef
# > 10.7 => password shadow calculation format SALTED-SHA512-PBKDF2
# => stored in: /var/db/dslocal/nodes/Default/users/#{name}.plist
# => shadow binary length 128 bytes
- # => Salt / Iterations are stored seperately in the same file
+ # => Salt / Iterations are stored separately in the same file
#
# This provider only supports Mac OSX versions 10.7 and above
class Dscl < Chef::Provider::User
@@ -239,8 +239,18 @@ user password using shadow hash.")
#
def uid_used?(uid)
return false unless uid
- users_uids = run_dscl("list /Users uid")
- !! ( users_uids =~ Regexp.new("#{Regexp.escape(uid.to_s)}\n") )
+ users_uids = run_dscl("list /Users uid").split("\n")
+ uid_map = users_uids.inject({}) do |tmap, tuid|
+ x = tuid.split
+ tmap[x[1]] = x[0]
+ tmap
+ end
+ if uid_map[uid.to_s]
+ unless uid_map[uid.to_s] == @new_resource.username.to_s
+ return true
+ end
+ end
+ return false
end
#
@@ -504,6 +514,11 @@ user password using shadow hash.")
# password to be updated.
return true if salted_sha512?(@current_resource.password)
+ # Some system users don't have salts; this can happen if the system is
+ # upgraded and the user hasn't logged in yet. In this case, we will force
+ # the password to be updated.
+ return true if @current_resource.salt.nil?
+
if salted_sha512_pbkdf2?(@new_resource.password)
diverged?(:password) || diverged?(:salt) || diverged?(:iterations)
else
@@ -535,7 +550,7 @@ user password using shadow hash.")
# A simple map of Chef's terms to DSCL's terms.
DSCL_PROPERTY_MAP = {
- :uid => "generateduid",
+ :uid => "uid",
:gid => "gid",
:home => "home",
:shell => "shell",
diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb
index c4f1ce769d..796a0f8fa6 100644
--- a/lib/chef/providers.rb
+++ b/lib/chef/providers.rb
@@ -63,6 +63,7 @@ require 'chef/provider/package/freebsd/pkgng'
require 'chef/provider/package/homebrew'
require 'chef/provider/package/ips'
require 'chef/provider/package/macports'
+require 'chef/provider/package/openbsd'
require 'chef/provider/package/pacman'
require 'chef/provider/package/portage'
require 'chef/provider/package/paludis'
@@ -80,6 +81,7 @@ require 'chef/provider/service/gentoo'
require 'chef/provider/service/init'
require 'chef/provider/service/invokercd'
require 'chef/provider/service/debian'
+require 'chef/provider/service/openbsd'
require 'chef/provider/service/redhat'
require 'chef/provider/service/insserv'
require 'chef/provider/service/simple'
diff --git a/lib/chef/recipe.rb b/lib/chef/recipe.rb
index de72a8d0c4..91f7f30aa9 100644
--- a/lib/chef/recipe.rb
+++ b/lib/chef/recipe.rb
@@ -24,6 +24,7 @@ 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/mixin/from_file'
@@ -40,6 +41,7 @@ class Chef
include Chef::DSL::Recipe
include Chef::DSL::RegistryHelper
include Chef::DSL::RebootPending
+ include Chef::DSL::Audit
include Chef::Mixin::FromFile
include Chef::Mixin::Deprecation
@@ -52,12 +54,16 @@ class Chef
# For example:
# "aws::elastic_ip" returns [:aws, "elastic_ip"]
# "aws" returns [:aws, "default"]
+ # "::elastic_ip" returns [ current_cookbook, "elastic_ip" ]
#--
# TODO: Duplicates functionality of RunListItem
- def self.parse_recipe_name(recipe_name)
- rmatch = recipe_name.match(/(.+?)::(.+)/)
- if rmatch
- [ rmatch[1].to_sym, rmatch[2] ]
+ def self.parse_recipe_name(recipe_name, current_cookbook: nil)
+ case recipe_name
+ when /(.+?)::(.+)/
+ [ $1.to_sym, $2 ]
+ when /^::(.+)/
+ raise "current_cookbook is nil, cannot resolve #{recipe_name}" if current_cookbook.nil?
+ [ current_cookbook.to_sym, $1 ]
else
[ recipe_name.to_sym, "default" ]
end
@@ -82,7 +88,7 @@ class Chef
run_context.resource_collection.find(*args)
end
- # This was moved to Chef::Node#tag, redirecting here for compatability
+ # This was moved to Chef::Node#tag, redirecting here for compatibility
def tag(*tags)
run_context.node.tag(*tags)
end
diff --git a/lib/chef/request_id.rb b/lib/chef/request_id.rb
index 7fc177c633..2c7af01879 100644
--- a/lib/chef/request_id.rb
+++ b/lib/chef/request_id.rb
@@ -15,7 +15,7 @@
# limitations under the License.
#
-require 'chef/monkey_patches/securerandom'
+require 'securerandom'
require 'singleton'
class Chef
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index 17f109242f..ea220b6c70 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -38,112 +38,60 @@ require 'chef/mixin/descendants_tracker'
class Chef
class Resource
- FORBIDDEN_IVARS = [:@run_context, :@not_if, :@only_if, :@enclosing_provider]
- HIDDEN_IVARS = [:@allowed_actions, :@resource_name, :@source_line, :@run_context, :@name, :@not_if, :@only_if, :@elapsed_time, :@enclosing_provider]
+ #
+ # Generic User DSL (not resource-specific)
+ #
include Chef::DSL::DataQuery
- include Chef::Mixin::ParamsValidate
include Chef::DSL::PlatformIntrospection
include Chef::DSL::RegistryHelper
include Chef::DSL::RebootPending
- include Chef::Mixin::ConvertToClassName
- include Chef::Mixin::Deprecation
- extend Chef::Mixin::ConvertToClassName
- extend Chef::Mixin::DescendantsTracker
-
- if Module.method(:const_defined?).arity == 1
- def self.strict_const_defined?(const)
- const_defined?(const)
- end
- else
- def self.strict_const_defined?(const)
- const_defined?(const, false)
- end
- end
-
- class << self
- # back-compat
- # NOTE: that we do not support unregistering classes as descendents like
- # we used to for LWRP unloading because that was horrible and removed in
- # Chef-12.
- alias :resource_classes :descendants
- alias :find_subclass_by_name :find_descendants_by_name
- end
-
- # Set or return the list of "state attributes" implemented by the Resource
- # subclass. State attributes are attributes that describe the desired state
- # of the system, such as file permissions or ownership. In general, state
- # attributes are attributes that could be populated by examining the state
- # of the system (e.g., File.stat can tell you the permissions on an
- # existing file). Contrarily, attributes that are not "state attributes"
- # usually modify the way Chef itself behaves, for example by providing
- # additional options for a package manager to use when installing a
- # package.
#
- # This list is used by the Chef client auditing system to extract
- # information from resources to describe changes made to the system.
- def self.state_attrs(*attr_names)
- @state_attrs ||= []
- @state_attrs = attr_names unless attr_names.empty?
-
- # Return *all* state_attrs that this class has, including inherited ones
- if superclass.respond_to?(:state_attrs)
- superclass.state_attrs + @state_attrs
- else
- @state_attrs
- end
- end
-
- # Set or return the "identity attribute" for this resource class. This is
- # generally going to be the "name attribute" for this resource. In other
- # words, the resource type plus this attribute uniquely identify a given
- # bit of state that chef manages. For a File resource, this would be the
- # path, for a package resource, it will be the package name. This will show
- # up in chef-client's audit records as a searchable field.
- def self.identity_attr(attr_name=nil)
- @identity_attr ||= nil
- @identity_attr = attr_name if attr_name
-
- # If this class doesn't have an identity attr, we'll defer to the superclass:
- if @identity_attr || !superclass.respond_to?(:identity_attr)
- @identity_attr
- else
- superclass.identity_attr
- end
+ # The node the current Chef run is using.
+ #
+ # Corresponds to `run_context.node`.
+ #
+ # @return [Chef::Node] The node the current Chef run is using.
+ #
+ def node
+ run_context && run_context.node
end
- def self.dsl_name
- convert_to_snake_case(name, 'Chef::Resource')
+ #
+ # Find existing resources by searching the list of existing resources. Possible
+ # forms are:
+ #
+ # find(:file => "foobar")
+ # find(:file => [ "foobar", "baz" ])
+ # find("file[foobar]", "file[baz]")
+ # find("file[foobar,baz]")
+ #
+ # Calls `run_context.resource_collection.find(*args)`
+ #
+ # @return the matching resource, or an Array of matching resources.
+ #
+ # @raise ArgumentError if you feed it bad lookup information
+ # @raise RuntimeError if it can't find the resources you are looking for.
+ #
+ def resources(*args)
+ run_context.resource_collection.find(*args)
end
- attr_accessor :params
- attr_accessor :provider
- attr_accessor :allowed_actions
- attr_accessor :run_context
- attr_accessor :cookbook_name
- attr_accessor :recipe_name
- attr_accessor :enclosing_provider
- attr_accessor :source_line
- attr_accessor :retries
- attr_accessor :retry_delay
- attr_accessor :declared_type
-
- attr_reader :updated
-
- attr_reader :resource_name
- attr_reader :not_if_args
- attr_reader :only_if_args
-
- attr_reader :elapsed_time
-
- attr_reader :default_guard_interpreter
- # Each notify entry is a resource/action pair, modeled as an
- # Struct with a #resource and #action member
+ #
+ # Resource User Interface (for users)
+ #
+ #
+ # Create a new Resource.
+ #
+ # @param name The name of this resource (corresponds to the #name attribute,
+ # used for notifications to this resource).
+ # @param run_context The context of the Chef run. Corresponds to #run_context.
+ #
def initialize(name, run_context=nil)
- @name = name
+ name(name)
@run_context = run_context
@noop = nil
@before = nil
@@ -171,101 +119,54 @@ class Chef
@sensitive = false
end
- # Returns a Hash of attribute => value for the state attributes declared in
- # the resource's class definition.
- def state
- self.class.state_attrs.inject({}) do |state_attrs, attr_name|
- state_attrs[attr_name] = send(attr_name)
- state_attrs
- end
- end
-
- # Returns the value of the identity attribute, if declared. Falls back to
- # #name if no identity attribute is declared.
- def identity
- if identity_attr = self.class.identity_attr
- send(identity_attr)
- else
- name
- end
- end
-
- def updated=(true_or_false)
- Chef::Log.warn("Chef::Resource#updated=(true|false) is deprecated. Please call #updated_by_last_action(true|false) instead.")
- Chef::Log.warn("Called from:")
- caller[0..3].each {|line| Chef::Log.warn(line)}
- updated_by_last_action(true_or_false)
- @updated = true_or_false
- end
-
- def node
- run_context && run_context.node
- end
-
- # If an unknown method is invoked, determine whether the enclosing Provider's
- # lexical scope can fulfill the request. E.g. This happens when the Resource's
- # block invokes new_resource.
- def method_missing(method_symbol, *args, &block)
- if enclosing_provider && enclosing_provider.respond_to?(method_symbol)
- enclosing_provider.send(method_symbol, *args, &block)
- else
- raise NoMethodError, "undefined method `#{method_symbol.to_s}' for #{self.class.to_s}"
- end
- end
-
- def load_prior_resource(resource_type, instance_name)
- begin
- key = "#{resource_type}[#{instance_name}]"
- prior_resource = run_context.resource_collection.lookup(key)
- # if we get here, there is a prior resource (otherwise we'd have jumped
- # to the rescue clause).
- Chef::Log.warn("Cloning resource attributes for #{key} from prior resource (CHEF-3694)")
- Chef::Log.warn("Previous #{prior_resource}: #{prior_resource.source_line}") if prior_resource.source_line
- Chef::Log.warn("Current #{self}: #{self.source_line}") if self.source_line
- prior_resource.instance_variables.each do |iv|
- unless iv.to_sym == :@source_line || iv.to_sym == :@action || iv.to_sym == :@not_if || iv.to_sym == :@only_if
- self.instance_variable_set(iv, prior_resource.instance_variable_get(iv))
- end
+ #
+ # The name of this particular resource.
+ #
+ # This special resource attribute is set automatically from the declaration
+ # of the resource, e.g.
+ #
+ # execute 'Vitruvius' do
+ # command 'ls'
+ # end
+ #
+ # Will set the name to "Vitruvius".
+ #
+ # This is also used in to_s to show the resource name, e.g. `execute[Vitruvius]`.
+ #
+ # This is also used for resource notifications and subscribes in the same manner.
+ #
+ # This will coerce any object into a string via #to_s. Arrays are a special case
+ # so that `package ["foo", "bar"]` becomes package[foo, bar] instead of the more
+ # awkward `package[["foo", "bar"]]` that #to_s would produce.
+ #
+ # @param name [Object] The name to set, typically a String or Array
+ # @return [String] The name of this Resource.
+ #
+ def name(name=nil)
+ if !name.nil?
+ if name.is_a?(Array)
+ @name = name.join(', ')
+ else
+ @name = name.to_s
end
- true
- rescue Chef::Exceptions::ResourceNotFound
- true
end
+ @name
end
- def supports(args={})
- if args.any?
- @supports = args
- else
- @supports
- end
- end
-
- def provider(arg=nil)
- klass = if arg.kind_of?(String) || arg.kind_of?(Symbol)
- lookup_provider_constant(arg)
- else
- arg
- end
- set_or_return(
- :provider,
- klass,
- :kind_of => [ Class ]
- )
- end
-
+ #
+ # The action or actions that will be taken when this resource is run.
+ #
+ # @param arg [Array[Symbol], Symbol] A list of actions (e.g. `:create`)
+ # @return [Array[Symbol]] the list of actions.
+ #
def action(arg=nil)
if arg
action_list = arg.kind_of?(Array) ? arg : [ arg ]
action_list = action_list.collect { |a| a.to_sym }
action_list.each do |action|
validate(
- {
- :action => action,
- },
- {
- :action => { :kind_of => Symbol, :equal_to => @allowed_actions },
- }
+ { action: action },
+ { action: { kind_of: Symbol, equal_to: @allowed_actions } }
)
end
@action = action_list
@@ -274,71 +175,60 @@ class Chef
end
end
- def name(name=nil)
- if !name.nil?
- raise ArgumentError, "name must be a string!" unless name.kind_of?(String)
- @name = name
- end
- @name
- end
-
- def noop(tf=nil)
- if !tf.nil?
- raise ArgumentError, "noop must be true or false!" unless tf == true || tf == false
- @noop = tf
- end
- @noop
- end
-
- def ignore_failure(arg=nil)
- set_or_return(
- :ignore_failure,
- arg,
- :kind_of => [ TrueClass, FalseClass ]
- )
- end
-
- def retries(arg=nil)
- set_or_return(
- :retries,
- arg,
- :kind_of => Integer
- )
- end
-
- def retry_delay(arg=nil)
- set_or_return(
- :retry_delay,
- arg,
- :kind_of => Integer
- )
- end
-
- def sensitive(arg=nil)
- set_or_return(
- :sensitive,
- arg,
- :kind_of => [ TrueClass, FalseClass ]
- )
- end
-
- def epic_fail(arg=nil)
- ignore_failure(arg)
- end
-
- def guard_interpreter(arg=nil)
- if arg.nil?
- @guard_interpreter || @default_guard_interpreter
- else
- set_or_return(
- :guard_interpreter,
- arg,
- :kind_of => Symbol
- )
- end
- end
-
- # Sets up a notification from this resource to the resource specified by +resource_spec+.
+ #
+ # Sets up a notification that will run a particular action on another resource
+ # if and when *this* resource is updated by an action.
+ #
+ # If the action does nothing--does not update this resource, the
+ # notification never triggers.)
+ #
+ # Only one resource may be specified per notification.
+ #
+ # `delayed` notifications will only *ever* happen once per resource, so if
+ # multiple resources all notify a single resource to perform the same action,
+ # the action will only happen once. However, if they ask for different
+ # actions, each action will happen once, in the order they were updated.
+ #
+ # `immediate` notifications will cause the action to be triggered once per
+ # notification, regardless of how many other resources have triggered the
+ # notification as well.
+ #
+ # @param action The action to run on the other resource.
+ # @param resource_spec [String, Hash, Chef::Resource] The resource to run.
+ # @param timing [String, Symbol] When to notify. Has these values:
+ # - `delayed`: Will run the action on the other resource after all other
+ # actions have been run. This is the default.
+ # - `immediate`, `immediately`: Will run the action on the other resource
+ # immediately (before any other action is run).
+ #
+ # @example Resource by string
+ # file '/foo.txt' do
+ # content 'hi'
+ # notifies :create, 'file[/bar.txt]'
+ # end
+ # file '/bar.txt' do
+ # action :nothing
+ # content 'hi'
+ # end
+ # @example Resource by hash
+ # file '/foo.txt' do
+ # content 'hi'
+ # notifies :create, file: '/bar.txt'
+ # end
+ # file '/bar.txt' do
+ # action :nothing
+ # content 'hi'
+ # end
+ # @example Direct Resource
+ # bar = file '/bar.txt' do
+ # action :nothing
+ # content 'hi'
+ # end
+ # file '/foo.txt' do
+ # content 'hi'
+ # notifies :create, bar
+ # end
+ #
def notifies(action, resource_spec, timing=:delayed)
# when using old-style resources(:template => "/foo.txt") style, you
# could end up with multiple resources.
@@ -354,79 +244,348 @@ class Chef
notifies_immediately(action, resource)
else
raise ArgumentError, "invalid timing: #{timing} for notifies(#{action}, #{resources.inspect}, #{timing}) resource #{self} "\
- "Valid timings are: :delayed, :immediate, :immediately"
+ "Valid timings are: :delayed, :immediate, :immediately"
end
end
true
end
- # Iterates over all immediate and delayed notifications, calling
- # resolve_resource_reference on each in turn, causing them to
- # resolve lazy/forward references.
- def resolve_notification_references
- run_context.immediate_notifications(self).each { |n|
- n.resolve_resource_reference(run_context.resource_collection)
- }
- run_context.delayed_notifications(self).each {|n|
- n.resolve_resource_reference(run_context.resource_collection)
- }
+ #
+ # Subscribes to updates from other resources, causing a particular action to
+ # run on *this* resource when the other resource is updated.
+ #
+ # If multiple resources are specified, this resource action will be run if
+ # *any* of them change.
+ #
+ # This notification will only trigger *once*, no matter how many other
+ # resources are updated (or how many actions are run by a particular resource).
+ #
+ # @param action The action to run on the other resource.
+ # @param resources [String, Resource, Array[String, Resource]] The resources to subscribe to.
+ # @param timing [String, Symbol] When to notify. Has these values:
+ # - `delayed`: An update will cause the action to run after all other
+ # actions have been run. This is the default.
+ # - `immediate`, `immediately`: The action will run immediately following
+ # the other resource being updated.
+ #
+ # @example Resources by string
+ # file '/foo.txt' do
+ # content 'hi'
+ # action :nothing
+ # subscribes :create, 'file[/bar.txt]'
+ # end
+ # file '/bar.txt' do
+ # content 'hi'
+ # end
+ # @example Direct resource
+ # bar = file '/bar.txt' do
+ # content 'hi'
+ # end
+ # file '/foo.txt' do
+ # content 'hi'
+ # action :nothing
+ # subscribes :create, '/bar.txt'
+ # end
+ # @example Multiple resources by string
+ # file '/foo.txt' do
+ # content 'hi'
+ # action :nothing
+ # subscribes :create, [ 'file[/bar.txt]', 'file[/baz.txt]' ]
+ # end
+ # file '/bar.txt' do
+ # content 'hi'
+ # end
+ # file '/baz.txt' do
+ # content 'hi'
+ # end
+ # @example Multiple resources
+ # bar = file '/bar.txt' do
+ # content 'hi'
+ # end
+ # baz = file '/bar.txt' do
+ # content 'hi'
+ # end
+ # file '/foo.txt' do
+ # content 'hi'
+ # action :nothing
+ # subscribes :create, [ bar, baz ]
+ # end
+ #
+ def subscribes(action, resources, timing=:delayed)
+ resources = [resources].flatten
+ resources.each do |resource|
+ if resource.is_a?(String)
+ resource = Chef::Resource.new(resource, run_context)
+ end
+ if resource.run_context.nil?
+ resource.run_context = run_context
+ end
+ resource.notifies(action, self, timing)
+ end
+ true
end
- def notifies_immediately(action, resource_spec)
- run_context.notifies_immediately(Notification.new(resource_spec, action, self))
+ #
+ # A command or block that indicates whether to actually run this resource.
+ # The command or block is run just before the action actually executes, and
+ # the action will be skipped if the block returns false.
+ #
+ # If a block is specified, it must return `true` in order for the Resource
+ # to be executed.
+ #
+ # If a command is specified, the resource's #guard_interpreter will run the
+ # command and interpret the results according to `opts`. For example, the
+ # default `execute` resource will be treated as `false` if the command
+ # returns a non-zero exit code, and `true` if it returns 0. Thus, in the
+ # default case:
+ #
+ # - `only_if "your command"` will perform the action only if `your command`
+ # returns 0.
+ # - `only_if "your command", valid_exit_codes: [ 1, 2, 3 ]` will perform the
+ # action only if `your command` returns 1, 2, or 3.
+ #
+ # @param command [String] A string to execute.
+ # @param opts [Hash] Options control the execution of the command
+ # @param block [Proc] A ruby block to run. Ignored if a command is given.
+ #
+ def only_if(command=nil, opts={}, &block)
+ if command || block_given?
+ @only_if << Conditional.only_if(self, command, opts, &block)
+ end
+ @only_if
end
- def notifies_delayed(action, resource_spec)
- run_context.notifies_delayed(Notification.new(resource_spec, action, self))
+ #
+ # A command or block that indicates whether to actually run this resource.
+ # The command or block is run just before the action actually executes, and
+ # the action will be skipped if the block returns true.
+ #
+ # If a block is specified, it must return `false` in order for the Resource
+ # to be executed.
+ #
+ # If a command is specified, the resource's #guard_interpreter will run the
+ # command and interpret the results according to `opts`. For example, the
+ # default `execute` resource will be treated as `false` if the command
+ # returns a non-zero exit code, and `true` if it returns 0. Thus, in the
+ # default case:
+ #
+ # - `not_if "your command"` will perform the action only if `your command`
+ # returns a non-zero code.
+ # - `only_if "your command", valid_exit_codes: [ 1, 2, 3 ]` will perform the
+ # action only if `your command` returns something other than 1, 2, or 3.
+ #
+ # @param command [String] A string to execute.
+ # @param opts [Hash] Options control the execution of the command
+ # @param block [Proc] A ruby block to run. Ignored if a command is given.
+ #
+ def not_if(command=nil, opts={}, &block)
+ if command || block_given?
+ @not_if << Conditional.not_if(self, command, opts, &block)
+ end
+ @not_if
end
- def immediate_notifications
- run_context.immediate_notifications(self)
+ #
+ # The number of times to retry this resource if it fails by throwing an
+ # exception while running an action. Default: 0
+ #
+ # When the retries have run out, the Resource will throw the last
+ # exception.
+ #
+ # @param arg [Integer] The number of retries.
+ # @return [Integer] The number of retries.
+ #
+ def retries(arg=nil)
+ set_or_return(:retries, arg, kind_of: Integer)
end
+ attr_writer :retries
- def delayed_notifications
- run_context.delayed_notifications(self)
+ #
+ # The number of seconds to wait between retries. Default: 2.
+ #
+ # @param arg [Integer] The number of seconds to wait between retries.
+ # @return [Integer] The number of seconds to wait between retries.
+ #
+ def retry_delay(arg=nil)
+ set_or_return(:retry_delay, arg, kind_of: Integer)
end
+ attr_writer :retry_delay
- def resources(*args)
- run_context.resource_collection.find(*args)
+ #
+ # Whether to treat this resource's data as sensitive. If set, no resource
+ # data will be displayed in log output.
+ #
+ # @param arg [Boolean] Whether this resource is sensitive or not.
+ # @return [Boolean] Whether this resource is sensitive or not.
+ #
+ def sensitive(arg=nil)
+ set_or_return(:sensitive, arg, :kind_of => [ TrueClass, FalseClass ])
end
+ attr_writer :sensitive
- def subscribes(action, resources, timing=:delayed)
- resources = [resources].flatten
- resources.each do |resource|
- if resource.is_a?(String)
- resource = Chef::Resource.new(resource, run_context)
- end
- if resource.run_context.nil?
- resource.run_context = run_context
- end
- resource.notifies(action, self, timing)
+ # ??? TODO unreferenced. Delete?
+ attr_reader :not_if_args
+ # ??? TODO unreferenced. Delete?
+ attr_reader :only_if_args
+
+ #
+ # The time it took (in seconds) to run the most recently-run action. Not
+ # cumulative across actions. This is set to 0 as soon as a new action starts
+ # running, and set to the elapsed time at the end of the action.
+ #
+ # @return [Integer] The time (in seconds) it took to process the most recent
+ # action. Not cumulative.
+ #
+ attr_reader :elapsed_time
+
+ #
+ # The guard interpreter that will be used to process `only_if` and `not_if`
+ # statements. If left unset, the #default_guard_interpreter will be used.
+ #
+ # Must be a resource class like `Chef::Resource::Execute`, or
+ # a corresponding to the name of a resource. The resource must descend from
+ # `Chef::Resource::Execute`.
+ #
+ # TODO this needs to be coerced on input so that retrieval is consistent.
+ #
+ # @param arg [Class, Symbol, String] The Guard interpreter resource class/
+ # symbol/name.
+ # @return [Class, Symbol, String] The Guard interpreter resource.
+ #
+ def guard_interpreter(arg=nil)
+ if arg.nil?
+ @guard_interpreter || @default_guard_interpreter
+ else
+ set_or_return(:guard_interpreter, arg, :kind_of => Symbol)
end
- true
end
- def validate_resource_spec!(resource_spec)
- run_context.resource_collection.validate_lookup_spec!(resource_spec)
+ #
+ # Get the value of the state attributes in this resource as a hash.
+ #
+ # @return [Hash{Symbol => Object}] A Hash of attribute => value for the
+ # Resource class's `state_attrs`.
+ def state
+ self.class.state_attrs.inject({}) do |state_attrs, attr_name|
+ state_attrs[attr_name] = send(attr_name)
+ state_attrs
+ end
end
- def is(*args)
- if args.size == 1
- args.first
+ #
+ # The value of the identity attribute, if declared. Falls back to #name if
+ # no identity attribute is declared.
+ #
+ # @return The value of the identity attribute.
+ #
+ def identity
+ if identity_attr = self.class.identity_attr
+ send(identity_attr)
else
- return *args
+ name
end
end
- # We usually want to store and reference resources by their declared type and not the actual type that
- # was looked up by the Resolver (IE, "package" becomes YumPackage class). If we have not been provided
- # the declared key we want to fall back on the old to_s key.
- def declared_key
- return to_s if declared_type.nil?
- "#{declared_type}[#{@name}]"
+ #
+ # Whether to ignore failures. If set to `true`, and this resource when an
+ # action is run, the resource will be marked as failed but no exception will
+ # be thrown (and no error will be output). Defaults to `false`.
+ #
+ # TODO ignore_failure and retries seem to be mutually exclusive; I doubt
+ # that was intended.
+ #
+ # @param arg [Boolean] Whether to ignore failures.
+ # @return Whether this resource will ignore failures.
+ #
+ def ignore_failure(arg=nil)
+ set_or_return(:ignore_failure, arg, kind_of: [ TrueClass, FalseClass ])
+ end
+ attr_writer :ignore_failure
+
+ #
+ # Equivalent to #ignore_failure.
+ #
+ def epic_fail(arg=nil)
+ ignore_failure(arg)
end
+ #
+ # Make this resource into an exact (shallow) copy of the other resource.
+ #
+ # @param resource [Chef::Resource] The resource to copy from.
+ #
+ def load_from(resource)
+ resource.instance_variables.each do |iv|
+ unless iv == :@source_line || iv == :@action || iv == :@not_if || iv == :@only_if
+ self.instance_variable_set(iv, resource.instance_variable_get(iv))
+ end
+ end
+ end
+
+ #
+ # Runs the given action on this resource, immediately.
+ #
+ # @param action The action to run (e.g. `:create`)
+ # @param notification_type The notification type that triggered this (if any)
+ # @param notifying_resource The resource that triggered this notification (if any)
+ #
+ # @raise Any error that occurs during the actual action.
+ #
+ def run_action(action, notification_type=nil, notifying_resource=nil)
+ # reset state in case of multiple actions on the same resource.
+ @elapsed_time = 0
+ start_time = Time.now
+ events.resource_action_start(self, action, notification_type, notifying_resource)
+ # Try to resolve lazy/forward references in notifications again to handle
+ # the case where the resource was defined lazily (ie. in a ruby_block)
+ resolve_notification_references
+ validate_action(action)
+
+ if Chef::Config[:verbose_logging] || Chef::Log.level == :debug
+ # This can be noisy
+ Chef::Log.info("Processing #{self} action #{action} (#{defined_at})")
+ end
+
+ # ensure that we don't leave @updated_by_last_action set to true
+ # on accident
+ updated_by_last_action(false)
+
+ # Don't modify @retries directly and keep it intact, so that the
+ # recipe_snippet from ResourceFailureInspector can print the value
+ # that was set in the resource block initially.
+ remaining_retries = retries
+
+ begin
+ return if should_skip?(action)
+ provider_for_action(action).run_action
+ rescue Exception => e
+ if ignore_failure
+ Chef::Log.error("#{custom_exception_message(e)}; ignore_failure is set, continuing")
+ events.resource_failed(self, action, e)
+ elsif remaining_retries > 0
+ events.resource_failed_retriable(self, action, remaining_retries, e)
+ remaining_retries -= 1
+ Chef::Log.info("Retrying execution of #{self}, #{remaining_retries} attempt(s) left")
+ sleep retry_delay
+ retry
+ else
+ events.resource_failed(self, action, e)
+ raise customize_exception(e)
+ end
+ ensure
+ @elapsed_time = Time.now - start_time
+ # Reporting endpoint doesn't accept a negative resource duration so set it to 0.
+ # A negative value can occur when a resource changes the system time backwards
+ @elapsed_time = 0 if @elapsed_time < 0
+ events.resource_completed(self)
+ end
+ end
+
+ #
+ # Generic Ruby and Data Structure Stuff (for user)
+ #
+
def to_s
"#{@resource_name}[#{@name}]"
end
@@ -486,46 +645,340 @@ class Chef
instance_vars
end
- # If command is a block, returns true if the block returns true, false if it returns false.
- # ("Only run this resource if the block is true")
+ def self.json_create(o)
+ resource = self.new(o["instance_vars"]["@name"])
+ o["instance_vars"].each do |k,v|
+ resource.instance_variable_set("@#{k}".to_sym, v)
+ end
+ resource
+ end
+
#
- # If the command is not a block, executes the command. If it returns any status other than
- # 0, it returns false (clearly, a 0 status code is true)
+ # Resource Definition Interface (for resource developers)
#
- # === Parameters
- # command<String>:: A a string to execute.
- # opts<Hash>:: Options control the execution of the command
- # block<Proc>:: A ruby block to run. Ignored if a command is given.
+
+ include Chef::Mixin::ParamsValidate
+ include Chef::Mixin::Deprecation
+
#
- # === Evaluation
- # * evaluates to true if the block is true, or if the command returns 0
- # * evaluates to false if the block is false, or if the command returns a non-zero exit code.
- def only_if(command=nil, opts={}, &block)
- if command || block_given?
- @only_if << Conditional.only_if(self, command, opts, &block)
+ # The provider class for this resource.
+ #
+ # If this is not set, `provider_for_action` will dynamically determine the
+ # provider.
+ #
+ # @param arg [String, Symbol, Class] Sets the provider class for this resource.
+ # If passed a String or Symbol, e.g. `:file` or `"file"`, looks up the
+ # provider based on the name.
+ # @return The provider class for this resource.
+ #
+ def provider(arg=nil)
+ klass = if arg.kind_of?(String) || arg.kind_of?(Symbol)
+ lookup_provider_constant(arg)
+ else
+ arg
end
- @only_if
+ set_or_return(:provider, klass, kind_of: [ Class ])
+ end
+ def provider=(arg)
+ provider(arg)
end
- # If command is a block, returns false if the block returns true, true if it returns false.
- # ("Do not run this resource if the block is true")
+ # Set or return the list of "state attributes" implemented by the Resource
+ # subclass. State attributes are attributes that describe the desired state
+ # of the system, such as file permissions or ownership. In general, state
+ # attributes are attributes that could be populated by examining the state
+ # of the system (e.g., File.stat can tell you the permissions on an
+ # existing file). Contrarily, attributes that are not "state attributes"
+ # usually modify the way Chef itself behaves, for example by providing
+ # additional options for a package manager to use when installing a
+ # package.
#
- # If the command is not a block, executes the command. If it returns a 0 exitstatus, returns false.
- # ("Do not run this resource if the command returns 0")
+ # This list is used by the Chef client auditing system to extract
+ # information from resources to describe changes made to the system.
+ def self.state_attrs(*attr_names)
+ @state_attrs ||= []
+ @state_attrs = attr_names unless attr_names.empty?
+
+ # Return *all* state_attrs that this class has, including inherited ones
+ if superclass.respond_to?(:state_attrs)
+ superclass.state_attrs + @state_attrs
+ else
+ @state_attrs
+ end
+ end
+
+ # Set or return the "identity attribute" for this resource class. This is
+ # generally going to be the "name attribute" for this resource. In other
+ # words, the resource type plus this attribute uniquely identify a given
+ # bit of state that chef manages. For a File resource, this would be the
+ # path, for a package resource, it will be the package name. This will show
+ # up in chef-client's audit records as a searchable field.
+ def self.identity_attr(attr_name=nil)
+ @identity_attr ||= nil
+ @identity_attr = attr_name if attr_name
+
+ # If this class doesn't have an identity attr, we'll defer to the superclass:
+ if @identity_attr || !superclass.respond_to?(:identity_attr)
+ @identity_attr
+ else
+ superclass.identity_attr
+ end
+ end
+
#
- # === Parameters
- # command<String>:: A a string to execute.
- # opts<Hash>:: Options control the execution of the command
- # block<Proc>:: A ruby block to run. Ignored if a command is given.
+ # The guard interpreter that will be used to process `only_if` and `not_if`
+ # statements by default. If left unset, or set to `:default`, the guard
+ # interpreter used will be Chef::GuardInterpreter::DefaultGuardInterpreter.
#
- # === Evaluation
- # * evaluates to true if the block is false, or if the command returns a non-zero exit status.
- # * evaluates to false if the block is true, or if the command returns a 0 exit status.
- def not_if(command=nil, opts={}, &block)
- if command || block_given?
- @not_if << Conditional.not_if(self, command, opts, &block)
+ # Must be a resource class like `Chef::Resource::Execute`, or
+ # a corresponding to the name of a resource. The resource must descend from
+ # `Chef::Resource::Execute`.
+ #
+ # TODO this needs to be coerced on input so that retrieval is consistent.
+ #
+ # @return [Class, Symbol, String] the default Guard interpreter resource.
+ #
+ attr_reader :default_guard_interpreter
+
+ #
+ # The list of actions this Resource is allowed to have. Setting `action`
+ # will fail unless it is in this list. Default: [ :nothing ]
+ #
+ # @return [Array<Symbol>] The list of actions this Resource is allowed to
+ # have.
+ #
+ attr_accessor :allowed_actions
+
+ #
+ # Whether or not this resource was updated during an action. If multiple
+ # actions are set on the resource, this will be `true` if *any* action
+ # caused an update to happen.
+ #
+ # @return [Boolean] Whether the resource was updated during an action.
+ #
+ attr_reader :updated
+
+ #
+ # Whether or not this resource was updated during an action. If multiple
+ # actions are set on the resource, this will be `true` if *any* action
+ # caused an update to happen.
+ #
+ # @return [Boolean] Whether the resource was updated during an action.
+ #
+ def updated?
+ updated
+ end
+
+ #
+ # Whether or not this resource was updated during the most recent action.
+ # This is set to `false` at the beginning of each action.
+ #
+ # @param true_or_false [Boolean] Whether the resource was updated during the
+ # current / most recent action.
+ # @return [Boolean] Whether the resource was updated during the most recent action.
+ #
+ def updated_by_last_action(true_or_false)
+ @updated ||= true_or_false
+ @updated_by_last_action = true_or_false
+ end
+
+ #
+ # Whether or not this resource was updated during the most recent action.
+ # This is set to `false` at the beginning of each action.
+ #
+ # @return [Boolean] Whether the resource was updated during the most recent action.
+ #
+ def updated_by_last_action?
+ @updated_by_last_action
+ end
+
+ #
+ # Set whether this class was updated during an action.
+ #
+ # @deprecated Multiple actions are supported by resources. Please call {}#updated_by_last_action} instead.
+ #
+ def updated=(true_or_false)
+ Chef::Log.warn("Chef::Resource#updated=(true|false) is deprecated. Please call #updated_by_last_action(true|false) instead.")
+ Chef::Log.warn("Called from:")
+ caller[0..3].each {|line| Chef::Log.warn(line)}
+ updated_by_last_action(true_or_false)
+ @updated = true_or_false
+ end
+
+ #
+ # The DSL name of this resource (e.g. `package` or `yum_package`)
+ #
+ # @return [String] The DSL name of this resource.
+ def self.dsl_name
+ convert_to_snake_case(name, 'Chef::Resource')
+ end
+
+ #
+ # The name of this resource (e.g. `file`)
+ #
+ # @return [String] The name of this resource.
+ #
+ attr_reader :resource_name
+
+ #
+ # Sets a list of capabilities of the real resource. For example, `:remount`
+ # (for filesystems) and `:restart` (for services).
+ #
+ # TODO Calling resource.supports({}) will not set this to empty; it will do
+ # a get instead. That's wrong.
+ #
+ # @param args Hash{Symbol=>Boolean} If non-empty, sets the capabilities of
+ # this resource. Default: {}
+ # @return Hash{Symbol=>Boolean} An array of things this resource supports.
+ #
+ def supports(args={})
+ if args.any?
+ @supports = args
+ else
+ @supports
end
- @not_if
+ end
+ def supports=(args)
+ supports(args)
+ end
+
+ #
+ # A hook called after a resource is created. Meant to be overriden by
+ # subclasses.
+ #
+ def after_created
+ nil
+ end
+
+ #
+ # The module where Chef should look for providers for this resource.
+ # The provider for `MyResource` will be looked up using
+ # `provider_base::MyResource`. Defaults to `Chef::Provider`.
+ #
+ # @param arg [Module] The module containing providers for this resource
+ # @return [Module] The module containing providers for this resource
+ #
+ # @example
+ # class MyResource < Chef::Resource
+ # provider_base Chef::Provider::Deploy
+ # # ...other stuff
+ # end
+ #
+ def self.provider_base(arg=nil)
+ @provider_base ||= arg
+ @provider_base ||= Chef::Provider
+ end
+
+
+ #
+ # Internal Resource Interface (for Chef)
+ #
+
+ FORBIDDEN_IVARS = [:@run_context, :@not_if, :@only_if, :@enclosing_provider]
+ HIDDEN_IVARS = [:@allowed_actions, :@resource_name, :@source_line, :@run_context, :@name, :@not_if, :@only_if, :@elapsed_time, :@enclosing_provider]
+
+ include Chef::Mixin::ConvertToClassName
+ extend Chef::Mixin::ConvertToClassName
+ extend Chef::Mixin::DescendantsTracker
+
+ # XXX: this is required for definition params inside of the scope of a
+ # subresource to work correctly.
+ attr_accessor :params
+
+ # @return [Chef::RunContext] The run context for this Resource. This is
+ # where the context for the current Chef run is stored, including the node
+ # and the resource collection.
+ attr_accessor :run_context
+
+ # @return [String] The cookbook this resource was declared in.
+ attr_accessor :cookbook_name
+
+ # @return [String] The recipe this resource was declared in.
+ attr_accessor :recipe_name
+
+ # @return [Chef::Provider] The provider this resource was declared in (if
+ # it was declared in an LWRP). When you call methods that do not exist
+ # on this Resource, Chef will try to call the method on the provider
+ # as well before giving up.
+ attr_accessor :enclosing_provider
+
+ # @return [String] The source line where this resource was declared.
+ # Expected to come from caller() or a stack trace, it usually follows one
+ # of these formats:
+ # /some/path/to/file.rb:80:in `wombat_tears'
+ # C:/some/path/to/file.rb:80 in 1`wombat_tears'
+ attr_accessor :source_line
+
+ # @return [String] The actual name that was used to create this resource.
+ # Sometimes, when you say something like `package 'blah'`, the system will
+ # create a different resource (i.e. `YumPackage`). When this happens, the
+ # user will expect to see the thing they wrote, not the type that was
+ # returned. May be `nil`, in which case callers should read #resource_name.
+ # See #declared_key.
+ attr_accessor :declared_type
+
+ #
+ # Iterates over all immediate and delayed notifications, calling
+ # resolve_resource_reference on each in turn, causing them to
+ # resolve lazy/forward references.
+ def resolve_notification_references
+ run_context.immediate_notifications(self).each { |n|
+ n.resolve_resource_reference(run_context.resource_collection)
+ }
+ run_context.delayed_notifications(self).each {|n|
+ n.resolve_resource_reference(run_context.resource_collection)
+ }
+ end
+
+ # Helper for #notifies
+ def notifies_immediately(action, resource_spec)
+ run_context.notifies_immediately(Notification.new(resource_spec, action, self))
+ end
+
+ # Helper for #notifies
+ def notifies_delayed(action, resource_spec)
+ run_context.notifies_delayed(Notification.new(resource_spec, action, self))
+ end
+
+ class << self
+ # back-compat
+ # NOTE: that we do not support unregistering classes as descendents like
+ # we used to for LWRP unloading because that was horrible and removed in
+ # Chef-12.
+ alias :resource_classes :descendants
+ alias :find_subclass_by_name :find_descendants_by_name
+ end
+
+ # If an unknown method is invoked, determine whether the enclosing Provider's
+ # lexical scope can fulfill the request. E.g. This happens when the Resource's
+ # block invokes new_resource.
+ def method_missing(method_symbol, *args, &block)
+ if enclosing_provider && enclosing_provider.respond_to?(method_symbol)
+ enclosing_provider.send(method_symbol, *args, &block)
+ else
+ raise NoMethodError, "undefined method `#{method_symbol.to_s}' for #{self.class.to_s}"
+ end
+ end
+
+ # Helper for #notifies
+ def validate_resource_spec!(resource_spec)
+ run_context.resource_collection.validate_lookup_spec!(resource_spec)
+ end
+
+ # We usually want to store and reference resources by their declared type and not the actual type that
+ # was looked up by the Resolver (IE, "package" becomes YumPackage class). If we have not been provided
+ # the declared key we want to fall back on the old to_s key.
+ def declared_key
+ return to_s if declared_type.nil?
+ "#{declared_type}[#{@name}]"
+ end
+
+ def immediate_notifications
+ run_context.immediate_notifications(self)
+ end
+
+ def delayed_notifications
+ run_context.delayed_notifications(self)
end
def defined_at
@@ -543,6 +996,11 @@ class Chef
end
end
+ #
+ # The cookbook in which this Resource was defined (if any).
+ #
+ # @return Chef::CookbookVersion The cookbook in which this Resource was defined.
+ #
def cookbook_version
if cookbook_name
run_context.cookbook_collection[cookbook_name]
@@ -553,56 +1011,6 @@ class Chef
run_context.events
end
- def run_action(action, notification_type=nil, notifying_resource=nil)
- # reset state in case of multiple actions on the same resource.
- @elapsed_time = 0
- start_time = Time.now
- events.resource_action_start(self, action, notification_type, notifying_resource)
- # Try to resolve lazy/forward references in notifications again to handle
- # the case where the resource was defined lazily (ie. in a ruby_block)
- resolve_notification_references
- validate_action(action)
-
- if Chef::Config[:verbose_logging] || Chef::Log.level == :debug
- # This can be noisy
- Chef::Log.info("Processing #{self} action #{action} (#{defined_at})")
- end
-
- # ensure that we don't leave @updated_by_last_action set to true
- # on accident
- updated_by_last_action(false)
-
- # Don't modify @retries directly and keep it intact, so that the
- # recipe_snippet from ResourceFailureInspector can print the value
- # that was set in the resource block initially.
- remaining_retries = retries
-
- begin
- return if should_skip?(action)
- provider_for_action(action).run_action
- rescue Exception => e
- if ignore_failure
- Chef::Log.error("#{custom_exception_message(e)}; ignore_failure is set, continuing")
- events.resource_failed(self, action, e)
- elsif remaining_retries > 0
- events.resource_failed_retriable(self, action, remaining_retries, e)
- remaining_retries -= 1
- Chef::Log.info("Retrying execution of #{self}, #{remaining_retries} attempt(s) left")
- sleep retry_delay
- retry
- else
- events.resource_failed(self, action, e)
- raise customize_exception(e)
- end
- ensure
- @elapsed_time = Time.now - start_time
- # Reporting endpoint doesn't accept a negative resource duration so set it to 0.
- # A negative value can occur when a resource changes the system time backwards
- @elapsed_time = 0 if @elapsed_time < 0
- events.resource_completed(self)
- end
- end
-
def validate_action(action)
raise ArgumentError, "nil is not a valid action for resource #{self}" if action.nil?
end
@@ -613,6 +1021,30 @@ class Chef
provider
end
+ # ??? TODO Seems unused. Delete?
+ def noop(tf=nil)
+ if !tf.nil?
+ raise ArgumentError, "noop must be true or false!" unless tf == true || tf == false
+ @noop = tf
+ end
+ @noop
+ end
+
+ # TODO Seems unused. Delete?
+ def is(*args)
+ if args.size == 1
+ args.first
+ else
+ return *args
+ end
+ end
+
+ #
+ # Preface an exception message with generic Resource information.
+ #
+ # @param e [StandardError] An exception with `e.message`
+ # @return [String] An exception message customized with class name.
+ #
def custom_exception_message(e)
"#{self} (#{defined_at}) had an error: #{e.class.name}: #{e.message}"
end
@@ -622,6 +1054,7 @@ class Chef
new_exception.set_backtrace(e.backtrace)
new_exception
end
+
# Evaluates not_if and only_if conditionals. Returns a falsey value if any
# of the conditionals indicate that this resource should be skipped, i.e.,
# if an only_if evaluates to false or a not_if evaluates to true.
@@ -647,48 +1080,6 @@ class Chef
end
end
- def updated_by_last_action(true_or_false)
- @updated ||= true_or_false
- @updated_by_last_action = true_or_false
- end
-
- def updated_by_last_action?
- @updated_by_last_action
- end
-
- def updated?
- updated
- end
-
- def self.json_create(o)
- resource = self.new(o["instance_vars"]["@name"])
- o["instance_vars"].each do |k,v|
- resource.instance_variable_set("@#{k}".to_sym, v)
- end
- resource
- end
-
- # Hook to allow a resource to run specific code after creation
- def after_created
- nil
- end
-
- # Resources that want providers namespaced somewhere other than
- # Chef::Provider can set the namespace with +provider_base+
- # Ex:
- # class MyResource < Chef::Resource
- # provider_base Chef::Provider::Deploy
- # # ...other stuff
- # end
- def self.provider_base(arg=nil)
- @provider_base ||= arg
- @provider_base ||= Chef::Provider
- end
-
- def self.node_map
- @@node_map ||= NodeMap.new
- end
-
# Maps a short_name (and optionally a platform and version) to a
# Chef::Resource. This allows finer grained per platform resource
# attributes and the end of overloaded resource definitions
@@ -731,6 +1122,10 @@ class Chef
klass
end
+ def self.node_map
+ @@node_map ||= NodeMap.new
+ end
+
# Returns the class of a Chef::Resource based on the short name
# ==== Parameters
# short_name<Symbol>:: short_name of the resource (ie :directory)
diff --git a/lib/chef/resource/chef_gem.rb b/lib/chef/resource/chef_gem.rb
index b4ead11f1d..59f575a524 100644
--- a/lib/chef/resource/chef_gem.rb
+++ b/lib/chef/resource/chef_gem.rb
@@ -28,6 +28,7 @@ class Chef
def initialize(name, run_context=nil)
super
@resource_name = :chef_gem
+ @compile_time = Chef::Config[:chef_gem_compile_time]
@gem_binary = RbConfig::CONFIG['bindir'] + "/gem"
end
@@ -40,13 +41,29 @@ class Chef
@gem_binary
end
+ def compile_time(arg=nil)
+ set_or_return(
+ :compile_time,
+ arg,
+ :kind_of => [ TrueClass, FalseClass ]
+ )
+ end
+
def after_created
# Chef::Resource.run_action: Caveat: this skips Chef::Runner.run_action, where notifications are handled
# Action could be an array of symbols, but probably won't (think install + enable for a package)
- Array(@action).each do |action|
- self.run_action(action)
+ if compile_time.nil?
+ Chef::Log.deprecation "#{self} chef_gem compile_time installation is deprecated"
+ Chef::Log.deprecation "#{self} Please set `compile_time false` on the resource to use the new behavior."
+ Chef::Log.deprecation "#{self} or set `compile_time true` on the resource if compile_time behavior is required."
+ end
+
+ if compile_time || compile_time.nil?
+ Array(action).each do |action|
+ self.run_action(action)
+ end
+ Gem.clear_paths
end
- Gem.clear_paths
end
end
end
diff --git a/lib/chef/resource/conditional.rb b/lib/chef/resource/conditional.rb
index 8960a4d57f..35bdae8d69 100644
--- a/lib/chef/resource/conditional.rb
+++ b/lib/chef/resource/conditional.rb
@@ -17,7 +17,7 @@
#
require 'chef/mixin/shell_out'
-require 'chef/guard_interpreter/resource_guard_interpreter'
+require 'chef/guard_interpreter'
class Chef
class Resource
@@ -55,8 +55,8 @@ class Chef
def configure
case @command
- when String
- @guard_interpreter = new_guard_interpreter(@parent_resource, @command, @command_opts, &@block)
+ when String,Array
+ @guard_interpreter = Chef::GuardInterpreter.for_resource(@parent_resource, @command, @command_opts)
@block = nil
when nil
# We should have a block if we get here
@@ -122,17 +122,6 @@ class Chef
"#{@positivity} { #code block }"
end
end
-
- private
-
- def new_guard_interpreter(parent_resource, command, opts)
- if parent_resource.guard_interpreter == :default
- guard_interpreter = Chef::GuardInterpreter::DefaultGuardInterpreter.new(command, opts)
- else
- guard_interpreter = Chef::GuardInterpreter::ResourceGuardInterpreter.new(parent_resource, command, opts)
- end
- end
-
end
end
end
diff --git a/lib/chef/resource/dsc_script.rb b/lib/chef/resource/dsc_script.rb
index 82907c25db..cf96ef6b7f 100644
--- a/lib/chef/resource/dsc_script.rb
+++ b/lib/chef/resource/dsc_script.rb
@@ -29,6 +29,7 @@ class Chef
@allowed_actions.push(:run)
@action = :run
@resource_name = :dsc_script
+ @imports = {}
end
def code(arg=nil)
@@ -89,6 +90,19 @@ class Chef
)
end
+ def imports(module_name=nil, *args)
+ if module_name
+ @imports[module_name] ||= []
+ if args.length == 0
+ @imports[module_name] << '*'
+ else
+ @imports[module_name].push(*args)
+ end
+ else
+ @imports
+ end
+ end
+
def flags(arg=nil)
set_or_return(
:flags,
diff --git a/lib/chef/resource/execute.rb b/lib/chef/resource/execute.rb
index 4fbaaf93ab..9f8b629fb8 100644
--- a/lib/chef/resource/execute.rb
+++ b/lib/chef/resource/execute.rb
@@ -26,6 +26,12 @@ class Chef
identity_attr :command
+ # The ResourceGuardInterpreter wraps a resource's guards in another resource. That inner resource
+ # needs to behave differently during (for example) why_run mode, so we flag it here. For why_run mode
+ # we still want to execute the guard resource even if we are not executing the wrapping resource.
+ # Only execute resources (and subclasses) can be guard interpreters.
+ attr_accessor :is_guard_interpreter
+
def initialize(name, run_context=nil)
super
@resource_name = :execute
@@ -43,6 +49,7 @@ class Chef
@allowed_actions.push(:run)
@umask = nil
@default_guard_interpreter = :execute
+ @is_guard_interpreter = false
end
def umask(arg=nil)
@@ -117,7 +124,7 @@ class Chef
set_or_return(
:timeout,
arg,
- :kind_of => [ Integer ]
+ :kind_of => [ Integer, Float ]
)
end
@@ -146,12 +153,12 @@ class Chef
end
set_guard_inherited_attributes(
- :cwd,
- :environment,
- :group,
- :user,
- :umask
- )
+ :cwd,
+ :environment,
+ :group,
+ :user,
+ :umask
+ )
end
end
diff --git a/lib/chef/resource/file.rb b/lib/chef/resource/file.rb
index 16491f9bc8..53a6a160af 100644
--- a/lib/chef/resource/file.rb
+++ b/lib/chef/resource/file.rb
@@ -20,6 +20,7 @@
require 'chef/resource'
require 'chef/platform/query_helpers'
require 'chef/mixin/securable'
+require 'chef/resource/file/verification'
class Chef
class Resource
@@ -50,6 +51,7 @@ class Chef
@force_unlink = false
@manage_symlink_source = nil
@diff = nil
+ @verifications = []
end
def content(arg=nil)
@@ -115,6 +117,18 @@ class Chef
:kind_of => [ TrueClass, FalseClass ]
)
end
+
+ def verify(command=nil, opts={}, &block)
+ if ! (command.nil? || [String, Symbol].include?(command.class))
+ raise ArgumentError, "verify requires either a string, symbol, or a block"
+ end
+
+ if command || block_given?
+ @verifications << Verification.new(self, command, opts, &block)
+ else
+ @verifications
+ end
+ end
end
end
end
diff --git a/lib/chef/resource/file/verification.rb b/lib/chef/resource/file/verification.rb
new file mode 100644
index 0000000000..f1ca0f1883
--- /dev/null
+++ b/lib/chef/resource/file/verification.rb
@@ -0,0 +1,122 @@
+#
+# Author:: Steven Danna (<steve@chef.io>)
+# Copyright:: Copyright (c) 2014 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/exceptions'
+require 'chef/guard_interpreter'
+require 'chef/mixin/descendants_tracker'
+
+class Chef
+ class Resource
+ class File < Chef::Resource
+
+ #
+ # See RFC 027 for a full specification
+ #
+ # File verifications allow user-supplied commands a means of
+ # preventing file reosurce content deploys. Their intended use
+ # is to verify the contents of a temporary file before it is
+ # deployed onto the system.
+ #
+ # Similar to not_if and only_if, file verifications can take a
+ # ruby block, which will be called, or a string, which will be
+ # executed as a Shell command.
+ #
+ # Additonally, Chef or third-party verifications can ship
+ # "registered verifications" that the user can use by specifying
+ # a :symbol as the command name.
+ #
+ # To create a registered verification, create a class that
+ # inherits from Chef::Resource::File::Verification and use the
+ # provides class method to give it name. Registered
+ # verifications are expected to supply a verify instance method
+ # that takes 2 arguments.
+ #
+ # Example:
+ # class Chef
+ # class Resource
+ # class File::Verification::Foo < Chef::Resource::File::Verification
+ # provides :noop
+ # def verify(path, opts)
+ # #yolo
+ # true
+ # end
+ # end
+ # end
+ # end
+ #
+ #
+
+ class Verification
+ extend Chef::Mixin::DescendantsTracker
+
+ def self.provides(name)
+ @provides = name
+ end
+
+ def self.provides?(name)
+ @provides == name
+ end
+
+ def self.lookup(name)
+ c = descendants.find {|d| d.provides?(name) }
+ if c.nil?
+ raise Chef::Exceptions::VerificationNotFound.new "No file verification for #{name} found."
+ end
+ c
+ end
+
+ def initialize(parent_resource, command, opts, &block)
+ @command, @command_opts = command, opts
+ @block = block
+ @parent_resource = parent_resource
+ end
+
+ def verify(path, opts={})
+ Chef::Log.debug("Running verification[#{self}] on #{path}")
+ if @block
+ verify_block(path, opts)
+ elsif @command.is_a?(Symbol)
+ verify_registered_verification(path, opts)
+ elsif @command.is_a?(String)
+ verify_command(path, opts)
+ end
+ end
+
+ # opts is currently unused, but included in the API
+ # to support future extensions
+ def verify_block(path, opts)
+ @block.call(path)
+ end
+
+ # We reuse Chef::GuardInterpreter in order to support
+ # the same set of options that the not_if/only_if blocks do
+ def verify_command(path, opts)
+ command = @command % {:file => path}
+ interpreter = Chef::GuardInterpreter.for_resource(@parent_resource, command, @command_opts)
+ interpreter.evaluate
+ end
+
+ def verify_registered_verification(path, opts)
+ verification_class = Chef::Resource::File::Verification.lookup(@command)
+ v = verification_class.new(@parent_resource, @command, @command_opts, &@block)
+ v.verify(path, opts)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resource/ips_package.rb b/lib/chef/resource/ips_package.rb
index 77b3387946..c0e699e31a 100644
--- a/lib/chef/resource/ips_package.rb
+++ b/lib/chef/resource/ips_package.rb
@@ -28,7 +28,7 @@ class Chef
def initialize(name, run_context = nil)
super(name, run_context)
@resource_name = :ips_package
- @allowed_actions = [ :install, :remove, :upgrade ]
+ @allowed_actions.push(:install, :remove, :upgrade)
@accept_license = false
end
diff --git a/lib/chef/resource/lwrp_base.rb b/lib/chef/resource/lwrp_base.rb
index 20d177f507..ce72e98028 100644
--- a/lib/chef/resource/lwrp_base.rb
+++ b/lib/chef/resource/lwrp_base.rb
@@ -39,7 +39,7 @@ class Chef
rname = filename_to_qualified_string(cookbook_name, filename)
class_name = convert_to_class_name(rname)
- if Resource.strict_const_defined?(class_name)
+ if Resource.const_defined?(class_name, false)
Chef::Log.info("#{class_name} light-weight resource is already initialized -- Skipping loading #{filename}!")
Chef::Log.debug("Overriding already defined LWRPs is not supported anymore starting with Chef 12.")
resource_class = Resource.const_get(class_name)
@@ -73,16 +73,7 @@ class Chef
# Define an attribute on this resource, including optional validation
# parameters.
def self.attribute(attr_name, validation_opts={})
- # Ruby 1.8 doesn't support default arguments to blocks, but we have to
- # use define_method with a block to capture +validation_opts+.
- # Workaround this by defining two methods :(
- class_eval(<<-SHIM, __FILE__, __LINE__)
- def #{attr_name}(arg=nil)
- _set_or_return_#{attr_name}(arg)
- end
- SHIM
-
- define_method("_set_or_return_#{attr_name.to_s}".to_sym) do |arg|
+ define_method(attr_name) do |arg=nil|
set_or_return(attr_name.to_sym, arg, validation_opts)
end
end
diff --git a/lib/chef/resource/macports_package.rb b/lib/chef/resource/macports_package.rb
index bdc8698155..0d4e5dec65 100644
--- a/lib/chef/resource/macports_package.rb
+++ b/lib/chef/resource/macports_package.rb
@@ -20,7 +20,8 @@ class Chef
class Resource
class MacportsPackage < Chef::Resource::Package
- provides :macports_package, os: "mac_os_x"
+ provides :macports_package
+ provides :package, os: "darwin"
def initialize(name, run_context=nil)
super
diff --git a/lib/chef/resource/openbsd_package.rb b/lib/chef/resource/openbsd_package.rb
new file mode 100644
index 0000000000..20a2523e3a
--- /dev/null
+++ b/lib/chef/resource/openbsd_package.rb
@@ -0,0 +1,51 @@
+#
+# Authors:: AJ Christensen (<aj@opscode.com>)
+# Richard Manyanza (<liseki@nyikacraftsmen.com>)
+# Scott Bonds (<scott@ggr.com>)
+# Copyright:: Copyright (c) 2008 Opscode, Inc.
+# Copyright:: Copyright (c) 2014 Richard Manyanza, Scott Bonds
+# 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/package'
+require 'chef/provider/package/openbsd'
+require 'chef/mixin/shell_out'
+
+class Chef
+ class Resource
+ class OpenbsdPackage < Chef::Resource::Package
+ include Chef::Mixin::ShellOut
+
+ provides :package, os: "openbsd"
+
+ def initialize(name, run_context=nil)
+ super
+ @resource_name = :openbsd_package
+ end
+
+ def after_created
+ assign_provider
+ end
+
+ private
+
+ def assign_provider
+ @provider = Chef::Provider::Package::Openbsd
+ end
+
+ end
+ end
+end
+
diff --git a/lib/chef/resource/package.rb b/lib/chef/resource/package.rb
index 772439b06c..f4f49b543b 100644
--- a/lib/chef/resource/package.rb
+++ b/lib/chef/resource/package.rb
@@ -46,7 +46,7 @@ class Chef
set_or_return(
:package_name,
arg,
- :kind_of => [ String ]
+ :kind_of => [ String, Array ]
)
end
@@ -54,7 +54,7 @@ class Chef
set_or_return(
:version,
arg,
- :kind_of => [ String ]
+ :kind_of => [ String, Array ]
)
end
diff --git a/lib/chef/resource/paludis_package.rb b/lib/chef/resource/paludis_package.rb
index 7eddf8690b..552c96857a 100644
--- a/lib/chef/resource/paludis_package.rb
+++ b/lib/chef/resource/paludis_package.rb
@@ -28,7 +28,7 @@ class Chef
def initialize(name, run_context=nil)
super(name, run_context)
@resource_name = :paludis_package
- @allowed_actions = [ :install, :remove, :upgrade ]
+ @allowed_actions.push(:install, :remove, :upgrade)
@timeout = 3600
end
end
diff --git a/lib/chef/resource/reboot.rb b/lib/chef/resource/reboot.rb
index d6caafdea8..c111b23d2e 100644
--- a/lib/chef/resource/reboot.rb
+++ b/lib/chef/resource/reboot.rb
@@ -28,7 +28,7 @@ class Chef
super
@resource_name = :reboot
@provider = Chef::Provider::Reboot
- @allowed_actions = [:request_reboot, :reboot_now, :cancel]
+ @allowed_actions.push(:request_reboot, :reboot_now, :cancel)
@reason = "Reboot by Chef"
@delay_mins = 0
diff --git a/lib/chef/resource/remote_file.rb b/lib/chef/resource/remote_file.rb
index 46516fd3fb..7ba98b9d3b 100644
--- a/lib/chef/resource/remote_file.rb
+++ b/lib/chef/resource/remote_file.rb
@@ -17,6 +17,7 @@
# limitations under the License.
#
+require 'uri'
require 'chef/resource/file'
require 'chef/provider/remote_file'
require 'chef/mixin/securable'
diff --git a/lib/chef/resource/rpm_package.rb b/lib/chef/resource/rpm_package.rb
index 8634f1e25d..f00121dd69 100644
--- a/lib/chef/resource/rpm_package.rb
+++ b/lib/chef/resource/rpm_package.rb
@@ -28,6 +28,15 @@ class Chef
def initialize(name, run_context=nil)
super
@resource_name = :rpm_package
+ @allow_downgrade = false
+ end
+
+ def allow_downgrade(arg=nil)
+ set_or_return(
+ :allow_downgrade,
+ arg,
+ :kind_of => [ TrueClass, FalseClass ]
+ )
end
end
diff --git a/lib/chef/resource/script.rb b/lib/chef/resource/script.rb
index 479295922c..fd0fd5a7fd 100644
--- a/lib/chef/resource/script.rb
+++ b/lib/chef/resource/script.rb
@@ -24,11 +24,13 @@ class Chef
class Resource
class Script < Chef::Resource::Execute
+ # Chef-13: go back to using :name as the identity attr
identity_attr :command
def initialize(name, run_context=nil)
super
@resource_name = :script
+ # Chef-13: the command variable should be initialized to nil
@command = name
@code = nil
@interpreter = nil
@@ -36,6 +38,15 @@ class Chef
@default_guard_interpreter = :default
end
+ def command(arg=nil)
+ unless arg.nil?
+ # Chef-13: change this to raise if the user is trying to set a value here
+ Chef::Log.warn "Specifying command attribute on a script resource is a coding error, use the 'code' attribute, or the execute resource"
+ Chef::Log.warn "This attribute is deprecated and must be fixed or this code will fail on Chef-13"
+ end
+ super
+ end
+
def code(arg=nil)
set_or_return(
:code,
diff --git a/lib/chef/resource/template.rb b/lib/chef/resource/template.rb
index 8c9607ee07..67a9e6a418 100644
--- a/lib/chef/resource/template.rb
+++ b/lib/chef/resource/template.rb
@@ -102,9 +102,8 @@ class Chef
#
# ==== Method Arguments:
# Helper methods can also take arguments. The syntax available for
- # argument specification will be dependent on ruby version. Ruby 1.8 only
- # supports a subset of the argument specification syntax available for
- # method definition, whereas 1.9 supports the full syntax.
+ # argument specification supports full syntax available for method
+ # definition.
#
# Continuing the above example of simplifying attribute access, we can
# define a helper to look up app-specific attributes like this:
diff --git a/lib/chef/resource/windows_package.rb b/lib/chef/resource/windows_package.rb
index b1ef2c288e..16cfcf865e 100644
--- a/lib/chef/resource/windows_package.rb
+++ b/lib/chef/resource/windows_package.rb
@@ -29,7 +29,7 @@ class Chef
def initialize(name, run_context=nil)
super
- @allowed_actions = [ :install, :remove ]
+ @allowed_actions.push(:install, :remove)
@resource_name = :windows_package
@source ||= source(@package_name)
diff --git a/lib/chef/resource/windows_service.rb b/lib/chef/resource/windows_service.rb
index 2aec4d6304..8090adceb0 100644
--- a/lib/chef/resource/windows_service.rb
+++ b/lib/chef/resource/windows_service.rb
@@ -37,6 +37,8 @@ class Chef
@resource_name = :windows_service
@allowed_actions.push(:configure_startup)
@startup_type = :automatic
+ @run_as_user = ""
+ @run_as_password = ""
end
def startup_type(arg=nil)
@@ -48,6 +50,22 @@ class Chef
:equal_to => [ :automatic, :manual, :disabled ]
)
end
+
+ def run_as_user(arg=nil)
+ set_or_return(
+ :run_as_user,
+ arg,
+ :kind_of => [ String ]
+ )
+ end
+
+ def run_as_password(arg=nil)
+ set_or_return(
+ :run_as_password,
+ arg,
+ :kind_of => [ String ]
+ )
+ end
end
end
end
diff --git a/lib/chef/resource_builder.rb b/lib/chef/resource_builder.rb
new file mode 100644
index 0000000000..bb0962d128
--- /dev/null
+++ b/lib/chef/resource_builder.rb
@@ -0,0 +1,137 @@
+#
+# Author:: Lamont Granquist (<lamont@chef.io>)
+# Copyright:: Copyright (c) 2015 Opscode, 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.
+#
+
+# NOTE: this was extracted from the Recipe DSL mixin, relevant specs are in spec/unit/recipe_spec.rb
+
+class Chef
+ class ResourceBuilder
+ attr_reader :type
+ attr_reader :name
+ attr_reader :created_at
+ attr_reader :params
+ attr_reader :run_context
+ attr_reader :cookbook_name
+ attr_reader :recipe_name
+ attr_reader :enclosing_provider
+ 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)
+ @type = type
+ @name = name
+ @created_at = created_at
+ @params = params
+ @run_context = run_context
+ @cookbook_name = cookbook_name
+ @recipe_name = recipe_name
+ @enclosing_provider = enclosing_provider
+ end
+
+ def build(&block)
+ raise ArgumentError, "You must supply a name when declaring a #{type} resource" if name.nil?
+
+ @resource = resource_class.new(name, run_context)
+ resource.source_line = created_at
+ resource.declared_type = type
+
+ # If we have a resource like this one, we want to steal its state
+ # This behavior is very counter-intuitive and should be removed.
+ # See CHEF-3694, https://tickets.opscode.com/browse/CHEF-3694
+ # Moved to this location to resolve CHEF-5052, https://tickets.opscode.com/browse/CHEF-5052
+ if prior_resource
+ resource.load_from(prior_resource)
+ end
+
+ resource.cookbook_name = cookbook_name
+ resource.recipe_name = recipe_name
+ # Determine whether this resource is being created in the context of an enclosing Provider
+ resource.enclosing_provider = enclosing_provider
+
+ # XXX: this is required for definition params inside of the scope of a
+ # subresource to work correctly.
+ resource.params = params
+
+ # Evaluate resource attribute DSL
+ resource.instance_eval(&block) if block_given?
+
+ # emit a cloned resource warning if it is warranted
+ if prior_resource
+ if is_trivial_resource?(prior_resource) && identicalish_resources?(prior_resource, resource)
+ emit_harmless_cloning_debug
+ else
+ emit_cloned_resource_warning
+ end
+ end
+
+ # Run optional resource hook
+ resource.after_created
+
+ resource
+ end
+
+ private
+
+ def resource_class
+ # Checks the new platform => short_name => resource mapping initially
+ # then fall back to the older approach (Chef::Resource.const_get) for
+ # backward compatibility
+ @resource_class ||= Chef::Resource.resource_for_node(type, run_context.node)
+ end
+
+ def is_trivial_resource?(resource)
+ identicalish_resources?(resource_class.new(name, run_context), resource)
+ end
+
+ # this is an equality test specific to checking for 3694 cloning warnings
+ def identicalish_resources?(first, second)
+ skipped_ivars = [ :@source_line, :@cookbook_name, :@recipe_name, :@params, :@elapsed_time, :@declared_type ]
+ checked_ivars = ( first.instance_variables | second.instance_variables ) - skipped_ivars
+ non_matching_ivars = checked_ivars.reject do |iv|
+ if iv == :@action && ( [first.instance_variable_get(iv)].flatten == [:nothing] || [second.instance_variable_get(iv)].flatten == [:nothing] )
+ # :nothing action on either side of the comparison always matches
+ true
+ else
+ first.instance_variable_get(iv) == second.instance_variable_get(iv)
+ end
+ end
+ Chef::Log.debug("ivars which did not match with the prior resource: #{non_matching_ivars}")
+ non_matching_ivars.empty?
+ end
+
+ def emit_cloned_resource_warning
+ Chef::Log.warn("Cloning resource attributes for #{resource} from prior resource (CHEF-3694)")
+ Chef::Log.warn("Previous #{prior_resource}: #{prior_resource.source_line}") if prior_resource.source_line
+ Chef::Log.warn("Current #{resource}: #{resource.source_line}") if resource.source_line
+ end
+
+ def emit_harmless_cloning_debug
+ Chef::Log.debug("Harmless resource cloning from #{prior_resource}:#{prior_resource.source_line} to #{resource}:#{resource.source_line}")
+ end
+
+ def prior_resource
+ @prior_resource ||=
+ begin
+ key = "#{type}[#{name}]"
+ prior_resource = run_context.resource_collection.lookup(key)
+ rescue Chef::Exceptions::ResourceNotFound
+ nil
+ end
+ end
+
+ end
+end
diff --git a/lib/chef/resource_definition.rb b/lib/chef/resource_definition.rb
index 278114e209..9d6844129c 100644
--- a/lib/chef/resource_definition.rb
+++ b/lib/chef/resource_definition.rb
@@ -54,7 +54,7 @@ class Chef
end
# When we do the resource definition, we're really just setting new values for
- # the paramaters we prototyped at the top. This method missing is as simple as
+ # the parameters we prototyped at the top. This method missing is as simple as
# it gets.
def method_missing(symbol, *args)
@params[symbol] = args.length == 1 ? args[0] : args
diff --git a/lib/chef/resource_reporter.rb b/lib/chef/resource_reporter.rb
index a19f26125e..1816fc857d 100644
--- a/lib/chef/resource_reporter.rb
+++ b/lib/chef/resource_reporter.rb
@@ -20,7 +20,7 @@
#
require 'uri'
-require 'chef/monkey_patches/securerandom'
+require 'securerandom'
require 'chef/event_dispatch/base'
class Chef
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index 696dbbdc55..680b393741 100644
--- a/lib/chef/resources.rb
+++ b/lib/chef/resources.rb
@@ -48,6 +48,7 @@ require 'chef/resource/macports_package'
require 'chef/resource/mdadm'
require 'chef/resource/mount'
require 'chef/resource/ohai'
+require 'chef/resource/openbsd_package'
require 'chef/resource/package'
require 'chef/resource/pacman_package'
require 'chef/resource/paludis_package'
diff --git a/lib/chef/role.rb b/lib/chef/role.rb
index 4b4669f4b5..c085d1d714 100644
--- a/lib/chef/role.rb
+++ b/lib/chef/role.rb
@@ -32,17 +32,20 @@ class Chef
include Chef::Mixin::FromFile
include Chef::Mixin::ParamsValidate
+ attr_accessor :chef_server_rest
+
# Create a new Chef::Role object.
- def initialize
+ def initialize(chef_server_rest: nil)
@name = ''
@description = ''
@default_attributes = Mash.new
@override_attributes = Mash.new
@env_run_lists = {"_default" => Chef::RunList.new}
+ @chef_server_rest = chef_server_rest
end
def chef_server_rest
- Chef::REST.new(Chef::Config[:chef_server_url])
+ @chef_server_rest ||= Chef::REST.new(Chef::Config[:chef_server_url])
end
def self.chef_server_rest
@@ -103,6 +106,16 @@ class Chef
alias :env_run_list :env_run_lists
+ def env_run_lists_add(env_run_lists=nil)
+ if (!env_run_lists.nil?)
+ env_run_lists.each { |k,v| @env_run_lists[k] = Chef::RunList.new(*Array(v))}
+ end
+ @env_run_lists
+ end
+
+ alias :env_run_list_add :env_run_lists_add
+
+
def default_attributes(arg=nil)
set_or_return(
:default_attributes,
@@ -236,8 +249,8 @@ class Chef
paths = Array(Chef::Config[:role_path])
paths.each do |path|
roles_files = Dir.glob(File.join(Chef::Util::PathHelper.escape_glob(path), "**", "**"))
- js_files = roles_files.select { |file| file.match /\/#{name}\.json$/ }
- rb_files = roles_files.select { |file| file.match /\/#{name}\.rb$/ }
+ js_files = roles_files.select { |file| file.match(/\/#{name}\.json$/) }
+ rb_files = roles_files.select { |file| file.match(/\/#{name}\.rb$/) }
if js_files.count > 1 or rb_files.count > 1
raise Chef::Exceptions::DuplicateRole, "Multiple roles of same type found named #{name}"
end
diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb
index 22679822a4..fc54506407 100644
--- a/lib/chef/run_context.rb
+++ b/lib/chef/run_context.rb
@@ -50,6 +50,9 @@ class Chef
# recipes, which is triggered by #load. (See also: CookbookCompiler)
attr_accessor :resource_collection
+ # The list of audits (control groups) to execute during the audit phase
+ attr_accessor :audits
+
# A Hash containing the immediate notifications triggered by resources
# during the converge phase of the chef run.
attr_accessor :immediate_notification_collection
@@ -73,6 +76,7 @@ class Chef
@node = node
@cookbook_collection = cookbook_collection
@resource_collection = Chef::ResourceCollection.new
+ @audits = {}
@immediate_notification_collection = Hash.new {|h,k| h[k] = []}
@delayed_notification_collection = Hash.new {|h,k| h[k] = []}
@definitions = Hash.new
@@ -132,10 +136,10 @@ class Chef
end
# Evaluates the recipes +recipe_names+. Used by DSL::IncludeRecipe
- def include_recipe(*recipe_names)
+ def include_recipe(*recipe_names, current_cookbook: nil)
result_recipes = Array.new
recipe_names.flatten.each do |recipe_name|
- if result = load_recipe(recipe_name)
+ if result = load_recipe(recipe_name, current_cookbook: current_cookbook)
result_recipes << result
end
end
@@ -143,10 +147,10 @@ class Chef
end
# Evaluates the recipe +recipe_name+. Used by DSL::IncludeRecipe
- def load_recipe(recipe_name)
+ def load_recipe(recipe_name, current_cookbook: nil)
Chef::Log.debug("Loading Recipe #{recipe_name} via include_recipe")
- cookbook_name, recipe_short_name = Chef::Recipe.parse_recipe_name(recipe_name)
+ cookbook_name, recipe_short_name = Chef::Recipe.parse_recipe_name(recipe_name, current_cookbook: current_cookbook)
if unreachable_cookbook?(cookbook_name) # CHEF-4367
Chef::Log.warn(<<-ERROR_MESSAGE)
@@ -194,7 +198,7 @@ ERROR_MESSAGE
end
# An Array of all recipes that have been loaded. This is stored internally
- # as a Hash, so ordering is not preserved when using ruby 1.8.
+ # as a Hash, so ordering is predictable.
#
# Recipe names are given in fully qualified form, e.g., the recipe "nginx"
# will be given as "nginx::default"
@@ -205,7 +209,7 @@ ERROR_MESSAGE
end
# An Array of all attributes files that have been loaded. Stored internally
- # using a Hash, so order is not preserved on ruby 1.8.
+ # using a Hash, so order is predictable.
#
# Attribute file names are given in fully qualified form, e.g.,
# "nginx::default" instead of "nginx".
diff --git a/lib/chef/search/query.rb b/lib/chef/search/query.rb
index cc43efe1b1..8656e810db 100644
--- a/lib/chef/search/query.rb
+++ b/lib/chef/search/query.rb
@@ -17,52 +17,47 @@
#
require 'chef/config'
-require 'uri'
-require 'chef/rest'
-require 'chef/node'
-require 'chef/role'
-require 'chef/data_bag'
-require 'chef/data_bag_item'
require 'chef/exceptions'
+require 'chef/rest'
+
+require 'uri'
class Chef
class Search
class Query
attr_accessor :rest
+ attr_reader :config
- def initialize(url=nil)
- @rest = Chef::REST.new(url ||Chef::Config[:chef_server_url])
+ def initialize(url=nil, config:Chef::Config)
+ @config = config
+ @url = url
end
+ def rest
+ @rest ||= Chef::REST.new(@url || @config[:chef_server_url])
+ end
- # This search is only kept for backwards compatibility, since the results of the
- # new filtered search method will be in a slightly different format
+ # Backwards compatability for cookbooks.
+ # This can be removed in Chef > 12.
def partial_search(type, query='*:*', *args, &block)
- Chef::Log.warn("DEPRECATED: The 'partial_search' api is deprecated, please use the search api with 'filter_result'")
- # accept both types of args
- if args.length == 1 && args[0].is_a?(Hash)
- args_hash = args[0].dup
- # partial_search implemented in the partial search cookbook uses the
- # arg hash :keys instead of :filter_result to filter returned data
- args_hash[:filter_result] = args_hash[:keys]
+ Chef::Log.warn(<<-WARNDEP)
+DEPRECATED: The 'partial_search' API is deprecated and will be removed in
+future releases. Please use 'search' with a :filter_result argument to get
+partial search data.
+WARNDEP
+
+ if !args.empty? && args.first.is_a?(Hash)
+ # partial_search uses :keys instead of :filter_result for
+ # result filtering.
+ args_h = args.first.dup
+ args_h[:filter_result] = args_h[:keys]
+ args_h.delete(:keys)
+
+ search(type, query, args_h, &block)
else
- args_hash = {}
- args_hash[:sort] = args[0] if args.length >= 1
- args_hash[:start] = args[1] if args.length >= 2
- args_hash[:rows] = args[2] if args.length >= 3
+ search(type, query, *args, &block)
end
-
- unless block.nil?
- raw_results = search(type,query,args_hash)
- else
- raw_results = search(type,query,args_hash,&block)
- end
- results = Array.new
- raw_results[0].each do |r|
- results << r["data"]
- end
- return results
end
#
@@ -87,87 +82,71 @@ class Chef
#
def search(type, query='*:*', *args, &block)
validate_type(type)
- validate_args(args)
- scrubbed_args = Hash.new
+ args_h = hashify_args(*args)
+ response = call_rest_service(type, query: query, **args_h)
- # argify everything
- if args[0].kind_of?(Hash)
- scrubbed_args = args[0]
+ if block
+ response["rows"].each { |row| block.call(row) if row }
+ unless (response["start"] + response["rows"].length) >= response["total"]
+ args_h[:start] = response["start"] + (args_h[:rows] || 0)
+ search(type, query, args_h, &block)
+ end
+ true
else
- # This api will be deprecated in a future release
- scrubbed_args = { :sort => args[0], :start => args[1], :rows => args[2] }
+ [ response["rows"], response["start"], response["total"] ]
end
-
- # set defaults, if they haven't been set yet.
- scrubbed_args[:sort] ||= 'X_CHEF_id_CHEF_X asc'
- scrubbed_args[:start] ||= 0
- scrubbed_args[:rows] ||= 1000
-
- do_search(type, query, scrubbed_args, &block)
- end
-
- def list_indexes
- @rest.get_rest("search")
end
private
def validate_type(t)
unless t.kind_of?(String) || t.kind_of?(Symbol)
msg = "Invalid search object type #{t.inspect} (#{t.class}), must be a String or Symbol." +
- "Useage: search(:node, QUERY, [OPTIONAL_ARGS])" +
- " `knife search environment QUERY (options)`"
+ "Usage: search(:node, QUERY[, OPTIONAL_ARGS])" +
+ " `knife search environment QUERY (options)`"
raise Chef::Exceptions::InvalidSearchQuery, msg
end
end
- def validate_args(a)
- max_args = 3
- raise Chef::Exceptions::InvalidSearchQuery, "Too many arguments! (#{a.size} for <= #{max_args})" if a.size > max_args
+ def hashify_args(*args)
+ return Hash.new if args.empty?
+ return args.first if args.first.is_a?(Hash)
+
+ args_h = Hash.new
+ args_h[:sort] = args[0] if args[0]
+ args_h[:start] = args[1] if args[1]
+ args_h[:rows] = args[2]
+ args_h[:filter_result] = args[3]
+ args_h
end
def escape(s)
s && URI.escape(s.to_s)
end
- # new search api that allows for a cleaner implementation of things like return filters
- # (formerly known as 'partial search').
- # Also args should never be nil, but that is required for Ruby 1.8 compatibility
- def do_search(type, query="*:*", args=nil, &block)
- query_string = create_query_string(type, query, args)
- response = call_rest_service(query_string, args)
- unless block.nil?
- response["rows"].each { |rowset| block.call(rowset) unless rowset.nil?}
- unless (response["start"] + response["rows"].length) >= response["total"]
- args[:start] = response["start"] + args[:rows]
- do_search(type, query, args, &block)
- end
- true
- else
- [ response["rows"], response["start"], response["total"] ]
- 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
end
- # create the full rest url string
- def create_query_string(type, query, args)
- # create some default variables just so we don't break backwards compatibility
- sort = args[:sort]
- start = args[:start]
- rows = args[:rows]
+ 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)
- return "search/#{type}?q=#{escape(query)}&sort=#{escape(sort)}&start=#{escape(start)}&rows=#{escape(rows)}"
- end
-
- def call_rest_service(query_string, args)
- if args.key?(:filter_result)
- response = @rest.post_rest(query_string, args[:filter_result])
- response_rows = response['rows'].map { |row| row['data'] }
+ if filter_result
+ response = rest.post_rest(query_string, filter_result)
+ # response returns rows in the format of
+ # { "url" => url_to_node, "data" => filter_result_hash }
+ response['rows'].map! { |row| row['data'] }
else
- response = @rest.get_rest(query_string)
- response_rows = response['rows']
+ response = rest.get_rest(query_string)
end
- return response
+
+ response
end
+
end
end
end
diff --git a/lib/chef/shell/ext.rb b/lib/chef/shell/ext.rb
index fd785e2f79..d516524765 100644
--- a/lib/chef/shell/ext.rb
+++ b/lib/chef/shell/ext.rb
@@ -211,8 +211,8 @@ E
def version
puts "This is the chef-shell.\n" +
" Chef Version: #{::Chef::VERSION}\n" +
- " http://www.opscode.com/chef\n" +
- " http://docs.opscode.com/"
+ " http://www.chef.io/\n" +
+ " http://docs.chef.io/"
:ucanhaz_automation
end
alias :shell :version
diff --git a/lib/chef/util/diff.rb b/lib/chef/util/diff.rb
index 3117484a71..c2dc6e045c 100644
--- a/lib/chef/util/diff.rb
+++ b/lib/chef/util/diff.rb
@@ -176,10 +176,7 @@ class Chef
end
def encode_diff_for_json(diff_str)
- if Object.const_defined? :Encoding
- diff_str.encode!('UTF-8', :invalid => :replace, :undef => :replace, :replace => '?')
- end
- return diff_str
+ diff_str.encode!('UTF-8', :invalid => :replace, :undef => :replace, :replace => '?')
end
end
diff --git a/lib/chef/util/dsc/configuration_generator.rb b/lib/chef/util/dsc/configuration_generator.rb
index 12cd5dc3a2..0d7296eae9 100644
--- a/lib/chef/util/dsc/configuration_generator.rb
+++ b/lib/chef/util/dsc/configuration_generator.rb
@@ -25,9 +25,9 @@ class Chef::Util::DSC
@config_directory = config_directory
end
- def configuration_document_from_script_code(code, configuration_flags, shellout_flags)
+ def configuration_document_from_script_code(code, configuration_flags, imports, shellout_flags)
Chef::Log.debug("DSC: DSC code:\n '#{code}'")
- generated_script_path = write_document_generation_script(code, 'chef_dsc')
+ generated_script_path = write_document_generation_script(code, 'chef_dsc', imports)
begin
configuration_document_from_script_path(generated_script_path, 'chef_dsc', configuration_flags, shellout_flags)
ensure
@@ -80,18 +80,42 @@ class Chef::Util::DSC
merged_configuration_flags
end
- def configuration_code(code, configuration_name)
- "$ProgressPreference = 'SilentlyContinue';Configuration '#{configuration_name}'\n{\n\tnode 'localhost'\n{\n\t#{code}\n}}\n"
+ def configuration_code(code, configuration_name, imports)
+ <<-EOF
+$ProgressPreference = 'SilentlyContinue';
+Configuration '#{configuration_name}'
+{
+ #{generate_import_resource_statements(imports).join(" \n")}
+ node 'localhost'
+ {
+ #{code}
+ }
+}
+ EOF
+ end
+
+ def generate_import_resource_statements(imports)
+ if imports
+ imports.map do |resource_module, resources|
+ if resources.length == 0 || resources.include?('*')
+ "Import-DscResource -ModuleName #{resource_module}"
+ else
+ "Import-DscResource -ModuleName #{resource_module} -Name #{resources.join(',')}"
+ end
+ end
+ else
+ []
+ end
end
def configuration_document_generation_code(configuration_script, configuration_name)
". '#{configuration_script}';#{configuration_name}"
end
- def write_document_generation_script(code, configuration_name)
+ def write_document_generation_script(code, configuration_name, imports)
script_path = "#{@config_directory}/chef_dsc_config.ps1"
::File.open(script_path, 'wt') do | script |
- script.write(configuration_code(code, configuration_name))
+ script.write(configuration_code(code, configuration_name, imports))
end
script_path
end
diff --git a/lib/chef/util/dsc/lcm_output_parser.rb b/lib/chef/util/dsc/lcm_output_parser.rb
index f8f853a33a..754fde3e8b 100644
--- a/lib/chef/util/dsc/lcm_output_parser.rb
+++ b/lib/chef/util/dsc/lcm_output_parser.rb
@@ -18,6 +18,7 @@
require 'chef/log'
require 'chef/util/dsc/resource_info'
+require 'chef/exceptions'
class Chef
class Util
@@ -53,8 +54,7 @@ class Chef
# ]
#
def self.parse(lcm_output)
- return [] unless lcm_output
-
+ lcm_output ||= ""
current_resource = Hash.new
resources = []
@@ -96,7 +96,11 @@ class Chef
resources.push(current_resource)
end
- build_resource_info(resources)
+ if resources.length > 0
+ build_resource_info(resources)
+ else
+ raise Chef::Exceptions::LCMParser, "Could not parse:\n#{lcm_output}"
+ end
end
def self.parse_line(line)
diff --git a/lib/chef/util/dsc/local_configuration_manager.rb b/lib/chef/util/dsc/local_configuration_manager.rb
index f498a2bfea..f8398341e5 100644
--- a/lib/chef/util/dsc/local_configuration_manager.rb
+++ b/lib/chef/util/dsc/local_configuration_manager.rb
@@ -27,14 +27,14 @@ class Chef::Util::DSC
clear_execution_time
end
- def test_configuration(configuration_document)
- status = run_configuration_cmdlet(configuration_document)
+ def test_configuration(configuration_document, shellout_flags)
+ status = run_configuration_cmdlet(configuration_document, false, shellout_flags)
log_what_if_exception(status.stderr) unless status.succeeded?
configuration_update_required?(status.return_value)
end
- def set_configuration(configuration_document)
- run_configuration_cmdlet(configuration_document, true)
+ def set_configuration(configuration_document, shellout_flags)
+ run_configuration_cmdlet(configuration_document, true, shellout_flags)
end
def last_operation_execution_time_seconds
@@ -45,7 +45,7 @@ class Chef::Util::DSC
private
- def run_configuration_cmdlet(configuration_document, apply_configuration = false)
+ def run_configuration_cmdlet(configuration_document, apply_configuration, shellout_flags)
Chef::Log.debug("DSC: Calling DSC Local Config Manager to #{apply_configuration ? "set" : "test"} configuration document.")
test_only_parameters = ! apply_configuration ? '-whatif; if (! $?) { exit 1 }' : ''
@@ -57,9 +57,9 @@ class Chef::Util::DSC
save_configuration_document(configuration_document)
cmdlet = ::Chef::Util::Powershell::Cmdlet.new(@node, "#{command_code}")
if apply_configuration
- status = cmdlet.run!
+ status = cmdlet.run!({}, shellout_flags)
else
- status = cmdlet.run
+ status = cmdlet.run({}, shellout_flags)
end
ensure
end_operation_timing
@@ -103,7 +103,7 @@ EOH
Chef::Log.debug("DSC: DSC returned the following '-whatif' output from test operation:\n#{what_if_output}")
begin
Parser::parse(what_if_output)
- rescue Chef::Util::DSC::LocalConfigurationManager::Parser => e
+ rescue Chef::Exceptions::LCMParser => e
Chef::Log::warn("Could not parse LCM output: #{e}")
[Chef::Util::DSC::ResourceInfo.new('Unknown DSC Resources', true, ['Unknown changes because LCM output was not parsable.'])]
end
diff --git a/lib/chef/util/file_edit.rb b/lib/chef/util/file_edit.rb
index 92cefb4bb4..4d2a9c03eb 100644
--- a/lib/chef/util/file_edit.rb
+++ b/lib/chef/util/file_edit.rb
@@ -47,7 +47,7 @@ class Chef
end
#search the file line by line and match each line with the given regex
- #if matched, replace the match (all occurances) with the replace parameter
+ #if matched, replace the match (all occurrences) with the replace parameter
def search_file_replace(regex, replace)
@changes = (editor.replace(regex, replace) > 0) || @changes
end
@@ -59,7 +59,7 @@ class Chef
end
#search the file line by line and match each line with the given regex
- #if matched, delete the match (all occurances) from the line
+ #if matched, delete the match (all occurrences) from the line
def search_file_delete(regex)
search_file_replace(regex, '')
end
diff --git a/lib/chef/util/path_helper.rb b/lib/chef/util/path_helper.rb
index 26c9c76fe5..1ae489598d 100644
--- a/lib/chef/util/path_helper.rb
+++ b/lib/chef/util/path_helper.rb
@@ -26,7 +26,7 @@ class Chef
if Chef::Platform.windows?
# Find the first slash, not counting trailing slashes
end_slash = path.size
- while true
+ loop do
slash = path.rindex(/[#{Regexp.escape(File::SEPARATOR)}#{Regexp.escape(path_separator)}]/, end_slash - 1)
if !slash
return end_slash == path.size ? '.' : path_separator
@@ -101,9 +101,6 @@ class Chef
# Produces a comparable path.
def self.canonical_path(path, add_prefix=true)
- # Rather than find an equivalent for File.absolute_path on 1.8.7, just bail out
- raise NotImplementedError, "This feature is not supported on Ruby versions < 1.9" if RUBY_VERSION.to_f < 1.9
-
# First remove extra separators and resolve any relative paths
abs_path = File.absolute_path(path)
diff --git a/lib/chef/util/windows/net_use.rb b/lib/chef/util/windows/net_use.rb
index 37efc02fcc..62d7e169dc 100644
--- a/lib/chef/util/windows/net_use.rb
+++ b/lib/chef/util/windows/net_use.rb
@@ -46,9 +46,9 @@ class Chef::Util::Windows::NetUse < Chef::Util::Windows
USE_INFO_2.collect { |field| field[1].class == Fixnum ? 'i' : 'L' }.join
SIZEOF_USE_INFO_2 = #sizeof(USE_INFO_2)
- USE_INFO_2.inject(0){|sum,item|
- sum + (item[1].class == Fixnum ? 4 : PTR_SIZE)
- }
+ USE_INFO_2.inject(0) do |sum, item|
+ sum + (item[1].class == Fixnum ? 4 : PTR_SIZE)
+ end
def use_info_2(args)
USE_INFO_2.collect { |field|
diff --git a/lib/chef/version.rb b/lib/chef/version.rb
index b61a044907..27ba372f61 100644
--- a/lib/chef/version.rb
+++ b/lib/chef/version.rb
@@ -17,7 +17,7 @@
class Chef
CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__)))
- VERSION = '12.0.3'
+ VERSION = '12.1.0.rc.0'
end
#
diff --git a/lib/chef/win32/api.rb b/lib/chef/win32/api.rb
index 0330810b3b..8b81947c9b 100644
--- a/lib/chef/win32/api.rb
+++ b/lib/chef/win32/api.rb
@@ -159,6 +159,7 @@ class Chef
host.typedef :pointer, :PDWORD32 # Pointer to a DWORD32.
host.typedef :pointer, :PDWORD64 # Pointer to a DWORD64.
host.typedef :pointer, :PFLOAT # Pointer to a FLOAT.
+ host.typedef :pointer, :PGENERICMAPPING #Pointer to GENERIC_MAPPING
host.typedef :pointer, :PHALF_PTR # Pointer to a HALF_PTR.
host.typedef :pointer, :PHANDLE # Pointer to a HANDLE.
host.typedef :pointer, :PHKEY # Pointer to an HKEY.
diff --git a/lib/chef/win32/api/security.rb b/lib/chef/win32/api/security.rb
index 7ca2d70c8e..229f2ace10 100644
--- a/lib/chef/win32/api/security.rb
+++ b/lib/chef/win32/api/security.rb
@@ -270,6 +270,15 @@ class Chef
:MaxTokenInfoClass
]
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379572%28v=vs.85%29.aspx
+ SECURITY_IMPERSONATION_LEVEL = enum :SECURITY_IMPERSONATION_LEVEL, [
+ :SecurityAnonymous,
+ :SecurityIdentification,
+ :SecurityImpersonation,
+ :SecurityDelegation
+ ]
+
+
# SECURITY_DESCRIPTOR is an opaque structure whose contents can vary. Pass the
# pointer around and free it with LocalFree.
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa379561(v=vs.85).aspx
@@ -320,6 +329,19 @@ class Chef
:Attributes, :DWORD
end
+ class GENERIC_MAPPING < FFI::Struct
+ layout :GenericRead, :DWORD,
+ :GenericWrite, :DWORD,
+ :GenericExecute, :DWORD,
+ :GenericAll, :DWORD
+ end
+
+ class PRIVILEGE_SET < FFI::Struct
+ layout :PrivilegeCount, :DWORD,
+ :Control, :DWORD,
+ :Privilege, [LUID_AND_ATTRIBUTES, 1]
+ end
+
class TOKEN_PRIVILEGES < FFI::Struct
layout :PrivilegeCount, :DWORD,
:Privileges, LUID_AND_ATTRIBUTES
@@ -339,6 +361,7 @@ class Chef
ffi_lib "advapi32"
+ safe_attach_function :AccessCheck, [:pointer, :HANDLE, :DWORD, :pointer, :pointer, :pointer, :pointer, :pointer], :BOOL
safe_attach_function :AddAce, [ :pointer, :DWORD, :DWORD, :LPVOID, :DWORD ], :BOOL
safe_attach_function :AddAccessAllowedAce, [ :pointer, :DWORD, :DWORD, :pointer ], :BOOL
safe_attach_function :AddAccessAllowedAceEx, [ :pointer, :DWORD, :DWORD, :DWORD, :pointer ], :BOOL
@@ -348,9 +371,11 @@ class Chef
safe_attach_function :ConvertSidToStringSidA, [ :pointer, :pointer ], :BOOL
safe_attach_function :ConvertStringSidToSidW, [ :pointer, :pointer ], :BOOL
safe_attach_function :DeleteAce, [ :pointer, :DWORD ], :BOOL
+ safe_attach_function :DuplicateToken, [:HANDLE, :SECURITY_IMPERSONATION_LEVEL, :PHANDLE], :BOOL
safe_attach_function :EqualSid, [ :pointer, :pointer ], :BOOL
safe_attach_function :FreeSid, [ :pointer ], :pointer
safe_attach_function :GetAce, [ :pointer, :DWORD, :pointer ], :BOOL
+ safe_attach_function :GetFileSecurityW, [:LPCWSTR, :DWORD, :pointer, :DWORD, :pointer], :BOOL
safe_attach_function :GetLengthSid, [ :pointer ], :DWORD
safe_attach_function :GetNamedSecurityInfoW, [ :LPWSTR, :SE_OBJECT_TYPE, :DWORD, :pointer, :pointer, :pointer, :pointer, :pointer ], :DWORD
safe_attach_function :GetSecurityDescriptorControl, [ :pointer, :PWORD, :LPDWORD], :BOOL
@@ -369,6 +394,7 @@ class Chef
safe_attach_function :LookupPrivilegeDisplayNameW, [ :LPCWSTR, :LPCWSTR, :LPWSTR, :LPDWORD, :LPDWORD ], :BOOL
safe_attach_function :LookupPrivilegeValueW, [ :LPCWSTR, :LPCWSTR, :PLUID ], :BOOL
safe_attach_function :MakeAbsoluteSD, [ :pointer, :pointer, :LPDWORD, :pointer, :LPDWORD, :pointer, :LPDWORD, :pointer, :LPDWORD, :pointer, :LPDWORD], :BOOL
+ safe_attach_function :MapGenericMask, [ :PDWORD, :PGENERICMAPPING ], :void
safe_attach_function :OpenProcessToken, [ :HANDLE, :DWORD, :PHANDLE ], :BOOL
safe_attach_function :QuerySecurityAccessMask, [ :DWORD, :LPDWORD ], :void
safe_attach_function :SetFileSecurityW, [ :LPWSTR, :DWORD, :pointer ], :BOOL
diff --git a/lib/chef/win32/file.rb b/lib/chef/win32/file.rb
index d489c9ce8a..e6640caa3c 100644
--- a/lib/chef/win32/file.rb
+++ b/lib/chef/win32/file.rb
@@ -155,6 +155,27 @@ class Chef
end
end
+ def self.file_access_check(path, desired_access)
+ security_descriptor = Chef::ReservedNames::Win32::Security.get_file_security(path)
+ token_rights = Chef::ReservedNames::Win32::Security::TOKEN_IMPERSONATE |
+ Chef::ReservedNames::Win32::Security::TOKEN_QUERY |
+ Chef::ReservedNames::Win32::Security::TOKEN_DUPLICATE |
+ Chef::ReservedNames::Win32::Security::STANDARD_RIGHTS_READ
+ token = Chef::ReservedNames::Win32::Security.open_process_token(
+ Chef::ReservedNames::Win32::Process.get_current_process,
+ token_rights)
+ duplicate_token = token.duplicate_token(:SecurityImpersonation)
+
+ 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
+
+ Chef::ReservedNames::Win32::Security.access_check(security_descriptor, duplicate_token,
+ desired_access, mapping)
+ end
+
# ::File compat
class << self
alias :stat :info
diff --git a/lib/chef/win32/security.rb b/lib/chef/win32/security.rb
index 48ca78647f..3902d8caaf 100644
--- a/lib/chef/win32/security.rb
+++ b/lib/chef/win32/security.rb
@@ -32,6 +32,34 @@ class Chef
extend Chef::ReservedNames::Win32::API::Security
extend Chef::ReservedNames::Win32::API::Macros
+ def self.access_check(security_descriptor, token, desired_access, generic_mapping)
+ token_handle = token.handle.handle
+ security_descriptor_ptr = security_descriptor.pointer
+
+ rights_ptr = FFI::MemoryPointer.new(:ulong)
+ rights_ptr.write_ulong(desired_access)
+
+ # This function takes care of calling MapGenericMask, so you don't have to
+ MapGenericMask(rights_ptr, generic_mapping)
+
+ result_ptr = FFI::MemoryPointer.new(:ulong)
+
+ # Because optional actually means required
+ privileges = PRIVILEGE_SET.new
+ privileges[:PrivilegeCount] = 0
+ privileges_length_ptr = FFI::MemoryPointer.new(:ulong)
+ privileges_length_ptr.write_ulong(privileges.size)
+
+ granted_access_ptr = FFI::MemoryPointer.new(:ulong)
+
+ unless AccessCheck(security_descriptor_ptr, token_handle, rights_ptr.read_ulong,
+ generic_mapping, privileges, privileges_length_ptr, granted_access_ptr,
+ result_ptr)
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+ result_ptr.read_ulong == 1
+ end
+
def self.add_ace(acl, ace, insert_position = MAXDWORD, revision = ACL_REVISION)
acl = acl.pointer if acl.respond_to?(:pointer)
ace = ace.pointer if ace.respond_to?(:pointer)
@@ -148,6 +176,24 @@ class Chef
GetLengthSid(sid)
end
+ def self.get_file_security(path, info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)
+ size_ptr = FFI::MemoryPointer.new(:ulong)
+
+ success = GetFileSecurityW(path.to_wstring, info, nil, 0, size_ptr)
+
+ if !success && FFI::LastError.error != ERROR_INSUFFICIENT_BUFFER
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+
+ security_descriptor_ptr = FFI::MemoryPointer.new(size_ptr.read_ulong)
+ unless GetFileSecurityW(path.to_wstring, info, security_descriptor_ptr, size_ptr.read_ulong, size_ptr)
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+
+ SecurityDescriptor.new(security_descriptor_ptr)
+ end
+
+
def self.get_named_security_info(path, type = :SE_FILE_OBJECT, info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)
security_descriptor = FFI::MemoryPointer.new :pointer
hr = GetNamedSecurityInfoW(path.to_wstring, type, info, nil, nil, nil, nil, security_descriptor)
diff --git a/lib/chef/win32/security/token.rb b/lib/chef/win32/security/token.rb
index ded4fc080e..9e494a73b9 100644
--- a/lib/chef/win32/security/token.rb
+++ b/lib/chef/win32/security/token.rb
@@ -58,6 +58,14 @@ class Chef
Chef::ReservedNames::Win32::Security::adjust_token_privileges(self, privileges_struct)
end
end
+
+ def duplicate_token(security_impersonation_level)
+ duplicate_token_handle = FFI::Buffer.new(:ulong)
+ unless Chef::ReservedNames::Win32::API::Security.DuplicateToken(handle.handle, security_impersonation_level, duplicate_token_handle)
+ raise Chef::ReservedNames::Win32::Error.raise!
+ end
+ Token.new(Handle.new(duplicate_token_handle.read_ulong))
+ end
end
end
end
diff --git a/lib/chef/win32/version.rb b/lib/chef/win32/version.rb
index d16bd8c12f..6a5bd35a26 100644
--- a/lib/chef/win32/version.rb
+++ b/lib/chef/win32/version.rb
@@ -126,14 +126,10 @@ class Chef
# https://github.com/ruby/ruby/commit/588504b20f5cc880ad51827b93e571e32446e5db
# https://github.com/ruby/ruby/commit/27ed294c7134c0de582007af3c915a635a6506cd
- WIN32OLE.ole_initialize
-
wmi = WmiLite::Wmi.new
os_info = wmi.first_of('Win32_OperatingSystem')
os_version = os_info['version']
- WIN32OLE.ole_uninitialize
-
# The operating system version is a string in the following form
# that can be split into components based on the '.' delimiter:
# MajorVersionNumber.MinorVersionNumber.BuildNumber
diff --git a/pedant.gemfile b/pedant.gemfile
index d4ac849707..baa3e9aece 100644
--- a/pedant.gemfile
+++ b/pedant.gemfile
@@ -2,7 +2,6 @@ source "https://rubygems.org"
gemspec :name => "chef"
gem 'rest-client', :github => 'opscode/rest-client', :branch => 'lcg/1.6.7-version-lying'
-gem 'chef-pedant', :github => 'opscode/chef-pedant', :branch => "metadata-name-fix"
# TODO figure out how to grab this stuff from the main Gemfile
gem "activesupport", "< 4.0.0", :group => :compat_testing, :platform => "ruby"
diff --git a/spec/data/recipes.tgz b/spec/data/recipes.tgz
new file mode 100644
index 0000000000..a6c172a001
--- /dev/null
+++ b/spec/data/recipes.tgz
Binary files differ
diff --git a/spec/functional/application_spec.rb b/spec/functional/application_spec.rb
index 4a0fdff8f8..00ff0f702a 100644
--- a/spec/functional/application_spec.rb
+++ b/spec/functional/application_spec.rb
@@ -52,7 +52,7 @@ describe Chef::Application do
shell_out("echo $http_proxy")
end
- so.stdout.chomp.should == "http://proxy.example.org:8080"
+ expect(so.stdout.chomp).to eq("http://proxy.example.org:8080")
end
end
end
diff --git a/spec/functional/audit/rspec_formatter_spec.rb b/spec/functional/audit/rspec_formatter_spec.rb
new file mode 100644
index 0000000000..009374db68
--- /dev/null
+++ b/spec/functional/audit/rspec_formatter_spec.rb
@@ -0,0 +1,54 @@
+#
+# Author:: Tyler Ball (<tball@chef.io>)
+# Author:: Claire McQuin (<claire@getchef.com>)
+#
+# Copyright:: Copyright (c) 2014 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 'spec_helper'
+require 'rspec/core/sandbox'
+require 'chef/audit/runner'
+require 'rspec/support/spec/in_sub_process'
+require 'rspec/support/spec/stderr_splitter'
+require 'chef/audit/rspec_formatter'
+
+describe Chef::Audit::RspecFormatter do
+ include RSpec::Support::InSubProcess
+
+ let(:events) { double("events").as_null_object }
+ let(:audits) { {} }
+ let(:run_context) { instance_double(Chef::RunContext, :events => events, :audits => audits) }
+ let(:runner) { Chef::Audit::Runner.new(run_context) }
+
+ let(:output) { double("output") }
+ # aggressively define this so we can mock out the new call later
+ let!(:formatter) { Chef::Audit::RspecFormatter.new(output) }
+
+ around(:each) do |ex|
+ RSpec::Core::Sandbox.sandboxed { ex.run }
+ end
+
+ it "should not close the output using our formatter" do
+ in_sub_process do
+ expect_any_instance_of(Chef::Audit::RspecFormatter).to receive(:new).and_return(formatter)
+ expect(formatter).to receive(:close).and_call_original
+ expect(output).to_not receive(:close)
+
+ runner.run
+ end
+ end
+
+end
diff --git a/spec/functional/audit/runner_spec.rb b/spec/functional/audit/runner_spec.rb
new file mode 100644
index 0000000000..494942889a
--- /dev/null
+++ b/spec/functional/audit/runner_spec.rb
@@ -0,0 +1,137 @@
+#
+# Author:: Tyler Ball (<tball@chef.io>)
+# Copyright:: Copyright (c) 2014 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 'spec_helper'
+require 'rspec/core/sandbox'
+require 'chef/audit/runner'
+require 'rspec/support/spec/in_sub_process'
+require 'rspec/support/spec/stderr_splitter'
+require 'tempfile'
+
+##
+# This functional test ensures that our runner can be setup to not interfere with existing RSpec
+# configuration and world objects. When normally running Chef, there is only 1 RSpec instance
+# so this isn't needed. In unit testing the Runner should be mocked appropriately.
+
+describe Chef::Audit::Runner do
+
+ # The functional tests must be run in a sub_process. Including Serverspec includes the Serverspec DSL - this
+ # conflicts with our `package` DSL (among others) when we try to test `package` inside an RSpec example.
+ # Our DSL leverages `method_missing` while the Serverspec DSL defines a method on the RSpec::Core::ExampleGroup.
+ # The defined method wins our and returns before our `method_missing` DSL can be called.
+ #
+ # Running in a sub_process means the serverspec libraries will only be included in a forked process, not the main one.
+ include RSpec::Support::InSubProcess
+
+ let(:events) { double("events").as_null_object }
+ let(:runner) { Chef::Audit::Runner.new(run_context) }
+ let(:stdout) { StringIO.new }
+
+ around(:each) do |ex|
+ RSpec::Core::Sandbox.sandboxed { ex.run }
+ end
+
+ before do
+ Chef::Config[:log_location] = stdout
+ end
+
+ describe "#run" do
+
+ let(:audits) { {} }
+ let(:run_context) { instance_double(Chef::RunContext, :events => events, :audits => audits) }
+ let(:control_group_name) { "control_group_name" }
+
+ it "Correctly runs an empty controls block" do
+ in_sub_process do
+ runner.run
+ end
+ end
+
+ shared_context "passing audit" do
+ let(:audits) do
+ should_pass = lambda do
+ it "should pass" do
+ expect(2 - 2).to eq(0)
+ end
+ end
+ { control_group_name => Struct.new(:args, :block).new([control_group_name], should_pass)}
+ end
+ end
+
+ shared_context "failing audit" do
+ let(:audits) do
+ should_fail = lambda do
+ it "should fail" do
+ expect(2 - 1).to eq(0)
+ end
+ end
+ { control_group_name => Struct.new(:args, :block).new([control_group_name], should_fail)}
+ end
+ end
+
+ context "there is a single successful control" do
+ include_context "passing audit"
+ it "correctly runs" do
+ in_sub_process do
+ runner.run
+
+ expect(stdout.string).to match(/1 example, 0 failures/)
+ end
+ end
+ end
+
+ context "there is a single failing control" do
+ include_context "failing audit"
+ it "correctly runs" do
+ in_sub_process do
+ runner.run
+
+ expect(stdout.string).to match(/Failure\/Error: expect\(2 - 1\)\.to eq\(0\)/)
+ expect(stdout.string).to match(/1 example, 1 failure/)
+ expect(stdout.string).to match(/# control_group_name should fail/)
+ end
+ end
+ end
+
+ describe "log location is a file" do
+ let(:tmpfile) { Tempfile.new("audit") }
+ before do
+ Chef::Config[:log_location] = tmpfile.path
+ end
+
+ after do
+ tmpfile.close
+ tmpfile.unlink
+ end
+
+ include_context "failing audit"
+ it "correctly runs" do
+ in_sub_process do
+ runner.run
+
+ contents = tmpfile.read
+ expect(contents).to match(/Failure\/Error: expect\(2 - 1\)\.to eq\(0\)/)
+ expect(contents).to match(/1 example, 1 failure/)
+ expect(contents).to match(/# control_group_name should fail/)
+ end
+ end
+ end
+
+ end
+
+end
diff --git a/spec/functional/dsl/reboot_pending_spec.rb b/spec/functional/dsl/reboot_pending_spec.rb
index 125c952a55..14dd9412d5 100644
--- a/spec/functional/dsl/reboot_pending_spec.rb
+++ b/spec/functional/dsl/reboot_pending_spec.rb
@@ -48,18 +48,18 @@ describe Chef::DSL::RebootPending, :windows_only do
describe "when there is nothing to indicate a reboot is pending" do
it "should return false" do
- pending "Found existing registry keys" if registry_unsafe?
- expect(recipe.reboot_pending?).to be_false
+ skip "Found existing registry keys" if registry_unsafe?
+ expect(recipe.reboot_pending?).to be_falsey
end
end
describe 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations' do
it "returns true if the registry value exists" do
- pending "Found existing registry keys" if registry_unsafe?
+ skip "Found existing registry keys" if registry_unsafe?
registry.set_value('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager',
{ :name => 'PendingFileRenameOperations', :type => :multi_string, :data => ['\??\C:\foo.txt|\??\C:\bar.txt'] })
- expect(recipe.reboot_pending?).to be_true
+ expect(recipe.reboot_pending?).to be_truthy
end
after do
@@ -71,10 +71,10 @@ describe Chef::DSL::RebootPending, :windows_only do
describe 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired' do
it "returns true if the registry key exists" do
- pending "Found existing registry keys" if registry_unsafe?
+ skip "Found existing registry keys" if registry_unsafe?
registry.create_key('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired', false)
- expect(recipe.reboot_pending?).to be_true
+ expect(recipe.reboot_pending?).to be_truthy
end
after do
@@ -87,10 +87,10 @@ describe Chef::DSL::RebootPending, :windows_only do
describe 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired' do
it "returns true if the registry key exists" do
pending "Permissions are limited to 'TrustedInstaller' by default"
- pending "Found existing registry keys" if registry_unsafe?
+ skip "Found existing registry keys" if registry_unsafe?
registry.create_key('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired', false)
- expect(recipe.reboot_pending?).to be_true
+ expect(recipe.reboot_pending?).to be_truthy
end
after do
@@ -102,12 +102,12 @@ describe Chef::DSL::RebootPending, :windows_only do
describe 'HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile\Flags' do
it "returns true if the registry key exists" do
- pending "Found existing registry keys" if registry_unsafe?
+ skip "Found existing registry keys" if registry_unsafe?
registry.create_key('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile', true)
registry.set_value('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile',
{ :name => 'Flags', :type => :dword, :data => 3 })
- expect(recipe.reboot_pending?).to be_true
+ expect(recipe.reboot_pending?).to be_truthy
end
after do
diff --git a/spec/functional/dsl/registry_helper_spec.rb b/spec/functional/dsl/registry_helper_spec.rb
index 452c4c2799..df5b09f1f6 100644
--- a/spec/functional/dsl/registry_helper_spec.rb
+++ b/spec/functional/dsl/registry_helper_spec.rb
@@ -40,24 +40,24 @@ describe Chef::Resource::RegistryKey, :windows_only do
context "tests registry dsl" do
it "returns true if registry_key_exists" do
- @resource.registry_key_exists?("HKCU\\Software\\Root").should == true
+ expect(@resource.registry_key_exists?("HKCU\\Software\\Root")).to eq(true)
end
it "returns true if registry has specified value" do
values = @resource.registry_get_values("HKCU\\Software\\Root")
- values.include?({:name=>"RootType1",:type=>:string,:data=>"fibrous"}).should == true
+ expect(values.include?({:name=>"RootType1",:type=>:string,:data=>"fibrous"})).to eq(true)
end
it "returns true if specified registry_has_subkey" do
- @resource.registry_has_subkeys?("HKCU\\Software\\Root").should == true
+ expect(@resource.registry_has_subkeys?("HKCU\\Software\\Root")).to eq(true)
end
it "returns true if specified key has specified subkey" do
subkeys = @resource.registry_get_subkeys("HKCU\\Software\\Root")
- subkeys.include?("Branch").should == true
+ expect(subkeys.include?("Branch")).to eq(true)
end
it "returns true if registry_value_exists" do
- @resource.registry_value_exists?("HKCU\\Software\\Root", {:name=>"RootType1", :type=>:string, :data=>"fibrous"}).should == true
+ expect(@resource.registry_value_exists?("HKCU\\Software\\Root", {:name=>"RootType1", :type=>:string, :data=>"fibrous"})).to eq(true)
end
it "returns true if data_value_exists" do
- @resource.registry_data_exists?("HKCU\\Software\\Root", {:name=>"RootType1", :type=>:string, :data=>"fibrous"}).should == true
+ expect(@resource.registry_data_exists?("HKCU\\Software\\Root", {:name=>"RootType1", :type=>:string, :data=>"fibrous"})).to eq(true)
end
end
end
diff --git a/spec/functional/event_loggers/windows_eventlog_spec.rb b/spec/functional/event_loggers/windows_eventlog_spec.rb
index c50bc7e00f..4e383dd429 100644
--- a/spec/functional/event_loggers/windows_eventlog_spec.rb
+++ b/spec/functional/event_loggers/windows_eventlog_spec.rb
@@ -37,21 +37,21 @@ describe Chef::EventLoggers::WindowsEventLogger, :windows_only, :not_supported_o
let(:mock_exception) { double('Exception', {message: SecureRandom.uuid, backtrace:[SecureRandom.uuid, SecureRandom.uuid]})}
it 'is available' do
- Chef::EventLoggers::WindowsEventLogger.available?.should be_true
+ expect(Chef::EventLoggers::WindowsEventLogger.available?).to be_truthy
end
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_true
+ e.string_inserts[0].include?(version)}).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_true
+ e.string_inserts[0].include?(run_id)}).to be_truthy
end
it 'writes run_completed event with event_id 10002 and contains the run_id and elapsed time' do
@@ -61,7 +61,7 @@ describe Chef::EventLoggers::WindowsEventLogger, :windows_only, :not_supported_o
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_true
+ }).to be_truthy
end
it 'writes run_failed event with event_id 10003 and contains the run_id, elapsed time, and exception info' do
@@ -76,7 +76,7 @@ describe Chef::EventLoggers::WindowsEventLogger, :windows_only, :not_supported_o
e.string_inserts[3].include?(mock_exception.message) &&
e.string_inserts[4].include?(mock_exception.backtrace[0]) &&
e.string_inserts[4].include?(mock_exception.backtrace[1])
- end).to be_true
+ end).to be_truthy
end
end
diff --git a/spec/functional/file_content_management/deploy_strategies_spec.rb b/spec/functional/file_content_management/deploy_strategies_spec.rb
index dd1ef6228f..03a6c504c1 100644
--- a/spec/functional/file_content_management/deploy_strategies_spec.rb
+++ b/spec/functional/file_content_management/deploy_strategies_spec.rb
@@ -20,15 +20,6 @@ require 'spec_helper'
shared_examples_for "a content deploy strategy" do
- # Ruby 1.8 has no binread
- def binread(file)
- if IO.respond_to?(:binread)
- IO.binread(file)
- else
- IO.read(file)
- end
- end
-
def normalize_mode(mode_int)
( mode_int & 07777).to_s(8)
end
@@ -56,11 +47,11 @@ shared_examples_for "a content deploy strategy" do
it "touches the file to create it (UNIX)", :unix_only do
content_deployer.create(target_file_path)
- File.should exist(target_file_path)
+ expect(File).to exist(target_file_path)
file_info = File.stat(target_file_path)
- file_info.should be_owned
- file_info.should be_file
- normalize_mode(file_info.mode).should == default_mode
+ expect(file_info).to be_owned
+ expect(file_info).to be_file
+ expect(normalize_mode(file_info.mode)).to eq(default_mode)
end
##
@@ -89,10 +80,10 @@ shared_examples_for "a content deploy strategy" do
it "touches the file to create it (Windows)", :windows_only do
content_deployer.create(target_file_path)
- File.should exist(target_file_path)
+ expect(File).to exist(target_file_path)
file_info = File.stat(target_file_path)
- file_info.should be_owned
- file_info.should be_file
+ expect(file_info).to be_owned
+ expect(file_info).to be_file
parent_aces = parent_inheritable_aces
security_obj = Chef::ReservedNames::Win32::Security::SecurableObject.new(target_file_path)
@@ -106,7 +97,7 @@ shared_examples_for "a content deploy strategy" do
end
self_aces.each_with_index do |ace, index|
- ace.mask.should == parent_aces[index].mask
+ expect(ace.mask).to eq(parent_aces[index].mask)
end
end
end
@@ -147,7 +138,7 @@ shared_examples_for "a content deploy strategy" do
content_deployer.deploy(staging_file_path, target_file_path)
updated_info = File.stat(target_file_path)
- unix_invariant_properies(original_info).should == unix_invariant_properies(updated_info)
+ expect(unix_invariant_properies(original_info)).to eq(unix_invariant_properies(updated_info))
end
it "maintains invariant properties on Windows", :windows_only do
@@ -155,12 +146,12 @@ shared_examples_for "a content deploy strategy" do
content_deployer.deploy(staging_file_path, target_file_path)
updated_info = Chef::ReservedNames::Win32::Security::SecurableObject.new(target_file_path)
- win_invariant_properties(original_info).should == win_invariant_properties(updated_info)
+ expect(win_invariant_properties(original_info)).to eq(win_invariant_properties(updated_info))
end
it "updates the target with content from staged" do
content_deployer.deploy(staging_file_path, target_file_path)
- binread(target_file_path).should == staging_file_content
+ expect(IO.binread(target_file_path)).to eq(staging_file_content)
end
context "when the owner of the target file is not the owner of the staging file", :requires_root do
@@ -174,7 +165,7 @@ shared_examples_for "a content deploy strategy" do
content_deployer.deploy(staging_file_path, target_file_path)
updated_info = File.stat(target_file_path)
- unix_invariant_properies(original_info).should == unix_invariant_properies(updated_info)
+ expect(unix_invariant_properies(original_info)).to eq(unix_invariant_properies(updated_info))
end
end
diff --git a/spec/functional/http/simple_spec.rb b/spec/functional/http/simple_spec.rb
index fec71351df..36468b4eba 100644
--- a/spec/functional/http/simple_spec.rb
+++ b/spec/functional/http/simple_spec.rb
@@ -85,7 +85,7 @@ describe Chef::HTTP::Simple do
before do
Chef::Log.level = :debug
@debug_log = ''
- Chef::Log.stub(:debug) { |str| @debug_log << str }
+ allow(Chef::Log).to receive(:debug) { |str| @debug_log << str }
end
let(:source) { 'http://localhost:9000' }
diff --git a/spec/functional/knife/cookbook_delete_spec.rb b/spec/functional/knife/cookbook_delete_spec.rb
index 4773fd2185..15ac8f55ab 100644
--- a/spec/functional/knife/cookbook_delete_spec.rb
+++ b/spec/functional/knife/cookbook_delete_spec.rb
@@ -51,9 +51,9 @@ describe Chef::Knife::CookbookDelete do
end
it "logs an error and exits" do
- @knife.ui.stub(:stderr).and_return(@log_output)
- lambda {@knife.run}.should raise_error(SystemExit)
- @log_output.string.should match(/Cannot find a cookbook named no-such-cookbook to delete/)
+ allow(@knife.ui).to receive(:stderr).and_return(@log_output)
+ expect {@knife.run}.to raise_error(SystemExit)
+ expect(@log_output.string).to match(/Cannot find a cookbook named no-such-cookbook to delete/)
end
end
@@ -67,33 +67,33 @@ describe Chef::Knife::CookbookDelete do
it "asks for confirmation, then deletes the cookbook" do
stdin, stdout = StringIO.new("y\n"), StringIO.new
- @knife.ui.stub(:stdin).and_return(stdin)
- @knife.ui.stub(:stdout).and_return(stdout)
+ allow(@knife.ui).to receive(:stdin).and_return(stdin)
+ allow(@knife.ui).to receive(:stdout).and_return(stdout)
cb100_deleted = false
@api.delete("/cookbooks/obsolete-cookbook/1.0.0", 200) { cb100_deleted = true; "[\"true\"]" }
@knife.run
- stdout.string.should match(/#{Regexp.escape('Do you really want to delete obsolete-cookbook version 1.0.0? (Y/N)')}/)
- cb100_deleted.should be_true
+ expect(stdout.string).to match(/#{Regexp.escape('Do you really want to delete obsolete-cookbook version 1.0.0? (Y/N)')}/)
+ expect(cb100_deleted).to be_truthy
end
it "asks for confirmation before purging" do
@knife.config[:purge] = true
stdin, stdout = StringIO.new("y\ny\n"), StringIO.new
- @knife.ui.stub(:stdin).and_return(stdin)
- @knife.ui.stub(:stdout).and_return(stdout)
+ allow(@knife.ui).to receive(:stdin).and_return(stdin)
+ allow(@knife.ui).to receive(:stdout).and_return(stdout)
cb100_deleted = false
@api.delete("/cookbooks/obsolete-cookbook/1.0.0?purge=true", 200) { cb100_deleted = true; "[\"true\"]" }
@knife.run
- stdout.string.should match(/#{Regexp.escape('Are you sure you want to purge files')}/)
- stdout.string.should match(/#{Regexp.escape('Do you really want to delete obsolete-cookbook version 1.0.0? (Y/N)')}/)
- cb100_deleted.should be_true
+ expect(stdout.string).to match(/#{Regexp.escape('Are you sure you want to purge files')}/)
+ expect(stdout.string).to match(/#{Regexp.escape('Do you really want to delete obsolete-cookbook version 1.0.0? (Y/N)')}/)
+ expect(cb100_deleted).to be_truthy
end
@@ -117,22 +117,22 @@ describe Chef::Knife::CookbookDelete do
@api.delete("/cookbooks/obsolete-cookbook/1.2.0", 200) { cb120_deleted = true; "[\"true\"]" }
@knife.run
- cb100_deleted.should be_true
- cb110_deleted.should be_true
- cb120_deleted.should be_true
+ expect(cb100_deleted).to be_truthy
+ expect(cb110_deleted).to be_truthy
+ expect(cb120_deleted).to be_truthy
end
it "asks which version to delete and deletes that when not given the -a flag" do
cb100_deleted = cb110_deleted = cb120_deleted = nil
@api.delete("/cookbooks/obsolete-cookbook/1.0.0", 200) { cb100_deleted = true; "[\"true\"]" }
stdin, stdout = StringIO.new, StringIO.new
- @knife.ui.stub(:stdin).and_return(stdin)
- @knife.ui.stub(:stdout).and_return(stdout)
+ allow(@knife.ui).to receive(:stdin).and_return(stdin)
+ allow(@knife.ui).to receive(:stdout).and_return(stdout)
stdin << "1\n"
stdin.rewind
@knife.run
- cb100_deleted.should be_true
- stdout.string.should match(/Which version\(s\) do you want to delete\?/)
+ expect(cb100_deleted).to be_truthy
+ expect(stdout.string).to match(/Which version\(s\) do you want to delete\?/)
end
it "deletes all versions of the cookbook when not given the -a flag and the user chooses to delete all" do
@@ -142,14 +142,14 @@ describe Chef::Knife::CookbookDelete do
@api.delete("/cookbooks/obsolete-cookbook/1.2.0", 200) { cb120_deleted = true; "[\"true\"]" }
stdin, stdout = StringIO.new("4\n"), StringIO.new
- @knife.ui.stub(:stdin).and_return(stdin)
- @knife.ui.stub(:stdout).and_return(stdout)
+ allow(@knife.ui).to receive(:stdin).and_return(stdin)
+ allow(@knife.ui).to receive(:stdout).and_return(stdout)
@knife.run
- cb100_deleted.should be_true
- cb110_deleted.should be_true
- cb120_deleted.should be_true
+ expect(cb100_deleted).to be_truthy
+ expect(cb110_deleted).to be_truthy
+ expect(cb120_deleted).to be_truthy
end
end
diff --git a/spec/functional/knife/exec_spec.rb b/spec/functional/knife/exec_spec.rb
index 7eb52d01df..6262094a9f 100644
--- a/spec/functional/knife/exec_spec.rb
+++ b/spec/functional/knife/exec_spec.rb
@@ -41,9 +41,7 @@ describe Chef::Knife::Exec do
@server.stop
end
- pending "executes a script in the context of the chef-shell main context", :ruby_18_only
-
- it "executes a script in the context of the chef-shell main context", :ruby_gte_19_only do
+ it "executes a script in the context of the chef-shell main context" do
@node = Chef::Node.new
@node.name("ohai-world")
response = {"rows" => [@node],"start" => 0,"total" => 1}
@@ -51,7 +49,7 @@ describe Chef::Knife::Exec do
code = "$output.puts nodes.all"
@knife.config[:exec] = code
@knife.run
- $output.string.should match(%r{node\[ohai-world\]})
+ expect($output.string).to match(%r{node\[ohai-world\]})
end
end
diff --git a/spec/functional/knife/smoke_test.rb b/spec/functional/knife/smoke_test.rb
index 6ccd462516..607e8065cf 100644
--- a/spec/functional/knife/smoke_test.rb
+++ b/spec/functional/knife/smoke_test.rb
@@ -29,6 +29,6 @@ describe "knife smoke tests" do
knife_cmd = Mixlib::ShellOut.new("#{knife_path} -v")
knife_cmd.run_command
knife_cmd.error!
- knife_cmd.stdout.should include(Chef::VERSION)
+ expect(knife_cmd.stdout).to include(Chef::VERSION)
end
end
diff --git a/spec/functional/knife/ssh_spec.rb b/spec/functional/knife/ssh_spec.rb
index 40d71859c7..5b8ad6f368 100644
--- a/spec/functional/knife/ssh_spec.rb
+++ b/spec/functional/knife/ssh_spec.rb
@@ -40,7 +40,7 @@ describe Chef::Knife::Ssh do
it "uses the ssh_identity_file" do
@knife.run
- @knife.config[:identity_file].should == "~/.ssh/aws.rsa"
+ expect(@knife.config[:identity_file]).to eq("~/.ssh/aws.rsa")
end
end
@@ -52,7 +52,7 @@ describe Chef::Knife::Ssh do
it "uses the ssh_identity_file" do
@knife.run
- @knife.config[:identity_file].should == "~/.ssh/aws.rsa"
+ expect(@knife.config[:identity_file]).to eq("~/.ssh/aws.rsa")
end
end
@@ -64,13 +64,13 @@ describe Chef::Knife::Ssh do
it "should use the value on the command line" do
@knife.run
- @knife.config[:identity_file].should == "~/.ssh/aws.rsa"
+ expect(@knife.config[:identity_file]).to eq("~/.ssh/aws.rsa")
end
it "should override what is set in knife.rb" do
Chef::Config[:knife][:ssh_identity_file] = "~/.ssh/other.rsa"
@knife.run
- @knife.config[:identity_file].should == "~/.ssh/aws.rsa"
+ expect(@knife.config[:identity_file]).to eq("~/.ssh/aws.rsa")
end
end
@@ -82,7 +82,7 @@ describe Chef::Knife::Ssh do
it "uses the default" do
@knife.run
- @knife.config[:identity_file].should == nil
+ expect(@knife.config[:identity_file]).to eq(nil)
end
end
end
@@ -95,7 +95,7 @@ describe Chef::Knife::Ssh do
it "uses the ssh_port" do
@knife.run
- @knife.config[:ssh_port].should == "31337"
+ expect(@knife.config[:ssh_port]).to eq("31337")
end
end
end
@@ -109,7 +109,7 @@ describe Chef::Knife::Ssh do
it "uses the ssh_user" do
@knife.run
- @knife.config[:ssh_user].should == "ubuntu"
+ expect(@knife.config[:ssh_user]).to eq("ubuntu")
end
end
@@ -121,7 +121,7 @@ describe Chef::Knife::Ssh do
it "uses the ssh_user" do
@knife.run
- @knife.config[:ssh_user].should == "ubuntu"
+ expect(@knife.config[:ssh_user]).to eq("ubuntu")
end
end
@@ -133,13 +133,13 @@ describe Chef::Knife::Ssh do
it "should use the value on the command line" do
@knife.run
- @knife.config[:ssh_user].should == "ubuntu"
+ expect(@knife.config[:ssh_user]).to eq("ubuntu")
end
it "should override what is set in knife.rb" do
Chef::Config[:knife][:ssh_user] = "root"
@knife.run
- @knife.config[:ssh_user].should == "ubuntu"
+ expect(@knife.config[:ssh_user]).to eq("ubuntu")
end
end
@@ -151,7 +151,7 @@ describe Chef::Knife::Ssh do
it "uses the default (current user)" do
@knife.run
- @knife.config[:ssh_user].should == nil
+ expect(@knife.config[:ssh_user]).to eq(nil)
end
end
end
@@ -165,7 +165,7 @@ describe Chef::Knife::Ssh do
it "uses the ssh_attribute" do
@knife.run
- @knife.config[:attribute].should == "ec2.public_hostname"
+ expect(@knife.config[:attribute]).to eq("ec2.public_hostname")
end
end
@@ -177,7 +177,7 @@ describe Chef::Knife::Ssh do
it "uses the default" do
@knife.run
- @knife.config[:attribute].should == "fqdn"
+ expect(@knife.config[:attribute]).to eq("fqdn")
end
end
@@ -189,7 +189,7 @@ describe Chef::Knife::Ssh do
it "should use the value on the command line" do
@knife.run
- @knife.config[:attribute].should == "ec2.public_hostname"
+ expect(@knife.config[:attribute]).to eq("ec2.public_hostname")
end
it "should override what is set in knife.rb" do
@@ -198,7 +198,7 @@ describe Chef::Knife::Ssh do
# Then we run knife with the -a flag, which sets the above variable
setup_knife(['-a ec2.public_hostname', '*:*', 'uptime'])
@knife.run
- @knife.config[:attribute].should == "ec2.public_hostname"
+ expect(@knife.config[:attribute]).to eq("ec2.public_hostname")
end
end
end
@@ -211,9 +211,9 @@ describe Chef::Knife::Ssh do
end
it "uses the ssh_gateway" do
- @knife.session.should_receive(:via).with("ec2.public_hostname", "user", {})
+ expect(@knife.session).to receive(:via).with("ec2.public_hostname", "user", {})
@knife.run
- @knife.config[:ssh_gateway].should == "user@ec2.public_hostname"
+ expect(@knife.config[:ssh_gateway]).to eq("user@ec2.public_hostname")
end
end
@@ -224,9 +224,9 @@ describe Chef::Knife::Ssh do
end
it "uses the ssh_gateway" do
- @knife.session.should_receive(:via).with("ec2.public_hostname", "user", {})
+ expect(@knife.session).to receive(:via).with("ec2.public_hostname", "user", {})
@knife.run
- @knife.config[:ssh_gateway].should == "user@ec2.public_hostname"
+ expect(@knife.config[:ssh_gateway]).to eq("user@ec2.public_hostname")
end
end
@@ -234,13 +234,13 @@ describe Chef::Knife::Ssh do
before do
setup_knife(['-G user@ec2.public_hostname', '*:*', 'uptime'])
Chef::Config[:knife][:ssh_gateway] = nil
- @knife.session.stub(:via) do |host, user, options|
+ allow(@knife.session).to receive(:via) do |host, user, options|
raise Net::SSH::AuthenticationFailed unless options[:password]
end
end
it "should prompt the user for a password" do
- @knife.ui.should_receive(:ask).with("Enter the password for user@ec2.public_hostname: ").and_return("password")
+ expect(@knife.ui).to receive(:ask).with("Enter the password for user@ec2.public_hostname: ").and_return("password")
@knife.run
end
end
@@ -252,7 +252,7 @@ describe Chef::Knife::Ssh do
# if available, but #merge_configs (which is called by #configure_chef) is
# necessary to have default options merged in.
@knife.merge_configs
- @knife.stub(:ssh_command).and_return { 0 }
+ allow(@knife).to receive(:ssh_command) { 0 }
@api = TinyServer::API.instance
@api.clear
@@ -260,7 +260,7 @@ 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&rows=1000", 200) {
+ @api.get("/search/node?q=*:*&sort=X_CHEF_id_CHEF_X%20asc&start=0", 200) {
%({"total":1, "start":0, "rows":[{"name":"i-xxxxxxxx", "json_class":"Chef::Node", "automatic":{"fqdn":"the.fqdn", "ec2":{"public_hostname":"the_public_hostname"}},"recipes":[]}]})
}
end
diff --git a/spec/functional/provider/remote_file/cache_control_data_spec.rb b/spec/functional/provider/remote_file/cache_control_data_spec.rb
index 63a4578c69..41f228ae3c 100755
--- a/spec/functional/provider/remote_file/cache_control_data_spec.rb
+++ b/spec/functional/provider/remote_file/cache_control_data_spec.rb
@@ -64,9 +64,9 @@ describe Chef::Provider::RemoteFile::CacheControlData do
it "writes the data to the cache and the same data can be read back" do
cache_control_data.save
saved_cache_control_data = Chef::Provider::RemoteFile::CacheControlData.load_and_validate(uri, file_checksum)
- saved_cache_control_data.etag.should == cache_control_data.etag
- saved_cache_control_data.mtime.should == cache_control_data.mtime
- saved_cache_control_data.checksum.should == cache_control_data.checksum
+ expect(saved_cache_control_data.etag).to eq(cache_control_data.etag)
+ expect(saved_cache_control_data.mtime).to eq(cache_control_data.mtime)
+ expect(saved_cache_control_data.checksum).to eq(cache_control_data.checksum)
end
# Cover the very long remote file path case -- see CHEF-4422 where
@@ -81,17 +81,17 @@ describe Chef::Provider::RemoteFile::CacheControlData do
let(:uri) { uri_exceeds_file_system_limit }
it "writes data to the cache" do
- lambda do
+ expect do
cache_control_data.save
- end.should_not raise_error
+ end.not_to raise_error
end
it "writes the data to the cache and the same data can be read back" do
cache_control_data.save
saved_cache_control_data = Chef::Provider::RemoteFile::CacheControlData.load_and_validate(uri, file_checksum)
- saved_cache_control_data.etag.should == cache_control_data.etag
- saved_cache_control_data.mtime.should == cache_control_data.mtime
- saved_cache_control_data.checksum.should == cache_control_data.checksum
+ expect(saved_cache_control_data.etag).to eq(cache_control_data.etag)
+ expect(saved_cache_control_data.mtime).to eq(cache_control_data.mtime)
+ expect(saved_cache_control_data.checksum).to eq(cache_control_data.checksum)
end
end
diff --git a/spec/functional/provider/whyrun_safe_ruby_block_spec.rb b/spec/functional/provider/whyrun_safe_ruby_block_spec.rb
index 150d46d384..b3c2333e9a 100644
--- a/spec/functional/provider/whyrun_safe_ruby_block_spec.rb
+++ b/spec/functional/provider/whyrun_safe_ruby_block_spec.rb
@@ -44,8 +44,8 @@ describe Chef::Resource::WhyrunSafeRubyBlock do
it "updates the evil laugh, even in why-run mode" do
new_resource.run_action(new_resource.action)
- $evil_global_evil_laugh.should == :mwahahaha
- new_resource.should be_updated
+ expect($evil_global_evil_laugh).to eq(:mwahahaha)
+ expect(new_resource).to be_updated
end
end
end
diff --git a/spec/functional/rebooter_spec.rb b/spec/functional/rebooter_spec.rb
index 8006580d5c..763021607b 100644
--- a/spec/functional/rebooter_spec.rb
+++ b/spec/functional/rebooter_spec.rb
@@ -70,7 +70,7 @@ describe Chef::Platform::Rebooter do
shared_context 'test a reboot method' do
def test_rebooter_method(method_sym, is_windows, expected_reboot_str)
- Chef::Platform.stub(:windows?).and_return(is_windows)
+ allow(Chef::Platform).to receive(:windows?).and_return(is_windows)
expect(rebooter).to receive(:shell_out!).once.with(expected_reboot_str)
expect(rebooter).to receive(method_sym).once.and_call_original
rebooter.send(method_sym, run_context.node)
diff --git a/spec/functional/resource/aix_service_spec.rb b/spec/functional/resource/aix_service_spec.rb
index 6008fdea8f..9dec87db93 100755
--- a/spec/functional/resource/aix_service_spec.rb
+++ b/spec/functional/resource/aix_service_spec.rb
@@ -73,6 +73,9 @@ shared_examples "src service" do
end
describe Chef::Resource::Service, :requires_root, :aix_only do
+
+ include Chef::Mixin::ShellOut
+
def get_user_id
shell_out("id -u #{ENV['USER']}").stdout.chomp
end
diff --git a/spec/functional/resource/aixinit_service_spec.rb b/spec/functional/resource/aixinit_service_spec.rb
index a99309187c..19b65ca2a0 100755
--- a/spec/functional/resource/aixinit_service_spec.rb
+++ b/spec/functional/resource/aixinit_service_spec.rb
@@ -28,12 +28,12 @@ describe Chef::Resource::Service, :requires_root, :aix_only do
# Platform specific validation routines.
def service_should_be_started(file_name)
- # The existance of this file indicates that the service was started.
- expect(File.exists?("/tmp/#{file_name}")).to be_true
+ # The existence of this file indicates that the service was started.
+ expect(File.exists?("/tmp/#{file_name}")).to be_truthy
end
def service_should_be_stopped(file_name)
- expect(File.exists?("/tmp/#{file_name}")).to be_false
+ expect(File.exists?("/tmp/#{file_name}")).to be_falsey
end
def valide_symlinks(expected_output, run_level = nil, status = nil, priority = nil)
diff --git a/spec/functional/resource/bash_spec.rb b/spec/functional/resource/bash_spec.rb
new file mode 100644
index 0000000000..209ec4a12f
--- /dev/null
+++ b/spec/functional/resource/bash_spec.rb
@@ -0,0 +1,88 @@
+#
+# Author:: Serdar Sutay (<serdar@opscode.com>)
+# Copyright:: Copyright (c) 2014 Opscode, 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 'spec_helper'
+require 'functional/resource/base'
+
+describe Chef::Resource::Bash, :unix_only do
+ let(:code) { "echo hello" }
+ let(:resource) {
+ resource = Chef::Resource::Bash.new("foo_resource", run_context)
+ resource.code(code)
+ resource
+ }
+
+ describe "when setting the command attribute" do
+ let (:command) { 'wizard racket' }
+
+ # in Chef-12 the `command` attribute is largely useless, but does set the identity attribute
+ # so that notifications need to target the value of the command. it will not run the `command`
+ # and if it is given without a code block then it does nothing and always succeeds.
+ describe "in Chef-12", :chef_lt_13_only do
+ it "gets the commmand attribute from the name" do
+ expect(resource.command).to eql("foo_resource")
+ end
+
+ it "sets the resource identity to the command name" do
+ resource.command command
+ expect(resource.identity).to eql(command)
+ end
+
+ it "warns when the code is not present and a useless `command` is present" do
+ expect(Chef::Log).to receive(:warn).with(/coding error/)
+ expect(Chef::Log).to receive(:warn).with(/deprecated/)
+ resource.code nil
+ resource.command command
+ expect { resource.run_action(:run) }.not_to raise_error
+ end
+
+ describe "when the code is not present" do
+ let(:code) { nil }
+ it "warns" do
+ expect(Chef::Log).to receive(:warn)
+ expect { resource.run_action(:run) }.not_to raise_error
+ end
+ end
+ end
+
+ # in Chef-13 the `command` attribute needs to be for internal use only
+ describe "in Chef-13", :chef_gte_13_only do
+ it "should raise an exception when trying to set the command" do
+ expect { resource.command command }.to raise_error # FIXME: add a real error in Chef-13
+ end
+
+ it "should initialize the command to nil" do
+ expect(resource.command).to be_nil
+ end
+
+ describe "when the code is not present" do
+ let(:code) { nil }
+ it "raises an exception" do
+ expect { resource.run_action(:run) }.to raise_error # FIXME: add a real error in Chef-13
+ expect { resource.run_action(:run) }.not_to raise_error
+ end
+ end
+ end
+ end
+
+ it "times out when a timeout is set on the resource" do
+ resource.code 'sleep 600'
+ resource.timeout 0.1
+ expect { resource.run_action(:run) }.to raise_error(Mixlib::ShellOut::CommandTimeout)
+ end
+end
diff --git a/spec/functional/resource/deploy_revision_spec.rb b/spec/functional/resource/deploy_revision_spec.rb
index eae422ac1d..e5f5341fcd 100644
--- a/spec/functional/resource/deploy_revision_spec.rb
+++ b/spec/functional/resource/deploy_revision_spec.rb
@@ -45,11 +45,10 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
before(:all) do
@ohai = Ohai::System.new
- @ohai.all_plugins("os")
+ @ohai.all_plugins(["platform", "os"])
end
let(:node) do
-
Chef::Node.new.tap do |n|
n.name "rspec-test"
n.consume_external_attrs(@ohai.data, {})
@@ -173,12 +172,12 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
it "deploys the app to the target revision (#{target_rev_spec})" do
target_rev = send(target_rev_spec)
- File.should exist(rel_path("current"))
+ expect(File).to exist(rel_path("current"))
- actual_current_rev.should == target_rev
+ expect(actual_current_rev).to eq(target_rev)
# Is the app code actually there?
- File.should exist(rel_path("current/app/app.rb"))
+ expect(File).to exist(rel_path("current/app/app.rb"))
end
end
@@ -193,12 +192,12 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
the_app_is_deployed_at_revision(:latest_rev)
it "restarts the application" do
- File.should exist(rel_path("current/restart.txt"))
- actual_operations_order.should == %w[deploy_to_latest_rev]
+ expect(File).to exist(rel_path("current/restart.txt"))
+ expect(actual_operations_order).to eq(%w[deploy_to_latest_rev])
end
it "is marked as updated" do
- deploy_to_latest_rev.should be_updated_by_last_action
+ expect(deploy_to_latest_rev).to be_updated_by_last_action
end
end
@@ -215,15 +214,15 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
the_app_is_deployed_at_revision(:latest_rev)
it "restarts the application after rolling back" do
- actual_operations_order.should == %w[deploy_to_latest_rev deploy_to_previous_rev deploy_to_latest_rev_again]
+ expect(actual_operations_order).to eq(%w[deploy_to_latest_rev deploy_to_previous_rev deploy_to_latest_rev_again])
end
it "is marked updated" do
- deploy_to_latest_rev_again.should be_updated_by_last_action
+ expect(deploy_to_latest_rev_again).to be_updated_by_last_action
end
it "deploys the right code" do
- IO.read(rel_path("current/app/app.rb")).should include("this is the fourth version of the app")
+ expect(IO.read(rel_path("current/app/app.rb"))).to include("this is the fourth version of the app")
end
end
@@ -233,27 +232,27 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
end
it "creates the required directory tree" do
- File.should be_directory(rel_path("releases"))
- File.should be_directory(rel_path("shared"))
- File.should be_directory(rel_path("releases/#{latest_rev}"))
+ expect(File).to be_directory(rel_path("releases"))
+ expect(File).to be_directory(rel_path("shared"))
+ expect(File).to be_directory(rel_path("releases/#{latest_rev}"))
- File.should be_directory(rel_path("current/tmp"))
- File.should be_directory(rel_path("current/config"))
- File.should be_directory(rel_path("current/public"))
+ expect(File).to be_directory(rel_path("current/tmp"))
+ expect(File).to be_directory(rel_path("current/config"))
+ expect(File).to be_directory(rel_path("current/public"))
- File.should be_symlink(rel_path("current"))
- File.readlink(rel_path("current")).should == rel_path("releases/#{latest_rev}")
+ expect(File).to be_symlink(rel_path("current"))
+ expect(File.readlink(rel_path("current"))).to eq(rel_path("releases/#{latest_rev}"))
end
the_app_is_deployed_at_revision(:latest_rev)
it "restarts the application" do
- File.should exist(rel_path("current/restart.txt"))
- actual_operations_order.should == %w[deploy_to_latest_rev]
+ expect(File).to exist(rel_path("current/restart.txt"))
+ expect(actual_operations_order).to eq(%w[deploy_to_latest_rev])
end
it "is marked as updated" do
- deploy_to_latest_rev.should be_updated_by_last_action
+ expect(deploy_to_latest_rev).to be_updated_by_last_action
end
end
@@ -266,11 +265,11 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
the_app_is_deployed_at_revision(:latest_rev)
it "does not restart the app" do
- actual_operations_order.should == %w[deploy_to_latest_rev]
+ expect(actual_operations_order).to eq(%w[deploy_to_latest_rev])
end
it "is not marked updated" do
- deploy_to_latest_rev.should_not be_updated_by_last_action
+ expect(deploy_to_latest_rev).not_to be_updated_by_last_action
end
end
@@ -284,11 +283,11 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
the_app_is_deployed_at_revision(:latest_rev)
it "restarts the app" do
- actual_operations_order.should == %w[deploy_to_latest_rev deploy_to_latest_rev_again]
+ expect(actual_operations_order).to eq(%w[deploy_to_latest_rev deploy_to_latest_rev_again])
end
it "is marked updated" do
- deploy_to_latest_rev.should be_updated_by_last_action
+ expect(deploy_to_latest_rev).to be_updated_by_last_action
end
end
@@ -302,15 +301,15 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
the_app_is_deployed_at_revision(:latest_rev)
it "restarts the application after the new deploy" do
- actual_operations_order.should == %w[deploy_to_previous_rev deploy_to_latest_rev]
+ expect(actual_operations_order).to eq(%w[deploy_to_previous_rev deploy_to_latest_rev])
end
it "is marked updated" do
- deploy_to_previous_rev.should be_updated_by_last_action
+ expect(deploy_to_previous_rev).to be_updated_by_last_action
end
it "leaves the old copy of the app around for rollback" do
- File.should exist(File.join(deploy_directory, "releases", previous_rev))
+ expect(File).to exist(File.join(deploy_directory, "releases", previous_rev))
end
end
@@ -325,15 +324,15 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
the_app_is_deployed_at_revision(:latest_rev)
it "restarts the application after rolling back" do
- actual_operations_order.should == %w[deploy_to_latest_rev deploy_to_previous_rev deploy_to_latest_rev_again]
+ expect(actual_operations_order).to eq(%w[deploy_to_latest_rev deploy_to_previous_rev deploy_to_latest_rev_again])
end
it "is marked updated" do
- deploy_to_latest_rev_again.should be_updated_by_last_action
+ expect(deploy_to_latest_rev_again).to be_updated_by_last_action
end
it "deploys the right code" do
- IO.read(rel_path("current/app/app.rb")).should include("this is the fourth version of the app")
+ expect(IO.read(rel_path("current/app/app.rb"))).to include("this is the fourth version of the app")
end
end
@@ -350,31 +349,31 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
the_app_is_deployed_at_revision(:previous_rev)
it "restarts the application after rolling back" do
- actual_operations_order.should == %w[deploy_to_previous_rev deploy_to_latest_rev deploy_to_latest_rev_again]
+ expect(actual_operations_order).to eq(%w[deploy_to_previous_rev deploy_to_latest_rev deploy_to_latest_rev_again])
end
it "is marked updated" do
- deploy_to_latest_rev_again.should be_updated_by_last_action
+ expect(deploy_to_latest_rev_again).to be_updated_by_last_action
end
it "deploys the right code" do
- IO.read(rel_path("current/app/app.rb")).should include("this is the third version of the app")
+ expect(IO.read(rel_path("current/app/app.rb"))).to include("this is the third version of the app")
end
it "all_releases after first deploy should have one entry" do
- @previous_rev_all_releases.length.should == 1
+ expect(@previous_rev_all_releases.length).to eq(1)
end
it "all_releases after second deploy should have two entries" do
- @latest_rev_all_releases.length.should == 2
+ expect(@latest_rev_all_releases.length).to eq(2)
end
it "all_releases after rollback should have one entry" do
- @previous_rev_again_all_releases.length.should == 1
+ expect(@previous_rev_again_all_releases.length).to eq(1)
end
it "all_releases after rollback should be the same as after the first deploy" do
- @previous_rev_again_all_releases.should == @previous_rev_all_releases
+ expect(@previous_rev_again_all_releases).to eq(@previous_rev_all_releases)
end
end
@@ -393,31 +392,31 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
the_app_is_deployed_at_revision(:previous_rev)
it "restarts the application after rolling back" do
- actual_operations_order.should == %w[deploy_to_previous_rev deploy_to_latest_rev deploy_to_previous_rev_again]
+ expect(actual_operations_order).to eq(%w[deploy_to_previous_rev deploy_to_latest_rev deploy_to_previous_rev_again])
end
it "is marked updated" do
- deploy_to_previous_rev_again.should be_updated_by_last_action
+ expect(deploy_to_previous_rev_again).to be_updated_by_last_action
end
it "deploys the right code" do
- IO.read(rel_path("current/app/app.rb")).should include("this is the third version of the app")
+ expect(IO.read(rel_path("current/app/app.rb"))).to include("this is the third version of the app")
end
it "all_releases after first deploy should have one entry" do
- @previous_rev_all_releases.length.should == 1
+ expect(@previous_rev_all_releases.length).to eq(1)
end
it "all_releases after second deploy should have two entries" do
- @latest_rev_all_releases.length.should == 2
+ expect(@latest_rev_all_releases.length).to eq(2)
end
it "all_releases after rollback should have one entry" do
- @previous_rev_again_all_releases.length.should == 1
+ expect(@previous_rev_again_all_releases.length).to eq(1)
end
it "all_releases after rollback should be the same as after the first deploy" do
- @previous_rev_again_all_releases.should == @previous_rev_all_releases
+ expect(@previous_rev_again_all_releases).to eq(@previous_rev_all_releases)
end
end
@@ -438,23 +437,23 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
the_app_is_deployed_at_revision(:second_rev)
it "restarts the application after rolling back" do
- actual_operations_order.should == %w[deploy_to_second_rev deploy_to_previous_rev deploy_to_previous_rev_again deploy_to_latest_rev deploy_to_latest_rev_again]
+ expect(actual_operations_order).to eq(%w[deploy_to_second_rev deploy_to_previous_rev deploy_to_previous_rev_again deploy_to_latest_rev deploy_to_latest_rev_again])
end
it "is marked updated" do
- deploy_to_latest_rev_again.should be_updated_by_last_action
+ expect(deploy_to_latest_rev_again).to be_updated_by_last_action
end
it "deploys the right code" do
- IO.read(rel_path("current/app/app.rb")).should include("this is the second version of the app")
+ expect(IO.read(rel_path("current/app/app.rb"))).to include("this is the second version of the app")
end
it "all_releases after rollback should have one entry" do
- @fifth_deploy_all_releases.length.should == 1
+ expect(@fifth_deploy_all_releases.length).to eq(1)
end
it "all_releases after rollback should be the same as after the first deploy" do
- @fifth_deploy_all_releases.should == @first_deploy_all_releases
+ expect(@fifth_deploy_all_releases).to eq(@first_deploy_all_releases)
end
end
@@ -475,23 +474,23 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
the_app_is_deployed_at_revision(:second_rev)
it "restarts the application after rolling back" do
- actual_operations_order.should == %w[deploy_to_second_rev deploy_to_previous_rev deploy_to_second_rev_again deploy_to_latest_rev deploy_to_second_rev_again_again]
+ expect(actual_operations_order).to eq(%w[deploy_to_second_rev deploy_to_previous_rev deploy_to_second_rev_again deploy_to_latest_rev deploy_to_second_rev_again_again])
end
it "is marked updated" do
- deploy_to_second_rev_again_again.should be_updated_by_last_action
+ expect(deploy_to_second_rev_again_again).to be_updated_by_last_action
end
it "deploys the right code" do
- IO.read(rel_path("current/app/app.rb")).should include("this is the second version of the app")
+ expect(IO.read(rel_path("current/app/app.rb"))).to include("this is the second version of the app")
end
it "all_releases after rollback should have one entry" do
- @fifth_deploy_all_releases.length.should == 1
+ expect(@fifth_deploy_all_releases.length).to eq(1)
end
it "all_releases after rollback should be the same as after the first deploy" do
- @fifth_deploy_all_releases.should == @first_deploy_all_releases
+ expect(@fifth_deploy_all_releases).to eq(@first_deploy_all_releases)
end
end
@@ -510,21 +509,21 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
end
before do
- File.should_not exist(deploy_directory)
+ expect(File).not_to exist(deploy_directory)
deploy_to_latest_rev.run_action(:deploy)
end
it "creates the required directory tree" do
- File.should be_directory(rel_path("releases"))
- File.should be_directory(rel_path("shared"))
- File.should be_directory(rel_path("releases/#{latest_rev}"))
+ expect(File).to be_directory(rel_path("releases"))
+ expect(File).to be_directory(rel_path("shared"))
+ expect(File).to be_directory(rel_path("releases/#{latest_rev}"))
- File.should be_directory(rel_path("current/tmp"))
- File.should be_directory(rel_path("current/config"))
- File.should be_directory(rel_path("current/public"))
+ expect(File).to be_directory(rel_path("current/tmp"))
+ expect(File).to be_directory(rel_path("current/config"))
+ expect(File).to be_directory(rel_path("current/public"))
- File.should be_symlink(rel_path("current"))
- File.readlink(rel_path("current")).should == rel_path("releases/#{latest_rev}")
+ expect(File).to be_symlink(rel_path("current"))
+ expect(File.readlink(rel_path("current"))).to eq(rel_path("releases/#{latest_rev}"))
end
the_app_is_deployed_at_revision(:latest_rev)
@@ -599,18 +598,18 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
the_app_is_deployed_at_revision(:latest_rev)
it "is marked updated" do
- deploy_to_latest_with_inline_recipes.should be_updated_by_last_action
+ expect(deploy_to_latest_with_inline_recipes).to be_updated_by_last_action
end
it "calls the callbacks in order" do
- callback_order.should == [:before_migrate, :before_symlink, :before_restart, :after_restart]
+ expect(callback_order).to eq([:before_migrate, :before_symlink, :before_restart, :after_restart])
end
it "runs chef resources in the callbacks" do
- File.should exist(rel_path("current/before_migrate.txt"))
- File.should exist(rel_path("current/before_symlink.txt"))
- File.should exist(rel_path("current/tmp/before_restart.txt"))
- File.should exist(rel_path("current/tmp/after_restart.txt"))
+ expect(File).to exist(rel_path("current/before_migrate.txt"))
+ expect(File).to exist(rel_path("current/before_symlink.txt"))
+ expect(File).to exist(rel_path("current/tmp/before_restart.txt"))
+ expect(File).to exist(rel_path("current/tmp/after_restart.txt"))
end
end
@@ -629,10 +628,10 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
the_app_is_deployed_at_revision(:rev_with_in_repo_callbacks)
it "runs chef resources in the callbacks" do
- File.should exist(rel_path("current/before_migrate.txt"))
- File.should exist(rel_path("current/before_symlink.txt"))
- File.should exist(rel_path("current/tmp/before_restart.txt"))
- File.should exist(rel_path("current/tmp/after_restart.txt"))
+ expect(File).to exist(rel_path("current/before_migrate.txt"))
+ expect(File).to exist(rel_path("current/before_symlink.txt"))
+ expect(File).to exist(rel_path("current/tmp/before_restart.txt"))
+ expect(File).to exist(rel_path("current/tmp/after_restart.txt"))
end
end
@@ -690,7 +689,7 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
end
it "runs migrations in between the before_migrate and before_symlink steps" do
- actual_operations_order.should == %w[before_migrate migration before_symlink before_restart after_restart]
+ expect(actual_operations_order).to eq(%w[before_migrate migration before_symlink before_restart after_restart])
end
end
@@ -703,7 +702,7 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
end
it "should not raise an exception calling File.utime on symlinks" do
- lambda { deploy_with_in_repo_symlinks.run_action(:deploy) }.should_not raise_error
+ expect { deploy_with_in_repo_symlinks.run_action(:deploy) }.not_to raise_error
end
end
@@ -712,16 +711,16 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
shared_examples_for "a redeployed application" do
it "should redeploy the application" do
- File.should be_directory(rel_path("releases"))
- File.should be_directory(rel_path("shared"))
- File.should be_directory(rel_path("releases/#{latest_rev}"))
+ expect(File).to be_directory(rel_path("releases"))
+ expect(File).to be_directory(rel_path("shared"))
+ expect(File).to be_directory(rel_path("releases/#{latest_rev}"))
- File.should be_directory(rel_path("current/tmp"))
- File.should be_directory(rel_path("current/config"))
- File.should be_directory(rel_path("current/public"))
+ expect(File).to be_directory(rel_path("current/tmp"))
+ expect(File).to be_directory(rel_path("current/config"))
+ expect(File).to be_directory(rel_path("current/public"))
- File.should be_symlink(rel_path("current"))
- File.readlink(rel_path("current")).should == rel_path("releases/#{latest_rev}")
+ expect(File).to be_symlink(rel_path("current"))
+ expect(File.readlink(rel_path("current"))).to eq(rel_path("releases/#{latest_rev}"))
end
end
@@ -758,23 +757,23 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
shared_examples_for "a recovered deployment" do
it "should redeploy the application" do
- File.should be_directory(rel_path("releases"))
- File.should be_directory(rel_path("shared"))
- File.should be_directory(rel_path("releases/#{latest_rev}"))
+ expect(File).to be_directory(rel_path("releases"))
+ expect(File).to be_directory(rel_path("shared"))
+ expect(File).to be_directory(rel_path("releases/#{latest_rev}"))
- File.should be_directory(rel_path("current/tmp"))
- File.should be_directory(rel_path("current/config"))
- File.should be_directory(rel_path("current/public"))
+ expect(File).to be_directory(rel_path("current/tmp"))
+ expect(File).to be_directory(rel_path("current/config"))
+ expect(File).to be_directory(rel_path("current/public"))
- File.should be_symlink(rel_path("current"))
- File.readlink(rel_path("current")).should == rel_path("releases/#{latest_rev}")
+ expect(File).to be_symlink(rel_path("current"))
+ expect(File.readlink(rel_path("current"))).to eq(rel_path("releases/#{latest_rev}"))
# if callbacks ran, we know the app was deployed and not merely rolled
# back to a (busted) prior deployment.
- callback_order.should == [:before_migrate,
+ expect(callback_order).to eq([:before_migrate,
:before_symlink,
:before_restart,
- :after_restart ]
+ :after_restart ])
end
end
@@ -794,7 +793,7 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
context "in the `#{callback}' callback" do
before do
- lambda { deploy_that_fails.run_action(:deploy) }.should raise_error(Exception, %r{I am a failed deploy})
+ expect { deploy_that_fails.run_action(:deploy) }.to raise_error(Exception, %r{I am a failed deploy})
deploy_to_latest_with_callback_tracking.run_action(:deploy)
end
@@ -820,7 +819,7 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
end
before do
- lambda { deploy_that_fails.run_action(:deploy) }.should raise_error(Chef::Exceptions::Exec)
+ expect { deploy_that_fails.run_action(:deploy) }.to raise_error(Chef::Exceptions::Exec)
deploy_to_latest_with_callback_tracking.run_action(:deploy)
end
@@ -852,7 +851,7 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
end
before do
- lambda { deploy_that_fails.run_action(:deploy) }.should raise_error(RuntimeError, /network error/)
+ expect { deploy_that_fails.run_action(:deploy) }.to raise_error(RuntimeError, /network error/)
deploy_to_latest_with_callback_tracking.run_action(:deploy)
end
@@ -868,12 +867,12 @@ describe Chef::Resource::DeployRevision, :unix_only => true do
end
before do
- lambda { deploy_that_fails.run_action(:deploy) }.should raise_error(Exception, %r{I am a failed deploy})
+ expect { deploy_that_fails.run_action(:deploy) }.to raise_error(Exception, %r{I am a failed deploy})
deploy_to_latest_rev.run_action(:deploy)
end
it "removes the unsuccessful deploy after a later successful deploy" do
- ::File.should_not exist(File.join(deploy_directory, "releases", previous_rev))
+ expect(::File).not_to exist(File.join(deploy_directory, "releases", previous_rev))
end
end
diff --git a/spec/functional/resource/env_spec.rb b/spec/functional/resource/env_spec.rb
index 8178eeba3d..16caec14bf 100755
--- a/spec/functional/resource/env_spec.rb
+++ b/spec/functional/resource/env_spec.rb
@@ -131,12 +131,12 @@ describe Chef::Resource::Env, :windows_only do
let!(:env_path_before) { ENV['PATH'] }
it 'should expand PATH' do
- path_before.should_not include(env_val)
+ expect(path_before).not_to include(env_val)
test_resource.key_name('PATH')
test_resource.value("#{path_before};#{env_val}")
test_resource.run_action(:create)
- ENV['PATH'].should_not include(env_val)
- ENV['PATH'].should include("#{random_name}")
+ expect(ENV['PATH']).not_to include(env_val)
+ expect(ENV['PATH']).to include("#{random_name}")
end
after(:each) do
diff --git a/spec/functional/resource/execute_spec.rb b/spec/functional/resource/execute_spec.rb
index ff358fe045..aaa1c772b7 100644
--- a/spec/functional/resource/execute_spec.rb
+++ b/spec/functional/resource/execute_spec.rb
@@ -18,96 +18,130 @@
require 'spec_helper'
require 'functional/resource/base'
+require 'timeout'
describe Chef::Resource::Execute do
- let(:execute_resource) {
- exec_resource = Chef::Resource::Execute.new("foo_resource", run_context)
-
- exec_resource.environment(resource_environment) if resource_environment
- exec_resource.cwd(resource_cwd) if resource_cwd
- exec_resource.command("echo hello")
- if guard
- if guard_options
- exec_resource.only_if(guard, guard_options)
- else
- exec_resource.only_if(guard)
- end
- end
- exec_resource
+ let(:resource) {
+ resource = Chef::Resource::Execute.new("foo_resource", run_context)
+ resource.command("echo hello")
+ resource
}
- let(:resource_environment) { nil }
- let(:resource_cwd) { nil }
- let(:guard) { nil }
- let(:guard_options) { nil }
-
describe "when guard is ruby block" do
it "guard can still run" do
- execute_resource.only_if do
- true
- end
- execute_resource.run_action(:run)
- execute_resource.should be_updated_by_last_action
+ resource.only_if { true }
+ resource.run_action(:run)
+ expect(resource).to be_updated_by_last_action
end
end
- describe "when parent resource sets :cwd" do
- let(:resource_cwd) { CHEF_SPEC_DATA }
+ describe "when why_run is enabled" do
+ before do
+ Chef::Config[:why_run] = true
+ end
+
+ let(:guard) { "ruby -e 'exit 0'" }
+ let!(:guard_resource) {
+ interpreter = Chef::GuardInterpreter::ResourceGuardInterpreter.new(resource, guard, nil)
+ interpreter.send(:get_interpreter_resource, resource)
+ }
+
+ 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)
+
+ # why_run mode doesn't disable the updated_by_last_action logic, so we really have to look at the provider action
+ # to see if why_run correctly disabled the resource. It should shell_out! for the guard but not the resource.
+ expect_any_instance_of(Chef::Provider::Execute).to receive(:shell_out!).once
+ resource.only_if guard
+ resource.run_action(:run)
+
+ expect(resource).to be_updated_by_last_action
+ expect(guard_resource).to be_updated_by_last_action
+ end
+ end
+
+ describe "when parent resource sets :cwd" do
let(:guard) { %{ruby -e 'exit 1 unless File.exists?("./big_json_plus_one.json")'} }
- it "guard inherits :cwd from resource" do
- execute_resource.run_action(:run)
- execute_resource.should be_updated_by_last_action
+ it "guard inherits :cwd from resource and runs" do
+ resource.cwd CHEF_SPEC_DATA
+ resource.only_if guard
+ resource.run_action(:run)
+ expect(resource).to be_updated_by_last_action
+ end
+
+ it "guard inherits :cwd from resource and does not run" do
+ resource.cwd CHEF_SPEC_DATA
+ resource.not_if guard
+ resource.run_action(:run)
+ expect(resource).not_to be_updated_by_last_action
end
end
+ # We use ruby command so that we don't need to deal with platform specific
+ # commands while testing execute resource. We set it so that the resource
+ # will be updated if the ENV variable is set to what we are intending
+ #
+ # FIXME: yeah, but invoking ruby is slow...
describe "when parent resource sets :environment" do
- let(:resource_environment) do
- {
+ before do
+ resource.environment({
"SAWS_SECRET" => "supersecret",
- "SAWS_KEY" => "qwerty"
- }
+ "SAWS_KEY" => "qwerty",
+ })
end
- # We use ruby command so that we don't need to deal with platform specific
- # commands while testing execute resource. We set it so that the resource
- # will be updated if the ENV variable is set to what we are intending
- let(:guard) { %{ruby -e 'exit 1 if ENV["SAWS_SECRET"] != "supersecret"'} }
-
- it "guard inherits :environment value from resource" do
- execute_resource.run_action(:run)
- execute_resource.should be_updated_by_last_action
+ it "guard inherits :environment value from resource and runs" do
+ resource.only_if %{ruby -e 'exit 1 if ENV["SAWS_SECRET"] != "supersecret"'}
+ resource.run_action(:run)
+ expect(resource).to be_updated_by_last_action
end
- describe "when guard sets additional values in the :environment" do
- let(:guard) { %{ruby -e 'exit 1 if ENV["SGCE_SECRET"] != "regularsecret"'} }
+ it "guard inherits :environment value from resource and does not run" do
+ resource.only_if %{ruby -e 'exit 1 if ENV["SAWS_SECRET"] == "supersecret"'}
+ resource.run_action(:run)
+ expect(resource).not_to be_updated_by_last_action
+ end
- let(:guard_options) do
- {
- :environment => { 'SGCE_SECRET' => "regularsecret" }
- }
- end
+ it "guard adds additional values in its :environment and runs" do
+ resource.only_if %{ruby -e 'exit 1 if ENV["SGCE_SECRET"] != "regularsecret"'}, {
+ :environment => { 'SGCE_SECRET' => "regularsecret" }
+ }
+ resource.run_action(:run)
+ expect(resource).to be_updated_by_last_action
+ end
- it "guard sees merged value for in its ENV" do
- execute_resource.run_action(:run)
- execute_resource.should be_updated_by_last_action
- end
+ it "guard adds additional values in its :environment and does not run" do
+ resource.only_if %{ruby -e 'exit 1 if ENV["SGCE_SECRET"] == "regularsecret"'}, {
+ :environment => { 'SGCE_SECRET' => "regularsecret" }
+ }
+ resource.run_action(:run)
+ expect(resource).not_to be_updated_by_last_action
end
- describe "when guard sets same value in the :environment" do
- let(:guard) { %{ruby -e 'exit 1 if ENV["SAWS_SECRET"] != "regularsecret"'} }
+ it "guard overwrites value with its :environment and runs" do
+ resource.only_if %{ruby -e 'exit 1 if ENV["SAWS_SECRET"] != "regularsecret"'}, {
+ :environment => { 'SAWS_SECRET' => "regularsecret" }
+ }
+ resource.run_action(:run)
+ expect(resource).to be_updated_by_last_action
+ end
- let(:guard_options) do
- {
- :environment => { 'SAWS_SECRET' => "regularsecret" }
- }
- end
+ it "guard overwrites value with its :environment and does not runs" do
+ resource.only_if %{ruby -e 'exit 1 if ENV["SAWS_SECRET"] == "regularsecret"'}, {
+ :environment => { 'SAWS_SECRET' => "regularsecret" }
+ }
+ resource.run_action(:run)
+ expect(resource).not_to be_updated_by_last_action
+ end
+ end
- it "guard sees value from guard options in its ENV" do
- execute_resource.run_action(:run)
- execute_resource.should be_updated_by_last_action
- end
+ it "times out when a timeout is set on the resource" do
+ Timeout::timeout(5) do
+ resource.command %{ruby -e 'sleep 600'}
+ resource.timeout 0.1
+ expect { resource.run_action(:run) }.to raise_error(Mixlib::ShellOut::CommandTimeout)
end
end
end
diff --git a/spec/functional/resource/file_spec.rb b/spec/functional/resource/file_spec.rb
index 83f051ea06..cf70c349fb 100644
--- a/spec/functional/resource/file_spec.rb
+++ b/spec/functional/resource/file_spec.rb
@@ -77,11 +77,11 @@ describe Chef::Resource::File do
context "and the target file does not exist" do
it "creates the file" do
- File.should exist(path)
+ expect(File).to exist(path)
end
it "is marked updated by last action" do
- resource_without_content.should be_updated_by_last_action
+ expect(resource_without_content).to be_updated_by_last_action
end
end
end
@@ -106,11 +106,11 @@ describe Chef::Resource::File do
end
it "it creates the file" do
- File.should exist(path)
+ expect(File).to exist(path)
end
it "is marked updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
@@ -128,15 +128,15 @@ describe Chef::Resource::File do
end
it "updates the mtime of the file" do
- File.stat(path).mtime.should > @expected_mtime
+ expect(File.stat(path).mtime).to be > @expected_mtime
end
it "does not change the content" do
- sha256_checksum(path).should == @expected_checksum
+ expect(sha256_checksum(path)).to eq(@expected_checksum)
end
it "is marked as updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
end
diff --git a/spec/functional/resource/git_spec.rb b/spec/functional/resource/git_spec.rb
index f0bd94b0c0..9d3b82f19e 100644
--- a/spec/functional/resource/git_spec.rb
+++ b/spec/functional/resource/git_spec.rb
@@ -92,7 +92,7 @@ E
before(:all) do
@ohai = Ohai::System.new
- @ohai.all_plugins("os")
+ @ohai.all_plugins(["platform", "os"])
end
context "working with pathes with special characters" do
@@ -130,10 +130,10 @@ E
it "checks out the revision pointed to by the tag commit, not the tag commit itself" do
basic_git_resource.run_action(:sync)
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
- head_rev.should == v1_commit
+ expect(head_rev).to eq(v1_commit)
# also verify the tag commit itself is what we expect as an extra sanity check
rev = shell_out!('git rev-parse v1.0.0', :cwd => deploy_directory, :returns => [0]).stdout.strip
- rev.should == v1_tag
+ expect(rev).to eq(v1_tag)
end
it "doesn't update if up-to-date" do
@@ -141,10 +141,10 @@ E
# properly to the pointed to commit.
basic_git_resource.run_action(:sync)
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
- head_rev.should == v1_commit
+ expect(head_rev).to eq(v1_commit)
copy_git_resource.run_action(:sync)
- copy_git_resource.should_not be_updated
+ expect(copy_git_resource).not_to be_updated
end
end
@@ -167,25 +167,25 @@ E
basic_git_resource.revision rev_foo
basic_git_resource.run_action(:sync)
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
- head_rev.should == rev_foo
+ expect(head_rev).to eq(rev_foo)
end
it "doesn't update if up-to-date" do
basic_git_resource.revision rev_foo
basic_git_resource.run_action(:sync)
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
- head_rev.should == rev_foo
+ expect(head_rev).to eq(rev_foo)
copy_git_resource.revision rev_foo
copy_git_resource.run_action(:sync)
- copy_git_resource.should_not be_updated
+ expect(copy_git_resource).not_to be_updated
end
it "checks out the expected revision 972d" do
basic_git_resource.revision rev_testing
basic_git_resource.run_action(:sync)
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
- head_rev.should == rev_testing
+ expect(head_rev).to eq(rev_testing)
end
end
@@ -200,7 +200,7 @@ E
it "checks out the expected revision" do
basic_git_resource.run_action(:sync)
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
- head_rev.should == rev_head
+ expect(head_rev).to eq(rev_head)
end
end
@@ -215,7 +215,7 @@ E
it "checks out HEAD as the default revision" do
basic_git_resource.run_action(:sync)
head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
- head_rev.should == rev_head
+ expect(head_rev).to eq(rev_head)
end
end
@@ -244,7 +244,7 @@ E
head_rev = shell_out!('git rev-parse HEAD',
:cwd => deploy_directory,
:returns => [0]).stdout.strip
- head_rev.should == rev_head
+ expect(head_rev).to eq(rev_head)
end
it "checks out the (master) HEAD revision when no revision is specified (ignores tag)" do
@@ -252,7 +252,7 @@ E
head_rev = shell_out!('git rev-parse HEAD',
:cwd => deploy_directory,
:returns => [0]).stdout.strip
- head_rev.should == rev_head
+ expect(head_rev).to eq(rev_head)
end
end
diff --git a/spec/functional/resource/group_spec.rb b/spec/functional/resource/group_spec.rb
index 9c14232071..6676aa32e9 100644
--- a/spec/functional/resource/group_spec.rb
+++ b/spec/functional/resource/group_spec.rb
@@ -19,12 +19,15 @@
require 'spec_helper'
require 'functional/resource/base'
+require 'chef/mixin/shell_out'
# Chef::Resource::Group are turned off on Mac OS X 10.6 due to caching
# issues around Etc.getgrnam() not picking up the group membership
# changes that are done on the system. Etc.endgrent is not functioning
# correctly on certain 10.6 boxes.
describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supported_on_mac_osx_106 do
+ include Chef::Mixin::ShellOut
+
def group_should_exist(group)
case ohai[:platform_family]
when "debian", "fedora", "rhel", "suse", "gentoo", "slackware", "arch"
@@ -108,7 +111,7 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte
temp_resource.append(true)
temp_resource.run_action(:modify)
members.each do |member|
- user_exist_in_group?(member).should == true
+ expect(user_exist_in_group?(member)).to eq(true)
end
end
@@ -119,7 +122,7 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte
temp_resource.run_action(:create)
group_should_exist(group_name)
included_members.each do |member|
- user_exist_in_group?(member).should == false
+ expect(user_exist_in_group?(member)).to eq(false)
end
end
@@ -149,8 +152,8 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte
it "should remove the existing users and add the new users to the group" do
group_resource.run_action(tested_action)
- user_exist_in_group?(spec_members[1]).should == true
- user_exist_in_group?(spec_members[0]).should == false
+ expect(user_exist_in_group?(spec_members[1])).to eq(true)
+ expect(user_exist_in_group?(spec_members[0])).to eq(false)
end
end
@@ -176,10 +179,10 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte
group_resource.run_action(tested_action)
included_members.each do |member|
- user_exist_in_group?(member).should == true
+ expect(user_exist_in_group?(member)).to eq(true)
end
excluded_members.each do |member|
- user_exist_in_group?(member).should == false
+ expect(user_exist_in_group?(member)).to eq(false)
end
end
@@ -192,10 +195,10 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte
group_resource.run_action(tested_action)
included_members.each do |member|
- user_exist_in_group?(member).should == true
+ expect(user_exist_in_group?(member)).to eq(true)
end
excluded_members.each do |member|
- user_exist_in_group?(member).should == false
+ expect(user_exist_in_group?(member)).to eq(false)
end
end
end
@@ -204,13 +207,13 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte
describe "when the users doesn't exist" do
describe "when append is not set" do
it "should raise an error" do
- lambda { @grp_resource.run_action(tested_action) }.should raise_error
+ expect { @grp_resource.run_action(tested_action) }.to raise_error
end
end
describe "when append is set" do
it "should raise an error" do
- lambda { @grp_resource.run_action(tested_action) }.should raise_error
+ expect { @grp_resource.run_action(tested_action) }.to raise_error
end
end
end
@@ -231,24 +234,24 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte
describe "when updating membership" do
it "raises an error for a non well-formed domain name" do
group_resource.members [invalid_domain_user_name]
- lambda { group_resource.run_action(tested_action) }.should raise_error Chef::Exceptions::Win32APIError
+ expect { group_resource.run_action(tested_action) }.to raise_error Chef::Exceptions::Win32APIError
end
it "raises an error for a nonexistent domain" do
group_resource.members [nonexistent_domain_user_name]
- lambda { group_resource.run_action(tested_action) }.should raise_error Chef::Exceptions::Win32APIError
+ expect { group_resource.run_action(tested_action) }.to raise_error Chef::Exceptions::Win32APIError
end
end
describe "when removing members" do
it "raises an error for a non well-formed domain name" do
group_resource.excluded_members [invalid_domain_user_name]
- lambda { group_resource.run_action(tested_action) }.should raise_error Chef::Exceptions::Win32APIError
+ expect { group_resource.run_action(tested_action) }.to raise_error Chef::Exceptions::Win32APIError
end
it "raises an error for a nonexistent domain" do
group_resource.excluded_members [nonexistent_domain_user_name]
- lambda { group_resource.run_action(tested_action) }.should raise_error Chef::Exceptions::Win32APIError
+ expect { group_resource.run_action(tested_action) }.to raise_error Chef::Exceptions::Win32APIError
end
end
end
@@ -264,7 +267,7 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte
}
it "append should be false by default" do
- group_resource.append.should == false
+ expect(group_resource.append).to eq(false)
end
describe "group create action" do
@@ -297,7 +300,7 @@ theoldmanwalkingdownthestreetalwayshadagoodsmileonhisfacetheoldmanwalking\
downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreeQQQQQQ" }
it "should not create a group" do
- lambda { group_resource.run_action(:create) }.should raise_error
+ expect { group_resource.run_action(:create) }.to raise_error
group_should_not_exist(group_name)
end
end
@@ -308,7 +311,7 @@ downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreeQQQQQQ" }
invalid_resource = group_resource.dup
invalid_resource.members(["Jack"])
invalid_resource.excluded_members(["Jack"])
- lambda { invalid_resource.run_action(:create)}.should raise_error(Chef::Exceptions::ConflictingMembersInGroup)
+ expect { invalid_resource.run_action(:create)}.to raise_error(Chef::Exceptions::ConflictingMembersInGroup)
end
end
end
@@ -342,7 +345,7 @@ downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreeQQQQQQ" }
describe "when there is no group" do
it "should raise an error" do
- lambda { group_resource.run_action(:modify) }.should raise_error
+ expect { group_resource.run_action(:modify) }.to raise_error
end
end
@@ -370,11 +373,11 @@ downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreeQQQQQQ" }
describe "when there is no group" do
it "raises an error on modify" do
- lambda { group_resource.run_action(:modify) }.should raise_error
+ expect { group_resource.run_action(:modify) }.to raise_error
end
it "does not raise an error on manage" do
- lambda { group_resource.run_action(:manage) }.should_not raise_error
+ expect { group_resource.run_action(:manage) }.not_to raise_error
end
end
@@ -399,15 +402,15 @@ downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreeQQQQQQ" }
let(:excluded_members) { ["Anthony"] }
it ":manage should raise an error" do
- lambda {group_resource.run_action(:manage) }.should raise_error
+ expect {group_resource.run_action(:manage) }.to raise_error
end
it ":modify should raise an error" do
- lambda {group_resource.run_action(:modify) }.should raise_error
+ expect {group_resource.run_action(:modify) }.to raise_error
end
it ":create should raise an error" do
- lambda {group_resource.run_action(:create) }.should raise_error
+ expect {group_resource.run_action(:create) }.to raise_error
end
end
@@ -419,11 +422,11 @@ downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreeQQQQQQ" }
end
it ":manage should raise an error" do
- lambda {group_resource.run_action(:manage) }.should raise_error
+ expect {group_resource.run_action(:manage) }.to raise_error
end
it ":modify should raise an error" do
- lambda {group_resource.run_action(:modify) }.should raise_error
+ expect {group_resource.run_action(:modify) }.to raise_error
end
end
end
diff --git a/spec/functional/resource/ifconfig_spec.rb b/spec/functional/resource/ifconfig_spec.rb
index c36288498b..9c613544ac 100644
--- a/spec/functional/resource/ifconfig_spec.rb
+++ b/spec/functional/resource/ifconfig_spec.rb
@@ -143,7 +143,7 @@ describe Chef::Resource::Ifconfig, :requires_root, :external => include_flag do
end
it "should disable interface (vip)" do
new_resource.run_action(:disable)
- new_resource.should be_updated_by_last_action
+ expect(new_resource).to be_updated_by_last_action
interface_should_not_exists(network_interface_alias(en0_interface_for_test))
end
end
@@ -155,7 +155,7 @@ describe Chef::Resource::Ifconfig, :requires_root, :external => include_flag do
end
it "should delete interface (vip)" do
new_resource.run_action(:delete)
- new_resource.should be_updated_by_last_action
+ expect(new_resource).to be_updated_by_last_action
interface_should_not_exists(network_interface_alias(en0_interface_for_test))
interface_persistence_should_not_exists(network_interface_alias(en0_interface_for_test))
end
diff --git a/spec/functional/resource/link_spec.rb b/spec/functional/resource/link_spec.rb
index 2b616408d0..d39a0c2ef6 100644
--- a/spec/functional/resource/link_spec.rb
+++ b/spec/functional/resource/link_spec.rb
@@ -123,8 +123,8 @@ describe Chef::Resource::Link do
describe "when supported on platform", :not_supported_on_win2k3 do
shared_examples_for 'delete errors out' do
it 'delete errors out' do
- lambda { resource.run_action(:delete) }.should raise_error(Chef::Exceptions::Link)
- (File.exist?(target_file) || symlink?(target_file)).should be_true
+ expect { resource.run_action(:delete) }.to raise_error(Chef::Exceptions::Link)
+ expect(File.exist?(target_file) || symlink?(target_file)).to be_truthy
end
end
@@ -132,19 +132,19 @@ describe Chef::Resource::Link do
describe 'the :delete action' do
before(:each) do
@info = []
- Chef::Log.stub(:info) { |msg| @info << msg }
+ allow(Chef::Log).to receive(:info) { |msg| @info << msg }
resource.run_action(:delete)
end
it 'leaves the file deleted' do
- File.exist?(target_file).should be_false
- symlink?(target_file).should be_false
+ expect(File.exist?(target_file)).to be_falsey
+ expect(symlink?(target_file)).to be_falsey
end
it 'does not mark the resource updated' do
- resource.should_not be_updated
+ expect(resource).not_to be_updated
end
it 'does not log that it deleted' do
- @info.include?("link[#{target_file}] deleted").should be_false
+ expect(@info.include?("link[#{target_file}] deleted")).to be_falsey
end
end
end
@@ -153,19 +153,19 @@ describe Chef::Resource::Link do
describe 'the :delete action' do
before(:each) do
@info = []
- Chef::Log.stub(:info) { |msg| @info << msg }
+ allow(Chef::Log).to receive(:info) { |msg| @info << msg }
resource.run_action(:delete)
end
it 'deletes the file' do
- File.exist?(target_file).should be_false
- symlink?(target_file).should be_false
+ expect(File.exist?(target_file)).to be_falsey
+ expect(symlink?(target_file)).to be_falsey
end
it 'marks the resource updated' do
- resource.should be_updated
+ expect(resource).to be_updated
end
it 'logs that it deleted' do
- @info.include?("link[#{target_file}] deleted").should be_true
+ expect(@info.include?("link[#{target_file}] deleted")).to be_truthy
end
end
end
@@ -174,19 +174,19 @@ describe Chef::Resource::Link do
describe 'the :create action' do
before(:each) do
@info = []
- Chef::Log.stub(:info) { |msg| @info << msg }
+ allow(Chef::Log).to receive(:info) { |msg| @info << msg }
resource.run_action(:create)
end
it 'links to the target file' do
- expect(symlink?(target_file)).to be_true
+ expect(symlink?(target_file)).to be_truthy
expect(readlink(target_file)).to eq(canonicalize(to))
end
it 'marks the resource updated' do
- resource.should be_updated
+ expect(resource).to be_updated
end
it 'logs that it created' do
- @info.include?("link[#{target_file}] created").should be_true
+ expect(@info.include?("link[#{target_file}] created")).to be_truthy
end
end
end
@@ -195,19 +195,19 @@ describe Chef::Resource::Link do
describe 'the :create action' do
before(:each) do
@info = []
- Chef::Log.stub(:info) { |msg| @info << msg }
+ allow(Chef::Log).to receive(:info) { |msg| @info << msg }
resource.run_action(:create)
end
it 'leaves the file linked' do
- expect(symlink?(target_file)).to be_true
+ expect(symlink?(target_file)).to be_truthy
expect(readlink(target_file)).to eq(canonicalize(to))
end
it 'does not mark the resource updated' do
- resource.should_not be_updated
+ expect(resource).not_to be_updated
end
it 'does not log that it created' do
- @info.include?("link[#{target_file}] created").should be_false
+ expect(@info.include?("link[#{target_file}] created")).to be_falsey
end
end
end
@@ -216,23 +216,23 @@ describe Chef::Resource::Link do
describe 'the :create action' do
before(:each) do
@info = []
- Chef::Log.stub(:info) { |msg| @info << msg }
+ allow(Chef::Log).to receive(:info) { |msg| @info << msg }
resource.run_action(:create)
end
it 'preserves the hard link' do
- File.exists?(target_file).should be_true
- symlink?(target_file).should be_false
+ expect(File.exists?(target_file)).to be_truthy
+ expect(symlink?(target_file)).to be_falsey
# Writing to one hardlinked file should cause both
# to have the new value.
- IO.read(to).should == IO.read(target_file)
+ expect(IO.read(to)).to eq(IO.read(target_file))
File.open(to, "w") { |file| file.write('wowzers') }
- IO.read(target_file).should == 'wowzers'
+ expect(IO.read(target_file)).to eq('wowzers')
end
it 'marks the resource updated' do
- resource.should be_updated
+ expect(resource).to be_updated
end
it 'logs that it created' do
- @info.include?("link[#{target_file}] created").should be_true
+ expect(@info.include?("link[#{target_file}] created")).to be_truthy
end
end
end
@@ -241,23 +241,23 @@ describe Chef::Resource::Link do
describe 'the :create action' do
before(:each) do
@info = []
- Chef::Log.stub(:info) { |msg| @info << msg }
+ allow(Chef::Log).to receive(:info) { |msg| @info << msg }
resource.run_action(:create)
end
it 'links to the target file' do
- File.exists?(target_file).should be_true
- symlink?(target_file).should be_false
+ expect(File.exists?(target_file)).to be_truthy
+ expect(symlink?(target_file)).to be_falsey
# Writing to one hardlinked file should cause both
# to have the new value.
- IO.read(to).should == IO.read(target_file)
+ expect(IO.read(to)).to eq(IO.read(target_file))
File.open(to, "w") { |file| file.write('wowzers') }
- IO.read(target_file).should == 'wowzers'
+ expect(IO.read(target_file)).to eq('wowzers')
end
it 'does not mark the resource updated' do
- resource.should_not be_updated
+ expect(resource).not_to be_updated
end
it 'does not log that it created' do
- @info.include?("link[#{target_file}] created").should be_false
+ expect(@info.include?("link[#{target_file}] created")).to be_falsey
end
end
end
@@ -278,14 +278,14 @@ describe Chef::Resource::Link do
context 'pointing at the target' do
before(:each) do
symlink(to, target_file)
- expect(symlink?(target_file)).to be_true
+ expect(symlink?(target_file)).to be_truthy
expect(readlink(target_file)).to eq(canonicalize(to))
end
include_context 'create symbolic link is noop'
include_context 'delete succeeds'
it 'the :delete action does not delete the target file' do
resource.run_action(:delete)
- File.exists?(to).should be_true
+ expect(File.exists?(to)).to be_truthy
end
end
context 'pointing somewhere else' do
@@ -293,7 +293,7 @@ describe Chef::Resource::Link do
@other_target = File.join(test_file_dir, make_tmpname('other_spec'))
File.open(@other_target, 'w') { |file| file.write('eek') }
symlink(@other_target, target_file)
- expect(symlink?(target_file)).to be_true
+ expect(symlink?(target_file)).to be_truthy
expect(readlink(target_file)).to eq(canonicalize(@other_target))
end
after(:each) do
@@ -303,14 +303,14 @@ describe Chef::Resource::Link do
include_context 'delete succeeds'
it 'the :delete action does not delete the target file' do
resource.run_action(:delete)
- File.exists?(to).should be_true
+ expect(File.exists?(to)).to be_truthy
end
end
context 'pointing nowhere' do
before(:each) do
nonexistent = File.join(test_file_dir, make_tmpname('nonexistent_spec'))
symlink(nonexistent, target_file)
- expect(symlink?(target_file)).to be_true
+ expect(symlink?(target_file)).to be_truthy
expect(readlink(target_file)).to eq(canonicalize(nonexistent))
end
include_context 'create symbolic link succeeds'
@@ -320,8 +320,8 @@ describe Chef::Resource::Link do
context 'and the link already exists and is a hard link to the file' do
before(:each) do
link(to, target_file)
- File.exists?(target_file).should be_true
- symlink?(target_file).should be_false
+ expect(File.exists?(target_file)).to be_truthy
+ expect(symlink?(target_file)).to be_falsey
end
include_context 'create symbolic link succeeds'
it_behaves_like 'delete errors out'
@@ -339,16 +339,16 @@ describe Chef::Resource::Link do
end
it 'create errors out' do
if windows?
- lambda { resource.run_action(:create) }.should raise_error(Errno::EACCES)
+ expect { resource.run_action(:create) }.to raise_error(Errno::EACCES)
elsif os_x? or solaris? or freebsd? or aix?
- lambda { resource.run_action(:create) }.should raise_error(Errno::EPERM)
+ expect { resource.run_action(:create) }.to raise_error(Errno::EPERM)
else
- lambda { resource.run_action(:create) }.should raise_error(Errno::EISDIR)
+ expect { resource.run_action(:create) }.to raise_error(Errno::EISDIR)
end
end
it_behaves_like 'delete errors out'
end
- context 'and the link already exists and is not writeable to this user', :pending do
+ context 'and the link already exists and is not writeable to this user', :skip => true do
end
it_behaves_like 'a securable resource without existing target' do
let(:path) { target_file }
@@ -392,7 +392,7 @@ describe Chef::Resource::Link do
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
File.open(@other_target, "w") { |file| file.write("eek") }
symlink(@other_target, to)
- expect(symlink?(to)).to be_true
+ expect(symlink?(to)).to be_truthy
expect(readlink(to)).to eq(canonicalize(@other_target))
end
after(:each) do
@@ -407,7 +407,7 @@ describe Chef::Resource::Link do
before(:each) do
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
symlink(@other_target, to)
- expect(symlink?(to)).to be_true
+ expect(symlink?(to)).to be_truthy
expect(readlink(to)).to eq(canonicalize(@other_target))
end
context 'and the link does not yet exist' do
@@ -416,7 +416,7 @@ describe Chef::Resource::Link do
end
end
end
- context "when the link destination is not readable to this user", :pending do
+ context "when the link destination is not readable to this user", :skip => true do
end
context "when the link destination does not exist" do
include_context 'create symbolic link succeeds'
@@ -440,7 +440,7 @@ describe Chef::Resource::Link do
context 'when the link already exists and points at the target' do
before(:each) do
symlink(to, target_file)
- expect(symlink?(target_file)).to be_true
+ expect(symlink?(target_file)).to be_truthy
expect(readlink(target_file)).to eq(canonicalize(to))
end
include_context 'create symbolic link is noop'
@@ -449,7 +449,7 @@ describe Chef::Resource::Link do
context 'when the link already exists and points at the target with an absolute path' do
before(:each) do
symlink(absolute_to, target_file)
- expect(symlink?(target_file)).to be_true
+ expect(symlink?(target_file)).to be_truthy
expect(readlink(target_file)).to eq(canonicalize(absolute_to))
end
include_context 'create symbolic link succeeds'
@@ -477,7 +477,7 @@ describe Chef::Resource::Link do
context "and the link already exists and is a symbolic link pointing at the same file" do
before(:each) do
symlink(to, target_file)
- expect(symlink?(target_file)).to be_true
+ expect(symlink?(target_file)).to be_truthy
expect(readlink(target_file)).to eq(canonicalize(to))
end
include_context 'create hard link succeeds'
@@ -486,14 +486,14 @@ describe Chef::Resource::Link do
context 'and the link already exists and is a hard link to the file' do
before(:each) do
link(to, target_file)
- File.exists?(target_file).should be_true
- symlink?(target_file).should be_false
+ expect(File.exists?(target_file)).to be_truthy
+ expect(symlink?(target_file)).to be_falsey
end
include_context 'create hard link is noop'
include_context 'delete succeeds'
it 'the :delete action does not delete the target file' do
resource.run_action(:delete)
- File.exists?(to).should be_true
+ expect(File.exists?(to)).to be_truthy
end
end
context "and the link already exists and is a file" do
@@ -509,16 +509,16 @@ describe Chef::Resource::Link do
end
it 'errors out' do
if windows?
- lambda { resource.run_action(:create) }.should raise_error(Errno::EACCES)
+ expect { resource.run_action(:create) }.to raise_error(Errno::EACCES)
elsif os_x? or solaris? or freebsd? or aix?
- lambda { resource.run_action(:create) }.should raise_error(Errno::EPERM)
+ expect { resource.run_action(:create) }.to raise_error(Errno::EPERM)
else
- lambda { resource.run_action(:create) }.should raise_error(Errno::EISDIR)
+ expect { resource.run_action(:create) }.to raise_error(Errno::EISDIR)
end
end
it_behaves_like 'delete errors out'
end
- context "and the link already exists and is not writeable to this user", :pending do
+ context "and the link already exists and is not writeable to this user", :skip => true do
end
context "and specifies security attributes" do
before(:each) do
@@ -527,9 +527,9 @@ describe Chef::Resource::Link do
it 'ignores them' do
resource.run_action(:create)
if windows?
- Chef::ReservedNames::Win32::Security.get_named_security_info(target_file).owner.should_not == SID.Guest
+ expect(Chef::ReservedNames::Win32::Security.get_named_security_info(target_file).owner).not_to eq(SID.Guest)
else
- File.lstat(target_file).uid.should_not == Etc.getpwnam('nobody').uid
+ expect(File.lstat(target_file).uid).not_to eq(Etc.getpwnam('nobody').uid)
end
end
end
@@ -540,7 +540,7 @@ describe Chef::Resource::Link do
end
context 'and the link does not yet exist' do
it 'create errors out' do
- lambda { resource.run_action(:create) }.should raise_error(windows? ? Chef::Exceptions::Win32APIError : Errno::EPERM)
+ expect { resource.run_action(:create) }.to raise_error(windows? ? Chef::Exceptions::Win32APIError : Errno::EPERM)
end
include_context 'delete is noop'
end
@@ -551,7 +551,7 @@ describe Chef::Resource::Link do
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
File.open(@other_target, "w") { |file| file.write("eek") }
symlink(@other_target, to)
- expect(symlink?(to)).to be_true
+ expect(symlink?(to)).to be_truthy
expect(readlink(to)).to eq(canonicalize(@other_target))
end
after(:each) do
@@ -560,10 +560,10 @@ describe Chef::Resource::Link do
context 'and the link does not yet exist' do
it 'links to the target file' do
resource.run_action(:create)
- File.exists?(target_file).should be_true
+ expect(File.exists?(target_file)).to be_truthy
# OS X gets angry about this sort of link. Bug in OS X, IMO.
pending('OS X/FreeBSD/AIX symlink? and readlink working on hard links to symlinks') if (os_x? or freebsd? or aix?)
- expect(symlink?(target_file)).to be_true
+ expect(symlink?(target_file)).to be_truthy
expect(readlink(target_file)).to eq(canonicalize(@other_target))
end
include_context 'delete is noop'
@@ -573,33 +573,32 @@ describe Chef::Resource::Link do
before(:each) do
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
symlink(@other_target, to)
- expect(symlink?(to)).to be_true
+ expect(symlink?(to)).to be_truthy
expect(readlink(to)).to eq(canonicalize(@other_target))
end
context 'and the link does not yet exist' do
it 'links to the target file' do
- pending('OS X/FreeBSD/AIX fails to create hardlinks to broken symlinks', :if => (os_x? or freebsd? or aix?)) do
- resource.run_action(:create)
- # Windows and Unix have different definitions of exists? here, and that's OK.
- if windows?
- File.exists?(target_file).should be_true
- else
- File.exists?(target_file).should be_false
- end
- expect(symlink?(target_file)).to be_true
- expect(readlink(target_file)).to eq(canonicalize(@other_target))
+ pending('OS X/FreeBSD/AIX fails to create hardlinks to broken symlinks') if (os_x? or freebsd? or 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(symlink?(target_file)).to be_truthy
+ expect(readlink(target_file)).to eq(canonicalize(@other_target))
end
include_context 'delete is noop'
end
end
end
- context "when the link destination is not readable to this user", :pending do
+ context "when the link destination is not readable to this user", :skip => true do
end
context "when the link destination does not exist" do
context 'and the link does not yet exist' do
it 'create errors out' do
- lambda { resource.run_action(:create) }.should raise_error(Errno::ENOENT)
+ expect { resource.run_action(:create) }.to raise_error(Errno::ENOENT)
end
include_context 'delete is noop'
end
@@ -609,7 +608,7 @@ describe Chef::Resource::Link do
describe "when not supported on platform", :win2k3_only do
it "raises error" do
- lambda {resource}.should raise_error(Chef::Exceptions::Win32APIFunctionNotImplemented)
+ expect {resource}.to raise_error(Chef::Exceptions::Win32APIFunctionNotImplemented)
end
end
end
diff --git a/spec/functional/resource/mount_spec.rb b/spec/functional/resource/mount_spec.rb
index 962c02670c..a016d12293 100644
--- a/spec/functional/resource/mount_spec.rb
+++ b/spec/functional/resource/mount_spec.rb
@@ -82,7 +82,7 @@ describe Chef::Resource::Mount, :requires_root, :external => include_flag do
end
def mount_should_not_exists(mount_point)
- shell_out("mount").stdout.should_not include(mount_point)
+ expect(shell_out("mount").stdout).not_to include(mount_point)
end
def unix_mount_config_file
@@ -106,7 +106,7 @@ describe Chef::Resource::Mount, :requires_root, :external => include_flag do
end
def mount_should_be_disabled(mount_point)
- shell_out("cat #{unix_mount_config_file}").stdout.should_not include("#{mount_point}:")
+ expect(shell_out("cat #{unix_mount_config_file}").stdout).not_to include("#{mount_point}:")
end
let(:new_resource) do
@@ -155,10 +155,10 @@ describe Chef::Resource::Mount, :requires_root, :external => include_flag do
describe "when the target state is a mounted filesystem" do
it "should mount the filesystem if it isn't mounted" do
- current_resource.enabled.should be_false
- current_resource.mounted.should be_false
+ expect(current_resource.enabled).to be_falsey
+ expect(current_resource.mounted).to be_falsey
new_resource.run_action(:mount)
- new_resource.should be_updated
+ expect(new_resource).to be_updated
mount_should_exist(new_resource.mount_point, new_resource.device)
end
end
diff --git a/spec/functional/resource/ohai_spec.rb b/spec/functional/resource/ohai_spec.rb
index b1e4891293..da47b9e140 100644
--- a/spec/functional/resource/ohai_spec.rb
+++ b/spec/functional/resource/ohai_spec.rb
@@ -42,7 +42,7 @@ describe Chef::Resource::Ohai do
sleep 1
ohai_resource.run_action(:reload)
- node[:uptime].should_not == initial_uptime
+ expect(node[:uptime]).not_to eq(initial_uptime)
end
end
diff --git a/spec/functional/resource/package_spec.rb b/spec/functional/resource/package_spec.rb
index 548db40e79..5c17ca0107 100644
--- a/spec/functional/resource/package_spec.rb
+++ b/spec/functional/resource/package_spec.rb
@@ -159,25 +159,25 @@ describe Chef::Resource::Package, metadata do
it "installs the package with action :install" do
package_resource.run_action(:install)
shell_out!("dpkg -l chef-integration-test")
- package_resource.should be_updated_by_last_action
+ expect(package_resource).to be_updated_by_last_action
end
it "installs the package for action :upgrade" do
package_resource.run_action(:upgrade)
shell_out!("dpkg -l chef-integration-test")
- package_resource.should be_updated_by_last_action
+ expect(package_resource).to be_updated_by_last_action
end
it "does nothing for action :remove" do
package_resource.run_action(:remove)
shell_out!("dpkg -l chef-integration-test", :returns => [1])
- package_resource.should_not be_updated_by_last_action
+ expect(package_resource).not_to be_updated_by_last_action
end
it "does nothing for action :purge" do
package_resource.run_action(:purge)
shell_out!("dpkg -l chef-integration-test", :returns => [1])
- package_resource.should_not be_updated_by_last_action
+ expect(package_resource).not_to be_updated_by_last_action
end
context "and a not-available package version is specified" do
@@ -221,8 +221,8 @@ describe Chef::Resource::Package, metadata do
it "preseeds the package, then installs it" do
package_resource.run_action(:install)
cmd = shell_out!("debconf-show chef-integration-test")
- cmd.stdout.should include('chef-integration-test/sample-var: "hello world"')
- package_resource.should be_updated_by_last_action
+ expect(cmd.stdout).to include('chef-integration-test/sample-var: "hello world"')
+ expect(package_resource).to be_updated_by_last_action
end
context "and the preseed file exists and is up-to-date" do
@@ -239,8 +239,8 @@ describe Chef::Resource::Package, metadata do
it "does not update the package configuration" do
package_resource.run_action(:install)
cmd = shell_out!("debconf-show chef-integration-test")
- cmd.stdout.should include('chef-integration-test/sample-var: INVALID')
- package_resource.should be_updated_by_last_action
+ expect(cmd.stdout).to include('chef-integration-test/sample-var: INVALID')
+ expect(package_resource).to be_updated_by_last_action
end
end
@@ -267,8 +267,8 @@ describe Chef::Resource::Package, metadata do
it "preseeds the package, then installs it" do
package_resource.run_action(:install)
cmd = shell_out!("debconf-show chef-integration-test")
- cmd.stdout.should include('chef-integration-test/sample-var: "FROM TEMPLATE"')
- package_resource.should be_updated_by_last_action
+ expect(cmd.stdout).to include('chef-integration-test/sample-var: "FROM TEMPLATE"')
+ expect(package_resource).to be_updated_by_last_action
end
context "with variables" do
@@ -283,8 +283,8 @@ describe Chef::Resource::Package, metadata do
it "preseeds the package, then installs it" do
package_resource.run_action(:install)
cmd = shell_out!("debconf-show chef-integration-test")
- cmd.stdout.should include('chef-integration-test/sample-var: "SUPPORTS VARIABLES"')
- package_resource.should be_updated_by_last_action
+ expect(cmd.stdout).to include('chef-integration-test/sample-var: "SUPPORTS VARIABLES"')
+ expect(package_resource).to be_updated_by_last_action
end
end
@@ -302,13 +302,13 @@ describe Chef::Resource::Package, metadata do
it "does nothing for action :install" do
package_resource.run_action(:install)
shell_out!("dpkg -l chef-integration-test", :returns => [0])
- package_resource.should_not be_updated_by_last_action
+ expect(package_resource).not_to be_updated_by_last_action
end
it "does nothing for action :upgrade" do
package_resource.run_action(:upgrade)
shell_out!("dpkg -l chef-integration-test", :returns => [0])
- package_resource.should_not be_updated_by_last_action
+ expect(package_resource).not_to be_updated_by_last_action
end
# Verify that the package is removed by running `dpkg -l PACKAGE`
@@ -328,7 +328,7 @@ describe Chef::Resource::Package, metadata do
pkg_check = shell_out!("dpkg -l chef-integration-test", :returns => [0,1])
if pkg_check.exitstatus == 0
- pkg_check.stdout.should =~ /un[\s]+chef-integration-test/
+ expect(pkg_check.stdout).to match(/un[\s]+chef-integration-test/)
end
end
@@ -336,13 +336,13 @@ describe Chef::Resource::Package, metadata do
it "removes the package for action :remove" do
package_resource.run_action(:remove)
pkg_should_be_removed
- package_resource.should be_updated_by_last_action
+ expect(package_resource).to be_updated_by_last_action
end
it "removes the package for action :purge" do
package_resource.run_action(:purge)
pkg_should_be_removed
- package_resource.should be_updated_by_last_action
+ expect(package_resource).to be_updated_by_last_action
end
end
@@ -356,14 +356,14 @@ describe Chef::Resource::Package, metadata do
it "does nothing for action :install" do
package_resource.run_action(:install)
shell_out!("dpkg -l chef-integration-test", :returns => [0])
- package_resource.should_not be_updated_by_last_action
+ expect(package_resource).not_to be_updated_by_last_action
end
it "upgrades the package for action :upgrade" do
package_resource.run_action(:upgrade)
dpkg_l = shell_out!("dpkg -l chef-integration-test", :returns => [0])
- dpkg_l.stdout.should =~ /chef\-integration\-test[\s]+1\.1\-1/
- package_resource.should be_updated_by_last_action
+ expect(dpkg_l.stdout).to match(/chef\-integration\-test[\s]+1\.1\-1/)
+ expect(package_resource).to be_updated_by_last_action
end
context "and the resource specifies the new version" do
@@ -376,8 +376,8 @@ describe Chef::Resource::Package, metadata do
it "upgrades the package for action :install" do
package_resource.run_action(:install)
dpkg_l = shell_out!("dpkg -l chef-integration-test", :returns => [0])
- dpkg_l.stdout.should =~ /chef\-integration\-test[\s]+1\.1\-1/
- package_resource.should be_updated_by_last_action
+ expect(dpkg_l.stdout).to match(/chef\-integration\-test[\s]+1\.1\-1/)
+ expect(package_resource).to be_updated_by_last_action
end
end
diff --git a/spec/functional/resource/powershell_spec.rb b/spec/functional/resource/powershell_spec.rb
index e1e9f787a3..1b3ac844e0 100644
--- a/spec/functional/resource/powershell_spec.rb
+++ b/spec/functional/resource/powershell_spec.rb
@@ -56,6 +56,21 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
resource.run_action(:run)
end
+ it "returns the -27 for a powershell script that exits with -27" do
+ file = Tempfile.new(['foo', '.ps1'])
+ begin
+ file.write "exit -27"
+ file.close
+ resource.code(". \"#{file.path}\"")
+ resource.returns(-27)
+ resource.run_action(:run)
+ ensure
+ file.close
+ file.unlink
+ end
+ end
+
+
it "returns the process exit code" do
resource.code(arbitrary_nonzero_process_exit_code_content)
resource.returns(arbitrary_nonzero_process_exit_code)
@@ -153,7 +168,7 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
detected_64_bit = source_contains_case_insensitive_content?( get_script_output, 'AMD64' )
- is_64_bit.should == detected_64_bit
+ expect(is_64_bit).to eq(detected_64_bit)
end
it "returns 1 if an invalid flag is passed to the interpreter" do
@@ -186,12 +201,12 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
resource.returns(0)
resource.run_action(:run)
- source_contains_case_insensitive_content?( get_script_output, 'x86' ).should == true
+ expect(source_contains_case_insensitive_content?( get_script_output, 'x86' )).to eq(true)
end
it "raises an exception if :x86_64 process architecture is specified" do
begin
- resource.architecture(:x86_64).should raise_error Chef::Exceptions::Win32ArchitectureIncorrect
+ expect(resource.architecture(:x86_64)).to raise_error Chef::Exceptions::Win32ArchitectureIncorrect
rescue Chef::Exceptions::Win32ArchitectureIncorrect
end
end
@@ -204,7 +219,7 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
resource.returns(0)
resource.run_action(:run)
- source_contains_case_insensitive_content?( get_script_output, 'AMD64' ).should == true
+ expect(source_contains_case_insensitive_content?( get_script_output, 'AMD64' )).to eq(true)
end
it "executes a script with a 32-bit process if :i386 arch is specified" do
@@ -213,7 +228,7 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
resource.returns(0)
resource.run_action(:run)
- source_contains_case_insensitive_content?( get_script_output, 'x86' ).should == true
+ expect(source_contains_case_insensitive_content?( get_script_output, 'x86' )).to eq(true)
end
end
@@ -230,22 +245,22 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
it "evaluates a succeeding not_if block using cmd.exe as false by default" do
resource.not_if "exit /b 0"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a failing not_if block using cmd.exe as true by default" do
resource.not_if "exit /b 2"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates an succeeding only_if block using cmd.exe as true by default" do
resource.only_if "exit /b 0"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a failing only_if block using cmd.exe as false by default" do
resource.only_if "exit /b 2"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
end
@@ -257,7 +272,7 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
it "evaluates a powershell $true for a only_if block as true" do
resource.only_if "$true"
resource.guard_interpreter :powershell_script
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
end
@@ -269,184 +284,184 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
it "evaluates a powershell $false for a not_if block as true" do
resource.not_if "$false"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a powershell $true for a not_if block as false" do
resource.not_if "$true"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a powershell $false for an only_if block as false" do
resource.only_if "$false"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a powershell $true for a only_if block as true" do
resource.only_if "$true"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a not_if block using powershell.exe" do
resource.not_if "exit([int32](![System.Environment]::CommandLine.Contains('powershell.exe')))"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates an only_if block using powershell.exe" do
resource.only_if "exit([int32](![System.Environment]::CommandLine.Contains('powershell.exe')))"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a non-zero powershell exit status for not_if as true" do
resource.not_if "exit 37"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a zero powershell exit status for not_if as false" do
resource.not_if "exit 0"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a failed executable exit status for not_if as false" do
resource.not_if windows_process_exit_code_not_found_content
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a successful executable exit status for not_if as true" do
resource.not_if windows_process_exit_code_success_content
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a failed executable exit status for only_if as false" do
resource.only_if windows_process_exit_code_not_found_content
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a successful executable exit status for only_if as true" do
resource.only_if windows_process_exit_code_success_content
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a failed cmdlet exit status for not_if as true" do
resource.not_if "throw 'up'"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a successful cmdlet exit status for not_if as true" do
resource.not_if "cd ."
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a failed cmdlet exit status for only_if as false" do
resource.only_if "throw 'up'"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a successful cmdlet exit status for only_if as true" do
resource.only_if "cd ."
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a not_if block using the cwd guard parameter" do
custom_cwd = "#{ENV['SystemRoot']}\\system32\\drivers\\etc"
resource.not_if "exit ! [int32]($pwd.path -eq '#{custom_cwd}')", :cwd => custom_cwd
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates an only_if block using the cwd guard parameter" do
custom_cwd = "#{ENV['SystemRoot']}\\system32\\drivers\\etc"
resource.only_if "exit ! [int32]($pwd.path -eq '#{custom_cwd}')", :cwd => custom_cwd
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "inherits cwd from the parent resource for only_if" do
custom_cwd = "#{ENV['SystemRoot']}\\system32\\drivers\\etc"
resource.cwd custom_cwd
resource.only_if "exit ! [int32]($pwd.path -eq '#{custom_cwd}')"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "inherits cwd from the parent resource for not_if" do
custom_cwd = "#{ENV['SystemRoot']}\\system32\\drivers\\etc"
resource.cwd custom_cwd
resource.not_if "exit ! [int32]($pwd.path -eq '#{custom_cwd}')"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a 64-bit resource with a 64-bit guard and interprets boolean false as zero status code", :windows64_only do
resource.architecture :x86_64
resource.only_if "exit [int32]($env:PROCESSOR_ARCHITECTURE -ne 'AMD64')"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a 64-bit resource with a 64-bit guard and interprets boolean true as nonzero status code", :windows64_only do
resource.architecture :x86_64
resource.only_if "exit [int32]($env:PROCESSOR_ARCHITECTURE -eq 'AMD64')"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a 32-bit resource with a 32-bit guard and interprets boolean false as zero status code" do
resource.architecture :i386
resource.only_if "exit [int32]($env:PROCESSOR_ARCHITECTURE -ne 'X86')"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a 32-bit resource with a 32-bit guard and interprets boolean true as nonzero status code" do
resource.architecture :i386
resource.only_if "exit [int32]($env:PROCESSOR_ARCHITECTURE -eq 'X86')"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a simple boolean false as nonzero status code when convert_boolean_return is true for only_if" do
resource.convert_boolean_return true
resource.only_if "$false"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a simple boolean false as nonzero status code when convert_boolean_return is true for not_if" do
resource.convert_boolean_return true
resource.not_if "$false"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a simple boolean true as 0 status code when convert_boolean_return is true for only_if" do
resource.convert_boolean_return true
resource.only_if "$true"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a simple boolean true as 0 status code when convert_boolean_return is true for not_if" do
resource.convert_boolean_return true
resource.not_if "$true"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a 32-bit resource with a 32-bit guard and interprets boolean false as zero status code using convert_boolean_return for only_if" do
resource.convert_boolean_return true
resource.architecture :i386
resource.only_if "$env:PROCESSOR_ARCHITECTURE -eq 'X86'"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a 32-bit resource with a 32-bit guard and interprets boolean false as zero status code using convert_boolean_return for not_if" do
resource.convert_boolean_return true
resource.architecture :i386
resource.not_if "$env:PROCESSOR_ARCHITECTURE -ne 'X86'"
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
it "evaluates a 32-bit resource with a 32-bit guard and interprets boolean true as nonzero status code using convert_boolean_return for only_if" do
resource.convert_boolean_return true
resource.architecture :i386
resource.only_if "$env:PROCESSOR_ARCHITECTURE -ne 'X86'"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
it "evaluates a 32-bit resource with a 32-bit guard and interprets boolean true as nonzero status code using convert_boolean_return for not_if" do
resource.convert_boolean_return true
resource.architecture :i386
resource.not_if "$env:PROCESSOR_ARCHITECTURE -eq 'X86'"
- resource.should_skip?(:run).should be_true
+ expect(resource.should_skip?(:run)).to be_truthy
end
end
end
diff --git a/spec/functional/resource/reboot_spec.rb b/spec/functional/resource/reboot_spec.rb
index 735ca994c8..99de136827 100644
--- a/spec/functional/resource/reboot_spec.rb
+++ b/spec/functional/resource/reboot_spec.rb
@@ -50,7 +50,7 @@ describe Chef::Resource::Reboot do
expect(reboot_info[:reason]).to eq(expected[:reason])
expect(reboot_info[:requested_by]).to eq(expected[:requested_by])
- expect(resource.run_context.reboot_requested?).to be_true
+ expect(resource.run_context.reboot_requested?).to be_truthy
end
end
@@ -97,7 +97,7 @@ describe Chef::Resource::Reboot do
it 'should have cleared the reboot request' do
# arguably we shouldn't be querying RunContext's internal data directly.
expect(resource.run_context.reboot_info).to eq({})
- expect(resource.run_context.reboot_requested?).to be_false
+ expect(resource.run_context.reboot_requested?).to be_falsey
end
end
end
diff --git a/spec/functional/resource/registry_spec.rb b/spec/functional/resource/registry_spec.rb
index 2d24eee6a3..f112ad9b00 100644
--- a/spec/functional/resource/registry_spec.rb
+++ b/spec/functional/resource/registry_spec.rb
@@ -35,12 +35,12 @@ describe Chef::Resource::RegistryKey, :unix_only do
it "throws an exception because you don't have a windows registry (derp)" do
@resource.key("HKCU\\Software\\Opscode")
@resource.values([{:name=>"Color", :type=>:string, :data=>"Orange"}])
- lambda{@resource.run_action(:create)}.should raise_error(Chef::Exceptions::Win32NotWindows)
+ expect{@resource.run_action(:create)}.to raise_error(Chef::Exceptions::Win32NotWindows)
end
end
end
-describe Chef::Resource::RegistryKey, :windows_only do
+describe Chef::Resource::RegistryKey, :windows_only, :broken => true do
# parent and key must be single keys, not paths
let(:parent) { 'Opscode' }
@@ -112,9 +112,9 @@ describe Chef::Resource::RegistryKey, :windows_only do
@node.name("windowsbox")
@rest_client = double("Chef::REST (mock)")
- @rest_client.stub(:create_url).and_return("reports/nodes/windowsbox/runs/#{@run_id}");
- @rest_client.stub(:raw_http_request).and_return({"result"=>"ok"});
- @rest_client.stub(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/windowsbox/runs/#{@run_id}"});
+ allow(@rest_client).to receive(:create_url).and_return("reports/nodes/windowsbox/runs/#{@run_id}");
+ allow(@rest_client).to receive(:raw_http_request).and_return({"result"=>"ok"});
+ allow(@rest_client).to receive(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/windowsbox/runs/#{@run_id}"});
@resource_reporter = Chef::ResourceReporter.new(@rest_client)
@events.register(@resource_reporter)
@@ -125,7 +125,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.cookbook_name = "monkey"
@cookbook_version = double("Cookbook::Version", :version => "1.2.3")
- @new_resource.stub(:cookbook_version).and_return(@cookbook_version)
+ allow(@new_resource).to receive(:cookbook_version).and_return(@cookbook_version)
end
after (:all) do
@@ -141,8 +141,8 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.values([{:name=>"Color", :type=>:string, :data=>"Orange"}])
@new_resource.run_action(:create)
- @registry.key_exists?(reg_child).should == true
- @registry.data_exists?(reg_child, {:name=>"Color", :type=>:string, :data=>"Orange"}).should == true
+ expect(@registry.key_exists?(reg_child)).to eq(true)
+ expect(@registry.data_exists?(reg_child, {:name=>"Color", :type=>:string, :data=>"Orange"})).to eq(true)
end
it "does not create the key if it already exists with same value, type and data" do
@@ -150,8 +150,8 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.values([{:name=>"Color", :type=>:string, :data=>"Orange"}])
@new_resource.run_action(:create)
- @registry.key_exists?(reg_child).should == true
- @registry.data_exists?(reg_child, {:name=>"Color", :type=>:string, :data=>"Orange"}).should == true
+ expect(@registry.key_exists?(reg_child)).to eq(true)
+ expect(@registry.data_exists?(reg_child, {:name=>"Color", :type=>:string, :data=>"Orange"})).to eq(true)
end
it "creates a value if it does not exist" do
@@ -159,7 +159,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.values([{:name=>"Mango", :type=>:string, :data=>"Yellow"}])
@new_resource.run_action(:create)
- @registry.data_exists?(reg_child, {:name=>"Mango", :type=>:string, :data=>"Yellow"}).should == true
+ expect(@registry.data_exists?(reg_child, {:name=>"Mango", :type=>:string, :data=>"Yellow"})).to eq(true)
end
it "modifies the data if the key and value exist and type matches" do
@@ -167,7 +167,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.values([{:name=>"Color", :type=>:string, :data=>"Not just Orange - OpscodeOrange!"}])
@new_resource.run_action(:create)
- @registry.data_exists?(reg_child, {:name=>"Color", :type=>:string, :data=>"Not just Orange - OpscodeOrange!"}).should == true
+ expect(@registry.data_exists?(reg_child, {:name=>"Color", :type=>:string, :data=>"Not just Orange - OpscodeOrange!"})).to eq(true)
end
it "modifys the type if the key and value exist and the type does not match" do
@@ -175,7 +175,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.values([{:name=>"Color", :type=>:multi_string, :data=>["Not just Orange - OpscodeOrange!"]}])
@new_resource.run_action(:create)
- @registry.data_exists?(reg_child, {:name=>"Color", :type=>:multi_string, :data=>["Not just Orange - OpscodeOrange!"]}).should == true
+ expect(@registry.data_exists?(reg_child, {:name=>"Color", :type=>:multi_string, :data=>["Not just Orange - OpscodeOrange!"]})).to eq(true)
end
it "creates subkey if parent exists" do
@@ -184,15 +184,15 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.recursive(false)
@new_resource.run_action(:create)
- @registry.key_exists?(reg_child + '\OpscodeTest').should == true
- @registry.value_exists?(reg_child + '\OpscodeTest', {:name=>"Chef", :type=>:multi_string, :data=>["OpscodeOrange", "Rules"]}).should == true
+ expect(@registry.key_exists?(reg_child + '\OpscodeTest')).to eq(true)
+ expect(@registry.value_exists?(reg_child + '\OpscodeTest', {:name=>"Chef", :type=>:multi_string, :data=>["OpscodeOrange", "Rules"]})).to eq(true)
end
it "gives error if action create and parent does not exist and recursive is set to false" do
@new_resource.key(reg_child + '\Missing1\Missing2')
@new_resource.values([{:name=>"OC", :type=>:string, :data=>"MissingData"}])
@new_resource.recursive(false)
- lambda{@new_resource.run_action(:create)}.should raise_error(Chef::Exceptions::Win32RegNoRecursive)
+ expect{@new_resource.run_action(:create)}.to raise_error(Chef::Exceptions::Win32RegNoRecursive)
end
it "creates missing keys if action create and parent does not exist and recursive is set to true" do
@@ -201,8 +201,8 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.recursive(true)
@new_resource.run_action(:create)
- @registry.key_exists?(reg_child + '\Missing1\Missing2').should == true
- @registry.value_exists?(reg_child + '\Missing1\Missing2', {:name=>"OC", :type=>:string, :data=>"MissingData"}).should == true
+ expect(@registry.key_exists?(reg_child + '\Missing1\Missing2')).to eq(true)
+ expect(@registry.value_exists?(reg_child + '\Missing1\Missing2', {:name=>"OC", :type=>:string, :data=>"MissingData"})).to eq(true)
end
it "creates key with multiple value as specified" do
@@ -212,7 +212,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.run_action(:create)
@new_resource.values.each do |value|
- @registry.value_exists?(reg_child, value).should == true
+ expect(@registry.value_exists?(reg_child, value)).to eq(true)
end
end
@@ -231,9 +231,9 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.architecture(:i386)
@new_resource.run_action(:create)
@registry.architecture = :i386
- @registry.data_exists?(reg_child + '\Atraxi', {:name=>"OC", :type=>:string, :data=>"Data"}).should == true
+ expect(@registry.data_exists?(reg_child + '\Atraxi', {:name=>"OC", :type=>:string, :data=>"Data"})).to eq(true)
@registry.architecture = :x86_64
- @registry.key_exists?(reg_child + '\Atraxi').should == false
+ expect(@registry.key_exists?(reg_child + '\Atraxi')).to eq(false)
end
end
@@ -244,16 +244,16 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.run_action(:create)
@report = @resource_reporter.prepare_run_data
- @report["action"].should == "end"
- @report["resources"][0]["type"].should == "registry_key"
- @report["resources"][0]["name"].should == resource_name
- @report["resources"][0]["id"].should == reg_child + '\Ood'
- @report["resources"][0]["after"][:values].should == [{:name=>"ReportingVal1", :type=>:string, :data=>"report1"},
- {:name=>"ReportingVal2", :type=>:string, :data=>"report2"}]
- @report["resources"][0]["before"][:values].should == []
- @report["resources"][0]["result"].should == "create"
- @report["status"].should == "success"
- @report["total_res_count"].should == "1"
+ expect(@report["action"]).to eq("end")
+ expect(@report["resources"][0]["type"]).to eq("registry_key")
+ expect(@report["resources"][0]["name"]).to eq(resource_name)
+ expect(@report["resources"][0]["id"]).to eq(reg_child + '\Ood')
+ expect(@report["resources"][0]["after"][:values]).to eq([{:name=>"ReportingVal1", :type=>:string, :data=>"report1"},
+ {:name=>"ReportingVal2", :type=>:string, :data=>"report2"}])
+ expect(@report["resources"][0]["before"][:values]).to eq([])
+ expect(@report["resources"][0]["result"]).to eq("create")
+ expect(@report["status"]).to eq("success")
+ expect(@report["total_res_count"]).to eq("1")
end
context "while running in whyrun mode" do
@@ -266,15 +266,15 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.values([{:name=>"BriskWalk",:type=>:string,:data=>"is good for health"}])
@new_resource.recursive(false)
@new_resource.run_action(:create) # should not raise_error
- @registry.key_exists?(reg_child + '\Slitheen').should == false
- @registry.key_exists?(reg_child + '\Slitheen\Raxicoricofallapatorius').should == false
+ expect(@registry.key_exists?(reg_child + '\Slitheen')).to eq(false)
+ expect(@registry.key_exists?(reg_child + '\Slitheen\Raxicoricofallapatorius')).to eq(false)
end
it "does not create key if the action is create" do
@new_resource.key(reg_child + '\Slitheen')
@new_resource.values([{:name=>"BriskWalk",:type=>:string,:data=>"is good for health"}])
@new_resource.recursive(false)
@new_resource.run_action(:create)
- @registry.key_exists?(reg_child + '\Slitheen').should == false
+ expect(@registry.key_exists?(reg_child + '\Slitheen')).to eq(false)
end
end
end
@@ -289,9 +289,9 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.values([{:name=>"Color", :type=>:string, :data=>"Orange"}])
@new_resource.run_action(:create_if_missing)
- @registry.key_exists?(reg_parent).should == true
- @registry.key_exists?(reg_child).should == true
- @registry.data_exists?(reg_child, {:name=>"Color", :type=>:string, :data=>"Orange"}).should == true
+ expect(@registry.key_exists?(reg_parent)).to eq(true)
+ expect(@registry.key_exists?(reg_child)).to eq(true)
+ expect(@registry.data_exists?(reg_child, {:name=>"Color", :type=>:string, :data=>"Orange"})).to eq(true)
end
it "does not create the key if it already exists with same value, type and data" do
@@ -299,8 +299,8 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.values([{:name=>"Color", :type=>:string, :data=>"Orange"}])
@new_resource.run_action(:create_if_missing)
- @registry.key_exists?(reg_child).should == true
- @registry.data_exists?(reg_child, {:name=>"Color", :type=>:string, :data=>"Orange"}).should == true
+ expect(@registry.key_exists?(reg_child)).to eq(true)
+ expect(@registry.data_exists?(reg_child, {:name=>"Color", :type=>:string, :data=>"Orange"})).to eq(true)
end
it "creates a value if it does not exist" do
@@ -308,7 +308,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.values([{:name=>"Mango", :type=>:string, :data=>"Yellow"}])
@new_resource.run_action(:create_if_missing)
- @registry.data_exists?(reg_child, {:name=>"Mango", :type=>:string, :data=>"Yellow"}).should == true
+ expect(@registry.data_exists?(reg_child, {:name=>"Mango", :type=>:string, :data=>"Yellow"})).to eq(true)
end
it "creates subkey if parent exists" do
@@ -317,15 +317,15 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.recursive(false)
@new_resource.run_action(:create_if_missing)
- @registry.key_exists?(reg_child + '\Pyrovile').should == true
- @registry.value_exists?(reg_child + '\Pyrovile', {:name=>"Chef", :type=>:multi_string, :data=>["OpscodeOrange", "Rules"]}).should == true
+ expect(@registry.key_exists?(reg_child + '\Pyrovile')).to eq(true)
+ expect(@registry.value_exists?(reg_child + '\Pyrovile', {:name=>"Chef", :type=>:multi_string, :data=>["OpscodeOrange", "Rules"]})).to eq(true)
end
it "gives error if action create and parent does not exist and recursive is set to false" do
@new_resource.key(reg_child + '\Sontaran\Sontar')
@new_resource.values([{:name=>"OC", :type=>:string, :data=>"MissingData"}])
@new_resource.recursive(false)
- lambda{@new_resource.run_action(:create_if_missing)}.should raise_error(Chef::Exceptions::Win32RegNoRecursive)
+ expect{@new_resource.run_action(:create_if_missing)}.to raise_error(Chef::Exceptions::Win32RegNoRecursive)
end
it "creates missing keys if action create and parent does not exist and recursive is set to true" do
@@ -334,8 +334,8 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.recursive(true)
@new_resource.run_action(:create_if_missing)
- @registry.key_exists?(reg_child + '\Sontaran\Sontar').should == true
- @registry.value_exists?(reg_child + '\Sontaran\Sontar', {:name=>"OC", :type=>:string, :data=>"MissingData"}).should == true
+ expect(@registry.key_exists?(reg_child + '\Sontaran\Sontar')).to eq(true)
+ expect(@registry.value_exists?(reg_child + '\Sontaran\Sontar', {:name=>"OC", :type=>:string, :data=>"MissingData"})).to eq(true)
end
it "creates key with multiple value as specified" do
@@ -345,7 +345,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.run_action(:create_if_missing)
@new_resource.values.each do |value|
- @registry.value_exists?(reg_child + '\Adipose', value).should == true
+ expect(@registry.value_exists?(reg_child + '\Adipose', value)).to eq(true)
end
end
@@ -356,15 +356,15 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.run_action(:create_if_missing)
@report = @resource_reporter.prepare_run_data
- @report["action"].should == "end"
- @report["resources"][0]["type"].should == "registry_key"
- @report["resources"][0]["name"].should == resource_name
- @report["resources"][0]["id"].should == reg_child + '\Judoon'
- @report["resources"][0]["after"][:values].should == [{:name=>"ReportingVal3", :type=>:string, :data=>"report3"}]
- @report["resources"][0]["before"][:values].should == []
- @report["resources"][0]["result"].should == "create_if_missing"
- @report["status"].should == "success"
- @report["total_res_count"].should == "1"
+ expect(@report["action"]).to eq("end")
+ expect(@report["resources"][0]["type"]).to eq("registry_key")
+ expect(@report["resources"][0]["name"]).to eq(resource_name)
+ expect(@report["resources"][0]["id"]).to eq(reg_child + '\Judoon')
+ expect(@report["resources"][0]["after"][:values]).to eq([{:name=>"ReportingVal3", :type=>:string, :data=>"report3"}])
+ expect(@report["resources"][0]["before"][:values]).to eq([])
+ expect(@report["resources"][0]["result"]).to eq("create_if_missing")
+ expect(@report["status"]).to eq("success")
+ expect(@report["total_res_count"]).to eq("1")
end
context "while running in whyrun mode" do
@@ -377,15 +377,15 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.values([{:name=>"BriskWalk",:type=>:string,:data=>"is good for health"}])
@new_resource.recursive(false)
@new_resource.run_action(:create_if_missing) # should not raise_error
- @registry.key_exists?(reg_child + '\Zygons').should == false
- @registry.key_exists?(reg_child + '\Zygons\Zygor').should == false
+ expect(@registry.key_exists?(reg_child + '\Zygons')).to eq(false)
+ expect(@registry.key_exists?(reg_child + '\Zygons\Zygor')).to eq(false)
end
it "does nothing if the action is create_if_missing" do
@new_resource.key(reg_child + '\Zygons')
@new_resource.values([{:name=>"BriskWalk",:type=>:string,:data=>"is good for health"}])
@new_resource.recursive(false)
@new_resource.run_action(:create_if_missing)
- @registry.key_exists?(reg_child + '\Zygons').should == false
+ expect(@registry.key_exists?(reg_child + '\Zygons')).to eq(false)
end
end
end
@@ -397,24 +397,24 @@ describe Chef::Resource::RegistryKey, :windows_only do
end
it "takes no action if the specified key path does not exist in the system" do
- @registry.key_exists?(reg_parent + '\Osirian').should == false
+ expect(@registry.key_exists?(reg_parent + '\Osirian')).to eq(false)
@new_resource.key(reg_parent+ '\Osirian')
@new_resource.recursive(false)
@new_resource.run_action(:delete)
- @registry.key_exists?(reg_parent + '\Osirian').should == false
+ expect(@registry.key_exists?(reg_parent + '\Osirian')).to eq(false)
end
it "takes no action if the key exists but the value does not" do
- @registry.data_exists?(reg_parent + '\Opscode', {:name=>"Color", :type=>:string, :data=>"Orange"}).should == true
+ expect(@registry.data_exists?(reg_parent + '\Opscode', {:name=>"Color", :type=>:string, :data=>"Orange"})).to eq(true)
@new_resource.key(reg_parent + '\Opscode')
@new_resource.values([{:name=>"LooksLike", :type=>:multi_string, :data=>["SeattleGrey", "OCOrange"]}])
@new_resource.recursive(false)
@new_resource.run_action(:delete)
- @registry.data_exists?(reg_parent + '\Opscode', {:name=>"Color", :type=>:string, :data=>"Orange"}).should == true
+ expect(@registry.data_exists?(reg_parent + '\Opscode', {:name=>"Color", :type=>:string, :data=>"Orange"})).to eq(true)
end
it "deletes only specified values under a key path" do
@@ -423,9 +423,9 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.recursive(false)
@new_resource.run_action(:delete)
- @registry.data_exists?(reg_parent + '\Opscode', {:name=>"Color", :type=>:string, :data=>"Orange"}).should == true
- @registry.value_exists?(reg_parent + '\Opscode', {:name=>"AKA", :type=>:string, :data=>"OC"}).should == false
- @registry.value_exists?(reg_parent + '\Opscode', {:name=>"Opscode", :type=>:multi_string, :data=>["Seattle", "Washington"]}).should == false
+ expect(@registry.data_exists?(reg_parent + '\Opscode', {:name=>"Color", :type=>:string, :data=>"Orange"})).to eq(true)
+ expect(@registry.value_exists?(reg_parent + '\Opscode', {:name=>"AKA", :type=>:string, :data=>"OC"})).to eq(false)
+ expect(@registry.value_exists?(reg_parent + '\Opscode', {:name=>"Opscode", :type=>:multi_string, :data=>["Seattle", "Washington"]})).to eq(false)
end
it "it deletes the values with the same name irrespective of it type and data" do
@@ -434,7 +434,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.recursive(false)
@new_resource.run_action(:delete)
- @registry.value_exists?(reg_parent + '\Opscode', {:name=>"Color", :type=>:string, :data=>"Orange"}).should == false
+ expect(@registry.value_exists?(reg_parent + '\Opscode', {:name=>"Color", :type=>:string, :data=>"Orange"})).to eq(false)
end
it "prepares the reporting data for action :delete" do
@@ -445,19 +445,19 @@ describe Chef::Resource::RegistryKey, :windows_only do
@report = @resource_reporter.prepare_run_data
- @registry.value_exists?(reg_parent + '\ReportKey', [{:name=>"ReportVal4", :type=>:string, :data=>"report4"},{:name=>"ReportVal5", :type=>:string, :data=>"report5"}]).should == false
+ expect(@registry.value_exists?(reg_parent + '\ReportKey', [{:name=>"ReportVal4", :type=>:string, :data=>"report4"},{:name=>"ReportVal5", :type=>:string, :data=>"report5"}])).to eq(false)
- @report["action"].should == "end"
- @report["resources"].count.should == 1
- @report["resources"][0]["type"].should == "registry_key"
- @report["resources"][0]["name"].should == resource_name
- @report["resources"][0]["id"].should == reg_parent + '\ReportKey'
- @report["resources"][0]["before"][:values].should == [{:name=>"ReportVal4", :type=>:string, :data=>"report4"},
- {:name=>"ReportVal5", :type=>:string, :data=>"report5"}]
+ expect(@report["action"]).to eq("end")
+ expect(@report["resources"].count).to eq(1)
+ expect(@report["resources"][0]["type"]).to eq("registry_key")
+ expect(@report["resources"][0]["name"]).to eq(resource_name)
+ expect(@report["resources"][0]["id"]).to eq(reg_parent + '\ReportKey')
+ expect(@report["resources"][0]["before"][:values]).to eq([{:name=>"ReportVal4", :type=>:string, :data=>"report4"},
+ {:name=>"ReportVal5", :type=>:string, :data=>"report5"}])
#Not testing for after values to match since after -> new_resource values.
- @report["resources"][0]["result"].should == "delete"
- @report["status"].should == "success"
- @report["total_res_count"].should == "1"
+ expect(@report["resources"][0]["result"]).to eq("delete")
+ expect(@report["status"]).to eq("success")
+ expect(@report["total_res_count"]).to eq("1")
end
context "while running in whyrun mode" do
@@ -470,7 +470,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.recursive(false)
@new_resource.run_action(:delete)
- @registry.key_exists?(reg_parent + '\OpscodeWhyRun').should == true
+ expect(@registry.key_exists?(reg_parent + '\OpscodeWhyRun')).to eq(true)
end
end
end
@@ -482,13 +482,13 @@ describe Chef::Resource::RegistryKey, :windows_only do
end
it "takes no action if the specified key path does not exist in the system" do
- @registry.key_exists?(reg_parent + '\Osirian').should == false
+ expect(@registry.key_exists?(reg_parent + '\Osirian')).to eq(false)
@new_resource.key(reg_parent + '\Osirian')
@new_resource.recursive(false)
@new_resource.run_action(:delete_key)
- @registry.key_exists?(reg_parent + '\Osirian').should == false
+ expect(@registry.key_exists?(reg_parent + '\Osirian')).to eq(false)
end
it "deletes key if it has no subkeys and recursive == false" do
@@ -496,13 +496,13 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.recursive(false)
@new_resource.run_action(:delete_key)
- @registry.key_exists?(reg_parent + '\OpscodeTest').should == false
+ expect(@registry.key_exists?(reg_parent + '\OpscodeTest')).to eq(false)
end
it "raises an exception if the key has subkeys and recursive == false" do
@new_resource.key(reg_parent)
@new_resource.recursive(false)
- lambda{@new_resource.run_action(:delete_key)}.should raise_error(Chef::Exceptions::Win32RegNoRecursive)
+ expect{@new_resource.run_action(:delete_key)}.to raise_error(Chef::Exceptions::Win32RegNoRecursive)
end
it "ignores the values under a key" do
@@ -517,7 +517,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.recursive(true)
@new_resource.run_action(:delete_key)
- @registry.key_exists?(reg_parent + '\Opscode').should == false
+ expect(@registry.key_exists?(reg_parent + '\Opscode')).to eq(false)
end
it "prepares the reporting data for action :delete_key" do
@@ -526,16 +526,16 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.run_action(:delete_key)
@report = @resource_reporter.prepare_run_data
- @report["action"].should == "end"
- @report["resources"][0]["type"].should == "registry_key"
- @report["resources"][0]["name"].should == resource_name
- @report["resources"][0]["id"].should == reg_parent + '\ReportKey'
+ expect(@report["action"]).to eq("end")
+ expect(@report["resources"][0]["type"]).to eq("registry_key")
+ expect(@report["resources"][0]["name"]).to eq(resource_name)
+ expect(@report["resources"][0]["id"]).to eq(reg_parent + '\ReportKey')
#Not testing for before or after values to match since
#after -> new_resource.values and
#before -> current_resource.values
- @report["resources"][0]["result"].should == "delete_key"
- @report["status"].should == "success"
- @report["total_res_count"].should == "1"
+ expect(@report["resources"][0]["result"]).to eq("delete_key")
+ expect(@report["status"]).to eq("success")
+ expect(@report["total_res_count"]).to eq("1")
end
context "while running in whyrun mode" do
before (:each) do
@@ -554,7 +554,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
@new_resource.recursive(false)
@new_resource.run_action(:delete_key)
- @registry.key_exists?(reg_parent + '\OpscodeWhyRun').should == true
+ expect(@registry.key_exists?(reg_parent + '\OpscodeWhyRun')).to eq(true)
end
end
end
diff --git a/spec/functional/resource/remote_directory_spec.rb b/spec/functional/resource/remote_directory_spec.rb
index f9eb20711e..bcafca7399 100644
--- a/spec/functional/resource/remote_directory_spec.rb
+++ b/spec/functional/resource/remote_directory_spec.rb
@@ -81,12 +81,12 @@ describe Chef::Resource::RemoteDirectory do
it "transfers the directory with all contents" do
expected_files.each do |file_path|
- File.should exist(file_path)
+ expect(File).to exist(file_path)
end
end
it "is marked as updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
@@ -98,13 +98,13 @@ describe Chef::Resource::RemoteDirectory do
it "does not modify the expected state of the directory" do
expected_files.each do |file_path|
- File.should exist(file_path)
+ expect(File).to exist(file_path)
end
end
it "does not remove unmanaged files" do
- File.should exist(@existing1)
- File.should exist(@existing2)
+ expect(File).to exist(@existing1)
+ expect(File).to exist(@existing2)
end
end
@@ -116,12 +116,12 @@ describe Chef::Resource::RemoteDirectory do
it "does not modify the expected state of the directory" do
expected_files.each do |file_path|
- File.should exist(file_path)
+ expect(File).to exist(file_path)
end
end
it "is not marked as updated by last action" do
- resource_second_pass.should_not be_updated_by_last_action
+ expect(resource_second_pass).not_to be_updated_by_last_action
end
end
@@ -142,8 +142,8 @@ describe Chef::Resource::RemoteDirectory do
modified_subdir_file_checksum = sha256_checksum(modified_subdir_file)
resource.run_action(:create)
- sha256_checksum(modified_file).should == modified_file_checksum
- sha256_checksum(modified_subdir_file).should == modified_subdir_file_checksum
+ expect(sha256_checksum(modified_file)).to eq(modified_file_checksum)
+ expect(sha256_checksum(modified_subdir_file)).to eq(modified_subdir_file_checksum)
end
end
end
@@ -160,7 +160,7 @@ describe Chef::Resource::RemoteDirectory do
it "creates the directory contents as normal" do
expected_files.each do |file_path|
- File.should exist(file_path)
+ expect(File).to exist(file_path)
end
end
@@ -173,18 +173,18 @@ describe Chef::Resource::RemoteDirectory do
end
it "removes unmanaged files" do
- File.should_not exist(@existing1)
- File.should_not exist(@existing2)
+ expect(File).not_to exist(@existing1)
+ expect(File).not_to exist(@existing2)
end
it "does not modify managed files" do
expected_files.each do |file_path|
- File.should exist(file_path)
+ expect(File).to exist(file_path)
end
end
it "is marked as updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
@@ -204,14 +204,14 @@ describe Chef::Resource::RemoteDirectory do
end
it "removes files in subdirectories before files above" do
- File.should_not exist(@existing1)
- File.should_not exist(@existing2)
- File.should_not exist(@existing3)
- File.should_not exist(@existing4)
+ expect(File).not_to exist(@existing1)
+ expect(File).not_to exist(@existing2)
+ expect(File).not_to exist(@existing3)
+ expect(File).not_to exist(@existing4)
end
it "is marked as updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
diff --git a/spec/functional/resource/remote_file_spec.rb b/spec/functional/resource/remote_file_spec.rb
index ccdf1cb812..29091fd785 100644
--- a/spec/functional/resource/remote_file_spec.rb
+++ b/spec/functional/resource/remote_file_spec.rb
@@ -137,20 +137,20 @@ describe Chef::Resource::RemoteFile do
let(:source) { 'http://localhost:9000/nyan_cat_content_length_compressed.png' }
before do
- File.should_not exist(path)
+ expect(File).not_to exist(path)
resource.run_action(:create)
end
it "should create the file" do
- File.should exist(path)
+ expect(File).to exist(path)
end
it "should mark the resource as updated" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
it "has the correct content" do
- binread(path).should == expected_content
+ expect(binread(path)).to eq(expected_content)
end
end
@@ -159,20 +159,20 @@ describe Chef::Resource::RemoteFile do
let(:source) { 'http://localhost:9000/nyan_cat_content_length.png' }
before do
- File.should_not exist(path)
+ expect(File).not_to exist(path)
resource.run_action(:create)
end
it "should create the file" do
- File.should exist(path)
+ expect(File).to exist(path)
end
it "should mark the resource as updated" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
it "has the correct content" do
- binread(path).should == expected_content
+ expect(binread(path)).to eq(expected_content)
end
end
@@ -180,11 +180,11 @@ describe Chef::Resource::RemoteFile do
let(:source) { 'http://localhost:9000/nyan_cat_truncated_compressed.png' }
before do
- File.should_not exist(path)
+ expect(File).not_to exist(path)
end
it "should raise ContentLengthMismatch" do
- lambda { resource.run_action(:create) }.should raise_error(Chef::Exceptions::ContentLengthMismatch)
+ expect { resource.run_action(:create) }.to raise_error(Chef::Exceptions::ContentLengthMismatch)
#File.should_not exist(path) # XXX: CHEF-5081
end
end
@@ -193,11 +193,11 @@ describe Chef::Resource::RemoteFile do
let(:source) { 'http://localhost:9000/nyan_cat_truncated.png' }
before do
- File.should_not exist(path)
+ expect(File).not_to exist(path)
end
it "should raise ContentLengthMismatch" do
- lambda { resource.run_action(:create) }.should raise_error(Chef::Exceptions::ContentLengthMismatch)
+ expect { resource.run_action(:create) }.to raise_error(Chef::Exceptions::ContentLengthMismatch)
#File.should_not exist(path) # XXX: CHEF-5081
end
end
@@ -207,20 +207,20 @@ describe Chef::Resource::RemoteFile do
let(:source) { 'http://localhost:9000/nyan_cat_transfer_encoding.png' }
before do
- File.should_not exist(path)
+ expect(File).not_to exist(path)
resource.run_action(:create)
end
it "should create the file" do
- File.should exist(path)
+ expect(File).to exist(path)
end
it "should mark the resource as updated" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
it "has the correct content" do
- binread(path).should == expected_content
+ expect(binread(path)).to eq(expected_content)
end
end
@@ -228,12 +228,12 @@ describe Chef::Resource::RemoteFile do
let(:source) { 'http://localhost:0000/seattle_capo.png' }
before do
- File.should_not exist(path)
+ expect(File).not_to exist(path)
end
it "should not create the file" do
expect{ resource.run_action(:create) }.to raise_error
- File.should_not exist(path)
+ expect(File).not_to exist(path)
end
end
end
diff --git a/spec/functional/resource/template_spec.rb b/spec/functional/resource/template_spec.rb
index fefd995743..d7b35e7450 100644
--- a/spec/functional/resource/template_spec.rb
+++ b/spec/functional/resource/template_spec.rb
@@ -69,7 +69,7 @@ describe Chef::Resource::Template do
resource.source('openldap_variable_stuff.conf.erb')
resource.variables(:secret => "nutella")
resource.run_action(:create)
- IO.read(path).should == "super secret is nutella"
+ expect(IO.read(path)).to eq("super secret is nutella")
end
it "creates the template with the rendered content using a local erb file when the :create action is run" do
@@ -77,7 +77,7 @@ describe Chef::Resource::Template do
resource.cookbook(nil)
resource.local(true)
resource.run_action(:create)
- IO.read(path).should == expected_content
+ expect(IO.read(path)).to eq(expected_content)
end
end
@@ -96,7 +96,7 @@ describe Chef::Resource::Template do
shared_examples "a template with helpers" do
it "generates expected content by calling helper methods" do
resource.run_action(:create)
- binread(path).strip.should == expected_content
+ expect(binread(path).strip).to eq(expected_content)
end
end
@@ -202,7 +202,7 @@ describe Chef::Resource::Template do
it "output should contain platform's line endings" do
resource.run_action(:create)
binread(path).each_line do |line|
- line.should end_with(Chef::Platform.windows? ? "\r\n" : "\n")
+ expect(line).to end_with(Chef::Platform.windows? ? "\r\n" : "\n")
end
end
end
diff --git a/spec/functional/resource/user/dscl_spec.rb b/spec/functional/resource/user/dscl_spec.rb
index ba508e3258..45b6754453 100644
--- a/spec/functional/resource/user/dscl_spec.rb
+++ b/spec/functional/resource/user/dscl_spec.rb
@@ -37,15 +37,15 @@ describe "Chef::Resource::User with Chef::Provider::User::Dscl provider", metada
end
def user_should_exist
- shell_out("/usr/bin/dscl . -ls /Users").stdout.should include username
+ expect(shell_out("/usr/bin/dscl . -ls /Users").stdout).to include username
end
def check_password(pass)
# In order to test the password we use dscl passwd command since
# that's the only command that gets the user password from CLI.
- shell_out("dscl . -passwd /Users/greatchef #{pass} new_password").exitstatus.should == 0
+ expect(shell_out("dscl . -passwd /Users/greatchef #{pass} new_password").exitstatus).to eq(0)
# Now reset the password back
- shell_out("dscl . -passwd /Users/greatchef new_password #{pass}").exitstatus.should == 0
+ expect(shell_out("dscl . -passwd /Users/greatchef new_password #{pass}").exitstatus).to eq(0)
end
let(:node) do
@@ -191,7 +191,7 @@ c5adbbac718b7eb99463a7b679571e0f\
user_resource.run_action(:remove)
groups.each do |group|
# Do not raise an error when group is empty
- shell_out("dscl . read /Groups/staff GroupMembership").stdout.should_not include(group)
+ expect(shell_out("dscl . read /Groups/staff GroupMembership").stdout).not_to include(group)
end
end
end
diff --git a/spec/functional/resource/user/useradd_spec.rb b/spec/functional/resource/user/useradd_spec.rb
index 1fbe6fcb4d..9ac88d7b60 100644
--- a/spec/functional/resource/user/useradd_spec.rb
+++ b/spec/functional/resource/user/useradd_spec.rb
@@ -70,9 +70,9 @@ describe Chef::Provider::User::Useradd, metadata do
def password_should_be_set
if ohai[:platform] == "aix"
- pw_entry.passwd.should == "!"
+ expect(pw_entry.passwd).to eq("!")
else
- pw_entry.passwd.should == "x"
+ expect(pw_entry.passwd).to eq("x")
end
end
@@ -82,12 +82,25 @@ describe Chef::Provider::User::Useradd, metadata do
end
after do
- begin
- pw_entry # will raise if the user doesn't exist
- shell_out!("userdel", "-r", username, :returns => [0,12])
- rescue UserNotFound
- # nothing to remove
+ max_retries = 3
+ while max_retries > 0
+ begin
+ pw_entry # will raise if the user doesn't exist
+ status = shell_out!("userdel", "-r", username, :returns => [0,8,12])
+
+ # Error code 8 during userdel indicates that the user is logged in.
+ # This occurs randomly because the accounts daemon holds a lock due to which userdel fails.
+ # The work around is to retry userdel for 3 times.
+ break if status.exitstatus != 8
+
+ sleep 1
+ max_retries = max_retries -1
+ rescue UserNotFound
+ break
+ end
end
+
+ status.error! if max_retries == 0
end
let(:node) do
@@ -145,12 +158,12 @@ describe Chef::Provider::User::Useradd, metadata do
pending(reason)
end
user_resource.run_action(:create)
- user_resource.should be_updated_by_last_action
+ expect(user_resource).to be_updated_by_last_action
end
it "ensures the user exists" do
- pw_entry.name.should == username
+ expect(pw_entry.name).to eq(username)
end
# On Debian, the only constraints are that usernames must neither start
@@ -171,7 +184,7 @@ describe Chef::Provider::User::Useradd, metadata do
let(:username) { "t'bilisi" }
it "ensures the user exists" do
- pw_entry.name.should == username
+ expect(pw_entry.name).to eq(username)
end
end
@@ -181,7 +194,7 @@ describe Chef::Provider::User::Useradd, metadata do
let(:uid) { 1999 }
it "ensures the user has the given uid" do
- pw_entry.uid.should == "1999"
+ expect(pw_entry.uid).to eq("1999")
end
end
@@ -189,14 +202,14 @@ describe Chef::Provider::User::Useradd, metadata do
let(:comment) { "hello this is dog" }
it "ensures the comment is set" do
- pw_entry.gecos.should == "hello this is dog"
+ expect(pw_entry.gecos).to eq("hello this is dog")
end
context "in standard gecos format" do
let(:comment) { "Bobo T. Clown,some building,555-555-5555,@boboclown" }
it "ensures the comment is set" do
- pw_entry.gecos.should == comment
+ expect(pw_entry.gecos).to eq(comment)
end
end
@@ -206,7 +219,7 @@ describe Chef::Provider::User::Useradd, metadata do
it "ensures the comment is set" do
actual = pw_entry.gecos
actual.force_encoding(Encoding::UTF_8) if "".respond_to?(:force_encoding)
- actual.should == comment
+ expect(actual).to eq(comment)
end
end
@@ -214,7 +227,7 @@ describe Chef::Provider::User::Useradd, metadata do
let(:comment) { "don't go" }
it "ensures the comment is set" do
- pw_entry.gecos.should == comment
+ expect(pw_entry.gecos).to eq(comment)
end
end
end
@@ -223,17 +236,17 @@ describe Chef::Provider::User::Useradd, metadata do
let(:home) { "/home/#{username}" }
it "ensures the user's home is set to the given path" do
- pw_entry.home.should == "/home/#{username}"
+ expect(pw_entry.home).to eq("/home/#{username}")
end
if %w{rhel fedora}.include?(OHAI_SYSTEM["platform_family"])
# Inconsistent behavior. See: CHEF-2205
it "creates the home dir when not explicitly asked to on RHEL (XXX)" do
- File.should exist("/home/#{username}")
+ expect(File).to exist("/home/#{username}")
end
else
it "does not create the home dir without `manage_home'" do
- File.should_not exist("/home/#{username}")
+ expect(File).not_to exist("/home/#{username}")
end
end
@@ -241,7 +254,7 @@ describe Chef::Provider::User::Useradd, metadata do
let(:manage_home) { true }
it "ensures the user's home directory exists" do
- File.should exist("/home/#{username}")
+ expect(File).to exist("/home/#{username}")
end
end
end
@@ -259,7 +272,7 @@ describe Chef::Provider::User::Useradd, metadata do
it "sets the user's shadow password" do
password_should_be_set
- etc_shadow.should include(expected_shadow)
+ expect(etc_shadow).to include(expected_shadow)
end
end
@@ -284,7 +297,7 @@ describe Chef::Provider::User::Useradd, metadata do
end
it "ensures the user has the properties of a system user" do
- pw_entry.uid.to_i.should be < uid_min.to_i
+ expect(pw_entry.uid.to_i).to be < uid_min.to_i
end
end
end # when the user does not exist beforehand
@@ -318,9 +331,9 @@ describe Chef::Provider::User::Useradd, metadata do
pending(reason)
end
existing_user.run_action(:create)
- existing_user.should be_updated_by_last_action
+ expect(existing_user).to be_updated_by_last_action
user_resource.run_action(:create)
- user_resource.updated_by_last_action?.should == expect_updated?
+ expect(user_resource.updated_by_last_action?).to eq(expect_updated?)
end
context "and all properties are in the desired state" do
@@ -350,7 +363,7 @@ describe Chef::Provider::User::Useradd, metadata do
let(:expect_updated?) { false }
it "does not update the user" do
- user_resource.should_not be_updated
+ expect(user_resource).not_to be_updated
end
end
@@ -359,7 +372,7 @@ describe Chef::Provider::User::Useradd, metadata do
let(:existing_uid) { 1998 }
it "ensures the uid is set to the desired value" do
- pw_entry.uid.should == "1999"
+ expect(pw_entry.uid).to eq("1999")
end
end
@@ -368,7 +381,7 @@ describe Chef::Provider::User::Useradd, metadata do
let(:existing_comment) { "woof" }
it "ensures the comment field is set to the desired value" do
- pw_entry.gecos.should == "hello this is dog"
+ expect(pw_entry.gecos).to eq("hello this is dog")
end
end
@@ -376,15 +389,15 @@ describe Chef::Provider::User::Useradd, metadata do
let(:existing_home) { "/home/foo" }
let(:home) { "/home/bar" }
it "ensures the home directory is set to the desired value" do
- pw_entry.home.should == "/home/bar"
+ expect(pw_entry.home).to eq("/home/bar")
end
context "and manage_home is enabled" do
let(:existing_manage_home) { true }
let(:manage_home) { true }
it "moves the home directory to the new location" do
- File.should_not exist("/home/foo")
- File.should exist("/home/bar")
+ expect(File).not_to exist("/home/foo")
+ expect(File).to exist("/home/bar")
end
end
@@ -396,19 +409,19 @@ describe Chef::Provider::User::Useradd, metadata do
# Inconsistent behavior. See: CHEF-2205
it "created the home dir b/c of CHEF-2205 so it still exists" do
# This behavior seems contrary to expectation and non-convergent.
- File.should_not exist("/home/foo")
- File.should exist("/home/bar")
+ expect(File).not_to exist("/home/foo")
+ expect(File).to exist("/home/bar")
end
elsif ohai[:platform] == "aix"
it "creates the home dir in the desired location" do
- File.should_not exist("/home/foo")
- File.should exist("/home/bar")
+ expect(File).not_to exist("/home/foo")
+ expect(File).to exist("/home/bar")
end
else
it "does not create the home dir in the desired location (XXX)" do
# This behavior seems contrary to expectation and non-convergent.
- File.should_not exist("/home/foo")
- File.should_not exist("/home/bar")
+ expect(File).not_to exist("/home/foo")
+ expect(File).not_to exist("/home/bar")
end
end
end
@@ -419,8 +432,8 @@ describe Chef::Provider::User::Useradd, metadata do
it "leaves the old home directory around (XXX)" do
# Would it be better to remove the old home?
- File.should exist("/home/foo")
- File.should_not exist("/home/bar")
+ expect(File).to exist("/home/foo")
+ expect(File).not_to exist("/home/bar")
end
end
end
@@ -439,7 +452,7 @@ describe Chef::Provider::User::Useradd, metadata do
it "ensures the password is set" do
password_should_be_set
- etc_shadow.should include(expected_shadow)
+ expect(etc_shadow).to include(expected_shadow)
end
end
@@ -468,7 +481,7 @@ describe Chef::Provider::User::Useradd, metadata do
it "ensures the password is set to the desired value" do
password_should_be_set
- etc_shadow.should include(expected_shadow)
+ expect(etc_shadow).to include(expected_shadow)
end
end
@@ -514,18 +527,18 @@ describe Chef::Provider::User::Useradd, metadata do
def user_account_should_be_locked
case ohai[:platform]
when "aix"
- aix_user_lock_status.should == "true"
+ expect(aix_user_lock_status).to eq("true")
else
- shadow_password.should include("!")
+ expect(shadow_password).to include("!")
end
end
def user_account_should_be_unlocked
case ohai[:platform]
when "aix"
- aix_user_lock_status.should == "false"
+ expect(aix_user_lock_status).to eq("false")
else
- shadow_password.should_not include("!")
+ expect(shadow_password).not_to include("!")
end
end
@@ -596,7 +609,7 @@ describe Chef::Provider::User::Useradd, metadata do
let(:user_locked_context?) { true }
it "does not update the user" do
- user_resource.should_not be_updated_by_last_action
+ expect(user_resource).not_to be_updated_by_last_action
end
end
end
@@ -628,8 +641,8 @@ describe Chef::Provider::User::Useradd, metadata do
if %w[suse opensuse].include?(OHAI_SYSTEM["platform_family"])
# suse gets this right:
it "errors out trying to unlock the user" do
- @error.should be_a(Mixlib::ShellOut::ShellCommandFailed)
- @error.message.should include("Cannot unlock the password")
+ expect(@error).to be_a(Mixlib::ShellOut::ShellCommandFailed)
+ expect(@error.message).to include("Cannot unlock the password")
end
else
@@ -644,13 +657,13 @@ describe Chef::Provider::User::Useradd, metadata do
# You should set a password with usermod -p to unlock this user's password.
# DEBUG: ---- End output of usermod -U chef-functional-test ----
# DEBUG: Ran usermod -U chef-functional-test returned 0
- @error.should be_nil
+ expect(@error).to be_nil
if ohai[:platform] == "aix"
- pw_entry.passwd.should == '*'
+ expect(pw_entry.passwd).to eq('*')
user_account_should_be_unlocked
else
- pw_entry.passwd.should == 'x'
- shadow_password.should include("!")
+ expect(pw_entry.passwd).to eq('x')
+ expect(shadow_password).to include("!")
end
end
end
@@ -668,7 +681,7 @@ describe Chef::Provider::User::Useradd, metadata do
context "and the user is not locked" do
it "does not update the user" do
- user_resource.should_not be_updated_by_last_action
+ expect(user_resource).not_to be_updated_by_last_action
end
end
diff --git a/spec/functional/resource/windows_service_spec.rb b/spec/functional/resource/windows_service_spec.rb
new file mode 100644
index 0000000000..29d1fc42c3
--- /dev/null
+++ b/spec/functional/resource/windows_service_spec.rb
@@ -0,0 +1,98 @@
+#
+# Author:: Chris Doherty (<cdoherty@chef.io>)
+# Copyright:: Copyright (c) 2014 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 'spec_helper'
+
+describe Chef::Resource::WindowsService, :windows_only, :system_windows_service_gem_only do
+
+ include_context "using Win32::Service"
+
+ let(:username) { "service_spec_user"}
+ let(:qualified_username) { ".\\#{username}"}
+ let(:password) { "1a2b3c4X!&narf"}
+
+ let(:user_resource) {
+ r = Chef::Resource::User.new(username, run_context)
+ r.username(username)
+ r.password(password)
+ r.comment("temp spec user")
+ r
+ }
+
+ let(:global_service_file_path) {
+ "#{ENV['WINDIR']}\\temp\\#{File.basename(test_service[:service_file_path])}"
+ }
+
+ let(:service_params) {
+
+ id = "#{$$}_#{rand(1000)}"
+
+ test_service.merge( {
+ run_as_user: qualified_username,
+ run_as_password: password,
+ service_name: "spec_service_#{id}",
+ service_display_name: "windows_service spec #{id}}",
+ service_description: "Test service for running the windows_service functional spec.",
+ service_file_path: global_service_file_path,
+ } )
+ }
+
+ let(:manager) {
+ Chef::Application::WindowsServiceManager.new(service_params)
+ }
+
+ let(:service_resource) {
+ 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
+ }
+
+ before {
+ user_resource.run_action(:create)
+
+ # the service executable has to be outside the current user's home
+ # directory in order for the logon user to execute it.
+ FileUtils::copy_file(test_service[:service_file_path], global_service_file_path)
+
+ # if you don't make the file executable by the service user, you'll get
+ # the not-very-helpful "service did not respond fast enough" error.
+
+ # #mode may break in a post-Windows 8.1 release, and have to be replaced
+ # with the rights stuff in the file resource.
+ file = Chef::Resource::File.new(global_service_file_path, run_context)
+ file.mode("0777")
+
+ file.run_action(:create)
+
+ manager.run(%w{--action install})
+ }
+
+ after {
+ user_resource.run_action(:remove)
+ manager.run(%w{--action uninstall})
+ File.delete(global_service_file_path)
+ }
+
+ describe "logon as a service" do
+ it "successfully runs a service as another user" do
+ service_resource.run_action(:start)
+ end
+
+ it "raises an exception when it can't grant the logon privilege"
+ end
+end
diff --git a/spec/functional/run_lock_spec.rb b/spec/functional/run_lock_spec.rb
index 9eec0dab04..0cb8635256 100644
--- a/spec/functional/run_lock_spec.rb
+++ b/spec/functional/run_lock_spec.rb
@@ -163,13 +163,13 @@ describe Chef::RunLock do
let!(:run_lock) { Chef::RunLock.new(lockfile) }
it "creates the full path to the lockfile" do
- lambda { run_lock.acquire }.should_not raise_error
- File.should exist(lockfile)
+ expect { run_lock.acquire }.not_to raise_error
+ expect(File).to exist(lockfile)
end
it "sets FD_CLOEXEC on the lockfile", :supports_cloexec => true do
run_lock.acquire
- (run_lock.runlock.fcntl(Fcntl::F_GETFD, 0) & Fcntl::FD_CLOEXEC).should == Fcntl::FD_CLOEXEC
+ expect(run_lock.runlock.fcntl(Fcntl::F_GETFD, 0) & Fcntl::FD_CLOEXEC).to eq(Fcntl::FD_CLOEXEC)
end
it "allows only one chef client run per lockfile" do
@@ -208,7 +208,7 @@ p1 has lock
p1 releasing lock
p2 has lock
E
- results.should == expected
+ expect(results).to eq(expected)
end
it "clears the lock if the process dies unexpectedly" do
@@ -233,12 +233,12 @@ E
Process.waitpid2(p2)
- results.should =~ /p2 has lock\Z/
+ expect(results).to match(/p2 has lock\Z/)
end
it "test returns true and acquires the lock" do
p1 = fork do
- run_lock.test.should == true
+ expect(run_lock.test).to eq(true)
sleep 2
exit! 1
end
@@ -246,7 +246,7 @@ E
wait_on_lock
p2 = fork do
- run_lock.test.should == false
+ expect(run_lock.test).to eq(false)
exit! 0
end
@@ -263,7 +263,7 @@ E
wait_on_lock
- run_lock.test.should == false
+ expect(run_lock.test).to eq(false)
Process.waitpid2(p1)
end
@@ -277,7 +277,7 @@ E
wait_on_lock
sleep 0.5 # Possible race condition on Solaris which pid is observed as 0
- File.read(lockfile).should == p1.to_s
+ expect(File.read(lockfile)).to eq(p1.to_s)
Process.waitpid2(p1)
end
diff --git a/spec/functional/shell_spec.rb b/spec/functional/shell_spec.rb
index f2ce3f53e4..fa9de77b0e 100644
--- a/spec/functional/shell_spec.rb
+++ b/spec/functional/shell_spec.rb
@@ -105,7 +105,7 @@ describe Shell do
it "boots correctly with -lauto" do
output, exitstatus = run_chef_shell_with("-lauto")
- output.should include("done")
+ expect(output).to include("done")
expect(exitstatus).to eq(0)
end
@@ -115,7 +115,7 @@ describe Shell do
keyboard.puts(show_log_level_code)
read_until(out, show_log_level_code)
end
- output.should include("===fatal===")
+ expect(output).to include("===fatal===")
expect(exitstatus).to eq(0)
end
@@ -125,7 +125,7 @@ describe Shell do
keyboard.puts(show_recipes_code)
read_until(out, show_recipes_code)
end
- output.should include(%q{["override::foo", "override::bar"]})
+ expect(output).to include(%q{["override::foo", "override::bar"]})
expect(exitstatus).to eq(0)
end
end
diff --git a/spec/functional/tiny_server_spec.rb b/spec/functional/tiny_server_spec.rb
index bfa6ff1ddb..87be948a0d 100644
--- a/spec/functional/tiny_server_spec.rb
+++ b/spec/functional/tiny_server_spec.rb
@@ -26,39 +26,39 @@ describe TinyServer::API do
end
it "is a Singleton" do
- lambda {TinyServer::API.new}.should raise_error
+ expect {TinyServer::API.new}.to raise_error
end
it "clears the router" do
@api.get('/blargh', 200, "blargh")
@api.clear
- @api.routes["GET"].should be_empty
+ expect(@api.routes["GET"]).to be_empty
end
it "creates a route for a GET request" do
@api.get('/foo/bar', 200, 'hello foobar')
# WEBrick gives you the full URI with host, Thin only gave the part after scheme+host+port
response = @api.call("REQUEST_METHOD" => "GET", "REQUEST_URI" => 'http://localhost:1974/foo/bar')
- response.should == [200, {'Content-Type' => 'application/json'}, [ 'hello foobar' ]]
+ expect(response).to eq([200, {'Content-Type' => 'application/json'}, [ 'hello foobar' ]])
end
it "creates a route for a request with a block" do
block_called = false
@api.get('/bar/baz', 200) { block_called = true; 'hello barbaz' }
response = @api.call("REQUEST_METHOD" => "GET", "REQUEST_URI" => 'http://localhost:1974/bar/baz')
- response.should == [200, {'Content-Type' => 'application/json'}, [ 'hello barbaz' ]]
- block_called.should be_true
+ expect(response).to eq([200, {'Content-Type' => 'application/json'}, [ 'hello barbaz' ]])
+ expect(block_called).to be_truthy
end
it "returns debugging info for 404s" do
response = @api.call("REQUEST_METHOD" => "GET", "REQUEST_URI" => '/no_such_thing')
- response[0].should == 404
- response[1].should == {'Content-Type' => 'application/json'}
- response[2].should be_a_kind_of(Array)
+ expect(response[0]).to eq(404)
+ expect(response[1]).to eq({'Content-Type' => 'application/json'})
+ expect(response[2]).to be_a_kind_of(Array)
response_obj = Chef::JSONCompat.from_json(response[2].first)
- response_obj["message"].should == "no data matches the request for /no_such_thing"
- response_obj["available_routes"].should == {"GET"=>[], "PUT"=>[], "POST"=>[], "DELETE"=>[]}
- response_obj["request"].should == {"REQUEST_METHOD"=>"GET", "REQUEST_URI"=>"/no_such_thing"}
+ expect(response_obj["message"]).to eq("no data matches the request for /no_such_thing")
+ expect(response_obj["available_routes"]).to eq({"GET"=>[], "PUT"=>[], "POST"=>[], "DELETE"=>[]})
+ expect(response_obj["request"]).to eq({"REQUEST_METHOD"=>"GET", "REQUEST_URI"=>"/no_such_thing"})
end
end
@@ -71,7 +71,7 @@ describe TinyServer::Manager do
TinyServer::API.instance.get("/index", 200, "[\"hello\"]")
rest = Chef::REST.new('http://localhost:9000', false, false)
- rest.get_rest("index").should == ["hello"]
+ expect(rest.get_rest("index")).to eq(["hello"])
@server.stop
end
diff --git a/spec/functional/util/path_helper_spec.rb b/spec/functional/util/path_helper_spec.rb
index ccdf383c22..0321702bb8 100644
--- a/spec/functional/util/path_helper_spec.rb
+++ b/spec/functional/util/path_helper_spec.rb
@@ -31,7 +31,7 @@ describe Chef::Util::PathHelper, "escape_glob" do
end
pattern = File.join(PathHelper.escape_glob(dir), "*")
- Dir.glob(pattern).map { |x| File.basename(x) }.should match_array(files)
+ expect(Dir.glob(pattern).map { |x| File.basename(x) }).to match_array(files)
end
end
end
diff --git a/spec/functional/version_spec.rb b/spec/functional/version_spec.rb
index a342206161..cd5bbc7678 100644
--- a/spec/functional/version_spec.rb
+++ b/spec/functional/version_spec.rb
@@ -28,7 +28,7 @@ describe "Chef Versions" do
binaries.each do |binary|
it "#{binary} version should be sane" do
- shell_out!("ruby #{File.join("bin", binary)} -v", :cwd => chef_dir).stdout.chomp.should == "Chef: #{Chef::VERSION}"
+ expect(shell_out!("ruby #{File.join("bin", binary)} -v", :cwd => chef_dir).stdout.chomp).to include("Chef: #{Chef::VERSION}")
end
end
diff --git a/spec/functional/win32/registry_helper_spec.rb b/spec/functional/win32/registry_helper_spec.rb
index 830d6f4777..7b070e6fe1 100644
--- a/spec/functional/win32/registry_helper_spec.rb
+++ b/spec/functional/win32/registry_helper_spec.rb
@@ -34,7 +34,7 @@ describe Chef::Resource::RegistryKey, :unix_only do
it "throws an exception because you don't have a windows registry (derp)" do
@resource.key("HKCU\\Software\\Opscode")
@resource.values([{:name=>"Color", :type=>:string, :data=>"Orange"}])
- lambda{@resource.run_action(:create)}.should raise_error(Chef::Exceptions::Win32NotWindows)
+ expect{@resource.run_action(:create)}.to raise_error(Chef::Exceptions::Win32NotWindows)
end
end
end
@@ -84,197 +84,197 @@ describe 'Chef::Win32::Registry', :windows_only do
describe "hive_exists?" do
it "returns true if the hive exists" do
- @registry.hive_exists?("HKCU\\Software\\Root").should == true
+ expect(@registry.hive_exists?("HKCU\\Software\\Root")).to eq(true)
end
it "returns false if the hive does not exist" do
- hive = @registry.hive_exists?("LYRU\\Software\\Root").should == false
+ hive = expect(@registry.hive_exists?("LYRU\\Software\\Root")).to eq(false)
end
end
describe "key_exists?" do
it "returns true if the key path exists" do
- @registry.key_exists?("HKCU\\Software\\Root\\Branch\\Flower").should == true
+ expect(@registry.key_exists?("HKCU\\Software\\Root\\Branch\\Flower")).to eq(true)
end
it "returns false if the key path does not exist" do
- @registry.key_exists?("HKCU\\Software\\Branch\\Flower").should == false
+ expect(@registry.key_exists?("HKCU\\Software\\Branch\\Flower")).to eq(false)
end
it "throws an exception if the hive does not exist" do
- lambda {@registry.key_exists?("JKLM\\Software\\Branch\\Flower")}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.key_exists?("JKLM\\Software\\Branch\\Flower")}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
end
describe "key_exists!" do
it "returns true if the key path exists" do
- @registry.key_exists!("HKCU\\Software\\Root\\Branch\\Flower").should == true
+ expect(@registry.key_exists!("HKCU\\Software\\Root\\Branch\\Flower")).to eq(true)
end
it "throws an exception if the key path does not exist" do
- lambda {@registry.key_exists!("HKCU\\Software\\Branch\\Flower")}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.key_exists!("HKCU\\Software\\Branch\\Flower")}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "throws an exception if the hive does not exist" do
- lambda {@registry.key_exists!("JKLM\\Software\\Branch\\Flower")}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.key_exists!("JKLM\\Software\\Branch\\Flower")}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
end
describe "value_exists?" do
it "throws an exception if the hive does not exist" do
- lambda {@registry.value_exists?("JKLM\\Software\\Branch\\Flower", {:name=>"Petals"})}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.value_exists?("JKLM\\Software\\Branch\\Flower", {:name=>"Petals"})}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
it "throws an exception if the key does not exist" do
- lambda {@registry.value_exists?("HKCU\\Software\\Branch\\Flower", {:name=>"Petals"})}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.value_exists?("HKCU\\Software\\Branch\\Flower", {:name=>"Petals"})}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "returns true if the value exists" do
- @registry.value_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals"}).should == true
+ expect(@registry.value_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals"})).to eq(true)
end
it "returns false if the value does not exist" do
- @registry.value_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"FOOBAR"}).should == false
+ expect(@registry.value_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"FOOBAR"})).to eq(false)
end
end
describe "value_exists!" do
it "throws an exception if the hive does not exist" do
- lambda {@registry.value_exists!("JKLM\\Software\\Branch\\Flower", {:name=>"Petals"})}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.value_exists!("JKLM\\Software\\Branch\\Flower", {:name=>"Petals"})}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
it "throws an exception if the key does not exist" do
- lambda {@registry.value_exists!("HKCU\\Software\\Branch\\Flower", {:name=>"Petals"})}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.value_exists!("HKCU\\Software\\Branch\\Flower", {:name=>"Petals"})}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "returns true if the value exists" do
- @registry.value_exists!("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals"}).should == true
+ expect(@registry.value_exists!("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals"})).to eq(true)
end
it "throws an exception if the value does not exist" do
- lambda {@registry.value_exists!("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"FOOBAR"})}.should raise_error(Chef::Exceptions::Win32RegValueMissing)
+ expect {@registry.value_exists!("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"FOOBAR"})}.to raise_error(Chef::Exceptions::Win32RegValueMissing)
end
end
describe "data_exists?" do
it "throws an exception if the hive does not exist" do
- lambda {@registry.data_exists?("JKLM\\Software\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Pink", "Delicate"]})}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.data_exists?("JKLM\\Software\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Pink", "Delicate"]})}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
it "throws an exception if the key does not exist" do
- lambda {@registry.data_exists?("HKCU\\Software\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Pink", "Delicate"]})}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.data_exists?("HKCU\\Software\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Pink", "Delicate"]})}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "returns true if all the data matches" do
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Pink", "Delicate"]}).should == true
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Pink", "Delicate"]})).to eq(true)
end
it "returns false if the name does not exist" do
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"slateP", :type=>:multi_string, :data=>["Pink", "Delicate"]}).should == false
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"slateP", :type=>:multi_string, :data=>["Pink", "Delicate"]})).to eq(false)
end
it "returns false if the types do not match" do
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:string, :data=>"Pink"}).should == false
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:string, :data=>"Pink"})).to eq(false)
end
it "returns false if the data does not match" do
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Mauve", "Delicate"]}).should == false
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Mauve", "Delicate"]})).to eq(false)
end
end
describe "data_exists!" do
it "throws an exception if the hive does not exist" do
- lambda {@registry.data_exists!("JKLM\\Software\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Pink", "Delicate"]})}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.data_exists!("JKLM\\Software\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Pink", "Delicate"]})}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
it "throws an exception if the key does not exist" do
- lambda {@registry.data_exists!("HKCU\\Software\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Pink", "Delicate"]})}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.data_exists!("HKCU\\Software\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Pink", "Delicate"]})}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "returns true if all the data matches" do
- @registry.data_exists!("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Pink", "Delicate"]}).should == true
+ expect(@registry.data_exists!("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Pink", "Delicate"]})).to eq(true)
end
it "throws an exception if the name does not exist" do
- lambda {@registry.data_exists!("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"slateP", :type=>:multi_string, :data=>["Pink", "Delicate"]})}.should raise_error(Chef::Exceptions::Win32RegDataMissing)
+ expect {@registry.data_exists!("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"slateP", :type=>:multi_string, :data=>["Pink", "Delicate"]})}.to raise_error(Chef::Exceptions::Win32RegDataMissing)
end
it "throws an exception if the types do not match" do
- lambda {@registry.data_exists!("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:string, :data=>"Pink"})}.should raise_error(Chef::Exceptions::Win32RegDataMissing)
+ expect {@registry.data_exists!("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:string, :data=>"Pink"})}.to raise_error(Chef::Exceptions::Win32RegDataMissing)
end
it "throws an exception if the data does not match" do
- lambda {@registry.data_exists!("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Mauve", "Delicate"]})}.should raise_error(Chef::Exceptions::Win32RegDataMissing)
+ expect {@registry.data_exists!("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Mauve", "Delicate"]})}.to raise_error(Chef::Exceptions::Win32RegDataMissing)
end
end
describe "get_values" do
it "returns all values for a key if it exists" do
values = @registry.get_values("HKCU\\Software\\Root")
- values.should be_an_instance_of Array
- values.should == [{:name=>"RootType1", :type=>:string, :data=>"fibrous"},
- {:name=>"Roots", :type=>:multi_string, :data=>["strong roots", "healthy tree"]}]
+ expect(values).to be_an_instance_of Array
+ expect(values).to eq([{:name=>"RootType1", :type=>:string, :data=>"fibrous"},
+ {:name=>"Roots", :type=>:multi_string, :data=>["strong roots", "healthy tree"]}])
end
it "throws an exception if the key does not exist" do
- lambda {@registry.get_values("HKCU\\Software\\Branch\\Flower")}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.get_values("HKCU\\Software\\Branch\\Flower")}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "throws an exception if the hive does not exist" do
- lambda {@registry.get_values("JKLM\\Software\\Branch\\Flower")}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.get_values("JKLM\\Software\\Branch\\Flower")}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
end
describe "set_value" do
it "updates a value if the key, value exist and type matches and value different" do
- @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Yellow", "Changed Color"]}).should == true
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Yellow", "Changed Color"]}).should == true
+ expect(@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Yellow", "Changed Color"]})).to eq(true)
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Yellow", "Changed Color"]})).to eq(true)
end
it "updates a value if the type does match and the values are different" do
- @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:string, :data=>"Yellow"}).should == true
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:string, :data=>"Yellow"}).should == true
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Yellow", "Changed Color"]}).should == false
+ expect(@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:string, :data=>"Yellow"})).to eq(true)
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:string, :data=>"Yellow"})).to eq(true)
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Yellow", "Changed Color"]})).to eq(false)
end
it "creates a value if key exists and value does not" do
- @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Stamen", :type=>:multi_string, :data=>["Yellow", "Changed Color"]}).should == true
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Stamen", :type=>:multi_string, :data=>["Yellow", "Changed Color"]}).should == true
+ expect(@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Stamen", :type=>:multi_string, :data=>["Yellow", "Changed Color"]})).to eq(true)
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Stamen", :type=>:multi_string, :data=>["Yellow", "Changed Color"]})).to eq(true)
end
it "does nothing if data,type and name parameters for the value are same" do
- @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Stamen", :type=>:multi_string, :data=>["Yellow", "Changed Color"]}).should == false
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Stamen", :type=>:multi_string, :data=>["Yellow", "Changed Color"]}).should == true
+ expect(@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Stamen", :type=>:multi_string, :data=>["Yellow", "Changed Color"]})).to eq(false)
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"Stamen", :type=>:multi_string, :data=>["Yellow", "Changed Color"]})).to eq(true)
end
it "throws an exception if the key does not exist" do
- lambda {@registry.set_value("HKCU\\Software\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Yellow", "Changed Color"]})}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.set_value("HKCU\\Software\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Yellow", "Changed Color"]})}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "throws an exception if the hive does not exist" do
- lambda {@registry.set_value("JKLM\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Yellow", "Changed Color"]})}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.set_value("JKLM\\Software\\Root\\Branch\\Flower", {:name=>"Petals", :type=>:multi_string, :data=>["Yellow", "Changed Color"]})}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
# we are validating that the data gets .to_i called on it when type is a :dword
it "casts an integer string given as a dword into an integer" do
- @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBe32767", :type=>:dword, :data=>"32767"}).should == true
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBe32767", :type=>:dword, :data=>32767}).should == true
+ expect(@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBe32767", :type=>:dword, :data=>"32767"})).to eq(true)
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBe32767", :type=>:dword, :data=>32767})).to eq(true)
end
it "casts a nonsense string given as a dword into zero" do
- @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBeZero", :type=>:dword, :data=>"whatdoesthisdo"}).should == true
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBeZero", :type=>:dword, :data=>0}).should == true
+ expect(@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBeZero", :type=>:dword, :data=>"whatdoesthisdo"})).to eq(true)
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBeZero", :type=>:dword, :data=>0})).to eq(true)
end
it "throws an exception when trying to cast an array to an int for a dword" do
- lambda {@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldThrow", :type=>:dword, :data=>["one","two"]})}.should raise_error
+ expect {@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldThrow", :type=>:dword, :data=>["one","two"]})}.to raise_error
end
# we are validating that the data gets .to_s called on it when type is a :string
it "stores the string representation of an array into a string if you pass it an array" do
- @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBePainful", :type=>:string, :data=>["one","two"]}).should == true
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBePainful", :type=>:string, :data=>'["one", "two"]'}).should == true
+ expect(@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBePainful", :type=>:string, :data=>["one","two"]})).to eq(true)
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBePainful", :type=>:string, :data=>'["one", "two"]'})).to eq(true)
end
it "stores the string representation of a number into a string if you pass it an number" do
- @registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBe65535", :type=>:string, :data=>65535}).should == true
- @registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBe65535", :type=>:string, :data=>"65535"}).should == true
+ expect(@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBe65535", :type=>:string, :data=>65535})).to eq(true)
+ expect(@registry.data_exists?("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBe65535", :type=>:string, :data=>"65535"})).to eq(true)
end
# we are validating that the data gets .to_a called on it when type is a :multi_string
it "throws an exception when a multi-string is passed a number" do
- lambda {@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldThrow", :type=>:multi_string, :data=>65535})}.should raise_error
+ expect {@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldThrow", :type=>:multi_string, :data=>65535})}.to raise_error
end
it "throws an exception when a multi-string is passed a string" do
- lambda {@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBeWat", :type=>:multi_string, :data=>"foo"})}.should raise_error
+ expect {@registry.set_value("HKCU\\Software\\Root\\Branch\\Flower", {:name=>"ShouldBeWat", :type=>:multi_string, :data=>"foo"})}.to raise_error
end
end
@@ -289,22 +289,22 @@ describe 'Chef::Win32::Registry', :windows_only do
end
it "throws an exception if the path has missing keys but recursive set to false" do
- lambda {@registry.create_key("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", false)}.should raise_error(Chef::Exceptions::Win32RegNoRecursive)
- @registry.key_exists?("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker").should == false
+ expect {@registry.create_key("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", false)}.to raise_error(Chef::Exceptions::Win32RegNoRecursive)
+ expect(@registry.key_exists?("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker")).to eq(false)
end
it "creates the key_path if the keys were missing but recursive was set to true" do
- @registry.create_key("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", true).should == true
- @registry.key_exists?("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker").should == true
+ expect(@registry.create_key("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", true)).to eq(true)
+ expect(@registry.key_exists?("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker")).to eq(true)
end
it "does nothing if the key already exists" do
- @registry.create_key("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", false).should == true
- @registry.key_exists?("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker").should == true
+ expect(@registry.create_key("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", false)).to eq(true)
+ expect(@registry.key_exists?("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker")).to eq(true)
end
it "throws an exception of the hive does not exist" do
- lambda {@registry.create_key("JKLM\\Software\\Root\\Trunk\\Peck\\Woodpecker", false)}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.create_key("JKLM\\Software\\Root\\Trunk\\Peck\\Woodpecker", false)}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
end
@@ -317,21 +317,21 @@ describe 'Chef::Win32::Registry', :windows_only do
end
it "deletes values if the value exists" do
- @registry.delete_value("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", {:name=>"Peter", :type=>:string, :data=>"Tiny"}).should == true
- @registry.value_exists?("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", {:name=>"Peter", :type=>:string, :data=>"Tiny"}).should == false
+ expect(@registry.delete_value("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", {:name=>"Peter", :type=>:string, :data=>"Tiny"})).to eq(true)
+ expect(@registry.value_exists?("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", {:name=>"Peter", :type=>:string, :data=>"Tiny"})).to eq(false)
end
it "does nothing if value does not exist" do
- @registry.delete_value("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", {:name=>"Peter", :type=>:string, :data=>"Tiny"}).should == true
- @registry.value_exists?("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", {:name=>"Peter", :type=>:string, :data=>"Tiny"}).should == false
+ expect(@registry.delete_value("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", {:name=>"Peter", :type=>:string, :data=>"Tiny"})).to eq(true)
+ expect(@registry.value_exists?("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker", {:name=>"Peter", :type=>:string, :data=>"Tiny"})).to eq(false)
end
it "throws an exception if the key does not exist?" do
- lambda {@registry.delete_value("HKCU\\Software\\Trunk\\Peck\\Woodpecker", {:name=>"Peter", :type=>:string, :data=>"Tiny"})}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.delete_value("HKCU\\Software\\Trunk\\Peck\\Woodpecker", {:name=>"Peter", :type=>:string, :data=>"Tiny"})}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "throws an exception if the hive does not exist" do
- lambda {@registry.delete_value("JKLM\\Software\\Root\\Trunk\\Peck\\Woodpecker", {:name=>"Peter", :type=>:string, :data=>"Tiny"})}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.delete_value("JKLM\\Software\\Root\\Trunk\\Peck\\Woodpecker", {:name=>"Peter", :type=>:string, :data=>"Tiny"})}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
end
@@ -348,27 +348,27 @@ describe 'Chef::Win32::Registry', :windows_only do
end
it "deletes a key if it has no subkeys" do
- @registry.delete_key("HKCU\\Software\\Root\\Branch\\Fruit", false).should == true
- @registry.key_exists?("HKCU\\Software\\Root\\Branch\\Fruit").should == false
+ expect(@registry.delete_key("HKCU\\Software\\Root\\Branch\\Fruit", false)).to eq(true)
+ expect(@registry.key_exists?("HKCU\\Software\\Root\\Branch\\Fruit")).to eq(false)
end
it "throws an exception if key to delete has subkeys and recursive is false" do
- lambda { @registry.delete_key("HKCU\\Software\\Root\\Trunk", false) }.should raise_error(Chef::Exceptions::Win32RegNoRecursive)
- @registry.key_exists?("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker").should == true
+ expect { @registry.delete_key("HKCU\\Software\\Root\\Trunk", false) }.to raise_error(Chef::Exceptions::Win32RegNoRecursive)
+ expect(@registry.key_exists?("HKCU\\Software\\Root\\Trunk\\Peck\\Woodpecker")).to eq(true)
end
it "deletes a key if it has subkeys and recursive true" do
- @registry.delete_key("HKCU\\Software\\Root\\Trunk", true).should == true
- @registry.key_exists?("HKCU\\Software\\Root\\Trunk").should == false
+ expect(@registry.delete_key("HKCU\\Software\\Root\\Trunk", true)).to eq(true)
+ expect(@registry.key_exists?("HKCU\\Software\\Root\\Trunk")).to eq(false)
end
it "does nothing if the key does not exist" do
- @registry.delete_key("HKCU\\Software\\Root\\Trunk", true).should == true
- @registry.key_exists?("HKCU\\Software\\Root\\Trunk").should == false
+ expect(@registry.delete_key("HKCU\\Software\\Root\\Trunk", true)).to eq(true)
+ expect(@registry.key_exists?("HKCU\\Software\\Root\\Trunk")).to eq(false)
end
it "throws an exception if the hive does not exist" do
- lambda {@registry.delete_key("JKLM\\Software\\Root\\Branch\\Flower", false)}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.delete_key("JKLM\\Software\\Root\\Branch\\Flower", false)}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
end
@@ -384,29 +384,29 @@ describe 'Chef::Win32::Registry', :windows_only do
end
it "throws an exception if the hive was missing" do
- lambda {@registry.has_subkeys?("LMNO\\Software\\Root")}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.has_subkeys?("LMNO\\Software\\Root")}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
it "throws an exception if the key is missing" do
- lambda {@registry.has_subkeys?("HKCU\\Software\\Root\\Trunk\\Red")}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.has_subkeys?("HKCU\\Software\\Root\\Trunk\\Red")}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "returns true if the key has subkeys" do
- @registry.has_subkeys?("HKCU\\Software\\Root").should == true
+ expect(@registry.has_subkeys?("HKCU\\Software\\Root")).to eq(true)
end
it "returns false if the key has no subkeys" do
::Win32::Registry::HKEY_CURRENT_USER.create "Software\\Root\\Trunk\\Red"
- @registry.has_subkeys?("HKCU\\Software\\Root\\Trunk\\Red").should == false
+ expect(@registry.has_subkeys?("HKCU\\Software\\Root\\Trunk\\Red")).to eq(false)
end
end
describe "get_subkeys" do
it "throws an exception if the key is missing" do
- lambda {@registry.get_subkeys("HKCU\\Software\\Trunk\\Red")}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.get_subkeys("HKCU\\Software\\Trunk\\Red")}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "throws an exception if the hive does not exist" do
- lambda {@registry.get_subkeys("JKLM\\Software\\Root")}.should raise_error(Chef::Exceptions::Win32RegHiveMissing)
+ expect {@registry.get_subkeys("JKLM\\Software\\Root")}.to raise_error(Chef::Exceptions::Win32RegHiveMissing)
end
it "returns the array of subkeys for a given key" do
subkeys = @registry.get_subkeys("HKCU\\Software\\Root")
@@ -414,7 +414,7 @@ describe 'Chef::Win32::Registry', :windows_only do
::Win32::Registry::HKEY_CURRENT_USER.open("Software\\Root", Win32::Registry::KEY_ALL_ACCESS) do |reg|
reg.each_key{|name| reg_subkeys << name}
end
- reg_subkeys.should == subkeys
+ expect(reg_subkeys).to eq(subkeys)
end
end
@@ -431,37 +431,37 @@ describe 'Chef::Win32::Registry', :windows_only do
context "registry constructor" do
it "throws an exception if requested architecture is 64bit but running on 32bit" do
- lambda {Chef::Win32::Registry.new(@run_context, :x86_64)}.should raise_error(Chef::Exceptions::Win32RegArchitectureIncorrect)
+ expect {Chef::Win32::Registry.new(@run_context, :x86_64)}.to raise_error(Chef::Exceptions::Win32RegArchitectureIncorrect)
end
it "can correctly set the requested architecture to 32-bit" do
@r = Chef::Win32::Registry.new(@run_context, :i386)
- @r.architecture.should == :i386
- @r.registry_system_architecture.should == 0x0200
+ expect(@r.architecture).to eq(:i386)
+ expect(@r.registry_system_architecture).to eq(0x0200)
end
it "can correctly set the requested architecture to :machine" do
@r = Chef::Win32::Registry.new(@run_context, :machine)
- @r.architecture.should == :machine
- @r.registry_system_architecture.should == 0x0200
+ expect(@r.architecture).to eq(:machine)
+ expect(@r.registry_system_architecture).to eq(0x0200)
end
end
context "architecture setter" do
it "throws an exception if requested architecture is 64bit but running on 32bit" do
- lambda {@registry.architecture = :x86_64}.should raise_error(Chef::Exceptions::Win32RegArchitectureIncorrect)
+ expect {@registry.architecture = :x86_64}.to raise_error(Chef::Exceptions::Win32RegArchitectureIncorrect)
end
it "sets the requested architecture to :machine if passed :machine" do
@registry.architecture = :machine
- @registry.architecture.should == :machine
- @registry.registry_system_architecture.should == 0x0200
+ expect(@registry.architecture).to eq(:machine)
+ expect(@registry.registry_system_architecture).to eq(0x0200)
end
it "sets the requested architecture to 32-bit if passed i386 as a string" do
@registry.architecture = :i386
- @registry.architecture.should == :i386
- @registry.registry_system_architecture.should == 0x0200
+ expect(@registry.architecture).to eq(:i386)
+ expect(@registry.registry_system_architecture).to eq(0x0200)
end
end
end
@@ -479,40 +479,40 @@ describe 'Chef::Win32::Registry', :windows_only do
context "registry constructor" do
it "can correctly set the requested architecture to 32-bit" do
@r = Chef::Win32::Registry.new(@run_context, :i386)
- @r.architecture.should == :i386
- @r.registry_system_architecture.should == 0x0200
+ expect(@r.architecture).to eq(:i386)
+ expect(@r.registry_system_architecture).to eq(0x0200)
end
it "can correctly set the requested architecture to 64-bit" do
@r = Chef::Win32::Registry.new(@run_context, :x86_64)
- @r.architecture.should == :x86_64
- @r.registry_system_architecture.should == 0x0100
+ expect(@r.architecture).to eq(:x86_64)
+ expect(@r.registry_system_architecture).to eq(0x0100)
end
it "can correctly set the requested architecture to :machine" do
@r = Chef::Win32::Registry.new(@run_context, :machine)
- @r.architecture.should == :machine
- @r.registry_system_architecture.should == 0x0100
+ expect(@r.architecture).to eq(:machine)
+ expect(@r.registry_system_architecture).to eq(0x0100)
end
end
context "architecture setter" do
it "sets the requested architecture to 64-bit if passed 64-bit" do
@registry.architecture = :x86_64
- @registry.architecture.should == :x86_64
- @registry.registry_system_architecture.should == 0x0100
+ expect(@registry.architecture).to eq(:x86_64)
+ expect(@registry.registry_system_architecture).to eq(0x0100)
end
it "sets the requested architecture to :machine if passed :machine" do
@registry.architecture = :machine
- @registry.architecture.should == :machine
- @registry.registry_system_architecture.should == 0x0100
+ expect(@registry.architecture).to eq(:machine)
+ expect(@registry.registry_system_architecture).to eq(0x0100)
end
it "sets the requested architecture to 32-bit if passed 32-bit" do
@registry.architecture = :i386
- @registry.architecture.should == :i386
- @registry.registry_system_architecture.should == 0x0200
+ expect(@registry.architecture).to eq(:i386)
+ expect(@registry.registry_system_architecture).to eq(0x0200)
end
end
end
@@ -555,75 +555,75 @@ describe 'Chef::Win32::Registry', :windows_only do
describe "key_exists?" do
it "does not find 64-bit keys in the 32-bit registry" do
@registry.architecture=:i386
- @registry.key_exists?("HKLM\\Software\\Root\\Mauve").should == false
+ expect(@registry.key_exists?("HKLM\\Software\\Root\\Mauve")).to eq(false)
end
it "finds 32-bit keys in the 32-bit registry" do
@registry.architecture=:i386
- @registry.key_exists?("HKLM\\Software\\Root\\Poosh").should == true
+ expect(@registry.key_exists?("HKLM\\Software\\Root\\Poosh")).to eq(true)
end
it "does not find 32-bit keys in the 64-bit registry" do
@registry.architecture=:x86_64
- @registry.key_exists?("HKLM\\Software\\Root\\Mauve").should == true
+ expect(@registry.key_exists?("HKLM\\Software\\Root\\Mauve")).to eq(true)
end
it "finds 64-bit keys in the 64-bit registry" do
@registry.architecture=:x86_64
- @registry.key_exists?("HKLM\\Software\\Root\\Poosh").should == false
+ expect(@registry.key_exists?("HKLM\\Software\\Root\\Poosh")).to eq(false)
end
end
describe "value_exists?" do
it "does not find 64-bit values in the 32-bit registry" do
@registry.architecture=:i386
- lambda{@registry.value_exists?("HKLM\\Software\\Root\\Mauve", {:name=>"Alert"})}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect{@registry.value_exists?("HKLM\\Software\\Root\\Mauve", {:name=>"Alert"})}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "finds 32-bit values in the 32-bit registry" do
@registry.architecture=:i386
- @registry.value_exists?("HKLM\\Software\\Root\\Poosh", {:name=>"Status"}).should == true
+ expect(@registry.value_exists?("HKLM\\Software\\Root\\Poosh", {:name=>"Status"})).to eq(true)
end
it "does not find 32-bit values in the 64-bit registry" do
@registry.architecture=:x86_64
- @registry.value_exists?("HKLM\\Software\\Root\\Mauve", {:name=>"Alert"}).should == true
+ expect(@registry.value_exists?("HKLM\\Software\\Root\\Mauve", {:name=>"Alert"})).to eq(true)
end
it "finds 64-bit values in the 64-bit registry" do
@registry.architecture=:x86_64
- lambda{@registry.value_exists?("HKLM\\Software\\Root\\Poosh", {:name=>"Status"})}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect{@registry.value_exists?("HKLM\\Software\\Root\\Poosh", {:name=>"Status"})}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
end
describe "data_exists?" do
it "does not find 64-bit keys in the 32-bit registry" do
@registry.architecture=:i386
- lambda{@registry.data_exists?("HKLM\\Software\\Root\\Mauve", {:name=>"Alert", :type=>:string, :data=>"Universal"})}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect{@registry.data_exists?("HKLM\\Software\\Root\\Mauve", {:name=>"Alert", :type=>:string, :data=>"Universal"})}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "finds 32-bit keys in the 32-bit registry" do
@registry.architecture=:i386
- @registry.data_exists?("HKLM\\Software\\Root\\Poosh", {:name=>"Status", :type=>:string, :data=>"Lost"}).should == true
+ expect(@registry.data_exists?("HKLM\\Software\\Root\\Poosh", {:name=>"Status", :type=>:string, :data=>"Lost"})).to eq(true)
end
it "does not find 32-bit keys in the 64-bit registry" do
@registry.architecture=:x86_64
- @registry.data_exists?("HKLM\\Software\\Root\\Mauve", {:name=>"Alert", :type=>:string, :data=>"Universal"}).should == true
+ expect(@registry.data_exists?("HKLM\\Software\\Root\\Mauve", {:name=>"Alert", :type=>:string, :data=>"Universal"})).to eq(true)
end
it "finds 64-bit keys in the 64-bit registry" do
@registry.architecture=:x86_64
- lambda{@registry.data_exists?("HKLM\\Software\\Root\\Poosh", {:name=>"Status", :type=>:string, :data=>"Lost"})}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect{@registry.data_exists?("HKLM\\Software\\Root\\Poosh", {:name=>"Status", :type=>:string, :data=>"Lost"})}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
end
describe "create_key" do
it "can create a 32-bit only registry key" do
@registry.architecture = :i386
- @registry.create_key("HKLM\\Software\\Root\\Trunk\\Red", true).should == true
- @registry.key_exists?("HKLM\\Software\\Root\\Trunk\\Red").should == true
+ expect(@registry.create_key("HKLM\\Software\\Root\\Trunk\\Red", true)).to eq(true)
+ expect(@registry.key_exists?("HKLM\\Software\\Root\\Trunk\\Red")).to eq(true)
@registry.architecture = :x86_64
- @registry.key_exists?("HKLM\\Software\\Root\\Trunk\\Red").should == false
+ expect(@registry.key_exists?("HKLM\\Software\\Root\\Trunk\\Red")).to eq(false)
end
it "can create a 64-bit only registry key" do
@registry.architecture = :x86_64
- @registry.create_key("HKLM\\Software\\Root\\Trunk\\Blue", true).should == true
- @registry.key_exists?("HKLM\\Software\\Root\\Trunk\\Blue").should == true
+ expect(@registry.create_key("HKLM\\Software\\Root\\Trunk\\Blue", true)).to eq(true)
+ expect(@registry.key_exists?("HKLM\\Software\\Root\\Trunk\\Blue")).to eq(true)
@registry.architecture = :i386
- @registry.key_exists?("HKLM\\Software\\Root\\Trunk\\Blue").should == false
+ expect(@registry.key_exists?("HKLM\\Software\\Root\\Trunk\\Blue")).to eq(false)
end
end
diff --git a/spec/functional/win32/security_spec.rb b/spec/functional/win32/security_spec.rb
index 4ad9b07b74..27af263860 100644
--- a/spec/functional/win32/security_spec.rb
+++ b/spec/functional/win32/security_spec.rb
@@ -23,7 +23,7 @@ end
describe 'Chef::Win32::Security', :windows_only do
it "has_admin_privileges? returns true when running as admin" do
- Chef::ReservedNames::Win32::Security.has_admin_privileges?.should == true
+ expect(Chef::ReservedNames::Win32::Security.has_admin_privileges?).to eq(true)
end
# We've done some investigation adding a negative test and it turned
@@ -32,6 +32,69 @@ describe 'Chef::Win32::Security', :windows_only do
#
# TODO - Add negative tests once mixlib-shellout has user support
it "has_admin_privileges? returns false when running as non-admin" do
- pending "requires user support in mixlib-shellout"
+ skip "requires user support in mixlib-shellout"
+ end
+
+ describe 'get_file_security' do
+ it 'should return a security descriptor when called with a path that exists' do
+ security_descriptor = Chef::ReservedNames::Win32::Security.get_file_security(
+ "C:\\Program Files")
+ # Make sure the security descriptor works
+ expect(security_descriptor.dacl_present?).to be true
+ end
+ end
+
+ describe 'access_check' do
+ let(:security_descriptor) {
+ Chef::ReservedNames::Win32::Security.get_file_security(
+ "C:\\Program Files")
+ }
+
+ let(:token_rights) { Chef::ReservedNames::Win32::Security::TOKEN_ALL_ACCESS }
+
+ let(:token) {
+ Chef::ReservedNames::Win32::Security.open_process_token(
+ Chef::ReservedNames::Win32::Process.get_current_process,
+ token_rights).duplicate_token(:SecurityImpersonation)
+ }
+
+ let(:mapping) {
+ 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
+ }
+
+ let(:desired_access) { Chef::ReservedNames::Win32::Security::FILE_GENERIC_READ }
+
+ it 'should check if the provided token has the desired access' do
+ expect(Chef::ReservedNames::Win32::Security.access_check(security_descriptor,
+ token, desired_access, mapping)).to be true
+ end
+ end
+
+ describe 'Chef::Win32::Security::Token' do
+ let(:token) {
+ Chef::ReservedNames::Win32::Security.open_process_token(
+ Chef::ReservedNames::Win32::Process.get_current_process,
+ token_rights)
+ }
+ context 'with all rights' do
+ let(:token_rights) { Chef::ReservedNames::Win32::Security::TOKEN_ALL_ACCESS }
+
+ it 'can duplicate a token' do
+ expect{ token.duplicate_token(:SecurityImpersonation) }.not_to raise_error
+ end
+ end
+
+ context 'with read only rights' do
+ let(:token_rights) { Chef::ReservedNames::Win32::Security::TOKEN_READ }
+
+ it 'raises an exception when trying to duplicate' do
+ expect{ token.duplicate_token(:SecurityImpersonation) }.to raise_error(Chef::Exceptions::Win32APIError)
+ end
+ end
end
end
diff --git a/spec/functional/win32/service_manager_spec.rb b/spec/functional/win32/service_manager_spec.rb
index b5b2e20825..d2474deace 100644
--- a/spec/functional/win32/service_manager_spec.rb
+++ b/spec/functional/win32/service_manager_spec.rb
@@ -24,7 +24,7 @@ end
#
# ATTENTION:
# This test creates a windows service for testing purposes and runs it
-# as Local System on windows boxes.
+# as Local System (or an otherwise specified user) on windows boxes.
# This test will fail if you run the tests inside a Windows VM by
# sharing the code from your host since Local System account by
# default can't see the mounted partitions.
@@ -35,65 +35,11 @@ end
describe "Chef::Application::WindowsServiceManager", :windows_only, :system_windows_service_gem_only do
- # Some helper methods.
-
- def test_service_exists?
- ::Win32::Service.exists?("spec-service")
- end
-
- def test_service_state
- ::Win32::Service.status("spec-service").current_state
- end
-
- def service_manager
- Chef::Application::WindowsServiceManager.new(test_service)
- end
-
- def cleanup
- # Uninstall if the test service is installed.
- if test_service_exists?
-
- # 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
- end
-
- ::Win32::Service.delete("spec-service")
- end
-
- # Delete the test_service_file if it exists
- if File.exists?(test_service_file)
- File.delete(test_service_file)
- end
-
- end
-
-
- # Definition for the test-service
-
- let(:test_service) {
- {
- :service_name => "spec-service",
- :service_display_name => "Spec Test Service",
- :service_description => "Service for testing Chef::Application::WindowsServiceManager.",
- :service_file_path => File.expand_path(File.join(File.dirname(__FILE__), '../../support/platforms/win32/spec_service.rb'))
- }
- }
-
- # 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) {
- "#{ENV['SystemDrive']}\\windows\\temp\\spec_service_file"
- }
+ include_context "using Win32::Service"
context "with invalid service definition" do
it "throws an error when initialized with no service definition" do
- lambda { Chef::Application::WindowsServiceManager.new(nil) }.should raise_error(ArgumentError)
+ expect { Chef::Application::WindowsServiceManager.new(nil) }.to raise_error(ArgumentError)
end
it "throws an error with required missing options" do
@@ -101,7 +47,7 @@ describe "Chef::Application::WindowsServiceManager", :windows_only, :system_wind
service_def = test_service.dup
service_def.delete(key)
- lambda { Chef::Application::WindowsServiceManager.new(service_def) }.should raise_error(ArgumentError)
+ expect { Chef::Application::WindowsServiceManager.new(service_def) }.to raise_error(ArgumentError)
end
end
end
@@ -111,7 +57,7 @@ describe "Chef::Application::WindowsServiceManager", :windows_only, :system_wind
@service_manager_output = [ ]
# Uncomment below lines to debug this test
# original_puts = $stdout.method(:puts)
- $stdout.stub(:puts) do |message|
+ allow($stdout).to receive(:puts) do |message|
@service_manager_output << message
# original_puts.call(message)
end
@@ -125,19 +71,19 @@ describe "Chef::Application::WindowsServiceManager", :windows_only, :system_wind
it "default => should say service don't exist" do
service_manager.run
- @service_manager_output.grep(/doesn't exist on the system/).length.should > 0
+ expect(@service_manager_output.grep(/doesn't exist on the system/).length).to be > 0
end
it "install => should install the service" do
service_manager.run(["-a", "install"])
- test_service_exists?.should be_true
+ expect(test_service_exists?).to be_truthy
end
it "other actions => should say service doesn't exist" do
["delete", "start", "stop", "pause", "resume", "uninstall"].each do |action|
service_manager.run(["-a", action])
- @service_manager_output.grep(/doesn't exist on the system/).length.should > 0
+ expect(@service_manager_output.grep(/doesn't exist on the system/).length).to be > 0
@service_manager_output = [ ]
end
end
@@ -150,47 +96,47 @@ describe "Chef::Application::WindowsServiceManager", :windows_only, :system_wind
it "should have an own-process, non-interactive type" do
status = ::Win32::Service.status("spec-service")
- status[:service_type].should == "own process"
- status[:interactive].should be_false
+ expect(status[:service_type]).to eq("own process")
+ expect(status[:interactive]).to be_falsey
end
it "install => should say service already exists" do
service_manager.run(["-a", "install"])
- @service_manager_output.grep(/already exists/).length.should > 0
+ expect(@service_manager_output.grep(/already exists/).length).to be > 0
end
context "and service is stopped" do
["delete", "uninstall"].each do |action|
it "#{action} => should remove the service", :volatile do
service_manager.run(["-a", action])
- test_service_exists?.should be_false
+ expect(test_service_exists?).to be_falsey
end
end
it "default, status => should say service is stopped" do
service_manager.run([ ])
- @service_manager_output.grep(/stopped/).length.should > 0
+ expect(@service_manager_output.grep(/stopped/).length).to be > 0
@service_manager_output = [ ]
service_manager.run(["-a", "status"])
- @service_manager_output.grep(/stopped/).length.should > 0
+ expect(@service_manager_output.grep(/stopped/).length).to be > 0
end
it "start should start the service", :volatile do
service_manager.run(["-a", "start"])
- test_service_state.should == "running"
- File.exists?(test_service_file).should be_true
+ expect(test_service_state).to eq("running")
+ expect(File.exists?(test_service_file)).to be_truthy
end
it "stop should not affect the service" do
service_manager.run(["-a", "stop"])
- test_service_state.should == "stopped"
+ expect(test_service_state).to eq("stopped")
end
["pause", "resume"].each do |action|
it "#{action} => should raise error" do
- lambda {service_manager.run(["-a", action])}.should raise_error(::Win32::Service::Error)
+ expect { service_manager.run(["-a", action]) }.to raise_error(SystemCallError)
end
end
@@ -202,32 +148,32 @@ describe "Chef::Application::WindowsServiceManager", :windows_only, :system_wind
["delete", "uninstall"].each do |action|
it "#{action} => should remove the service", :volatile do
service_manager.run(["-a", action])
- test_service_exists?.should be_false
+ expect(test_service_exists?).to be_falsey
end
end
it "default, status => should say service is running" do
service_manager.run([ ])
- @service_manager_output.grep(/running/).length.should > 0
+ expect(@service_manager_output.grep(/running/).length).to be > 0
@service_manager_output = [ ]
service_manager.run(["-a", "status"])
- @service_manager_output.grep(/running/).length.should > 0
+ expect(@service_manager_output.grep(/running/).length).to be > 0
end
it "stop should stop the service" do
service_manager.run(["-a", "stop"])
- test_service_state.should == "stopped"
+ expect(test_service_state).to eq("stopped")
end
it "pause should pause the service" do
service_manager.run(["-a", "pause"])
- test_service_state.should == "paused"
+ expect(test_service_state).to eq("paused")
end
it "resume should have no affect" do
service_manager.run(["-a", "resume"])
- test_service_state.should == "running"
+ expect(test_service_state).to eq("running")
end
end
@@ -241,31 +187,31 @@ describe "Chef::Application::WindowsServiceManager", :windows_only, :system_wind
actions.each do |action|
it "#{action} => should remove the service" do
service_manager.run(["-a", action])
- test_service_exists?.should be_false
+ expect(test_service_exists?).to be_falsey
end
end
it "default, status => should say service is paused" do
service_manager.run([ ])
- @service_manager_output.grep(/paused/).length.should > 0
+ expect(@service_manager_output.grep(/paused/).length).to be > 0
@service_manager_output = [ ]
service_manager.run(["-a", "status"])
- @service_manager_output.grep(/paused/).length.should > 0
+ expect(@service_manager_output.grep(/paused/).length).to be > 0
end
it "stop should stop the service" do
service_manager.run(["-a", "stop"])
- test_service_state.should == "stopped"
+ expect(test_service_state).to eq("stopped")
end
it "pause should not affect the service" do
service_manager.run(["-a", "pause"])
- test_service_state.should == "paused"
+ expect(test_service_state).to eq("paused")
end
it "start should raise an error" do
- lambda {service_manager.run(["-a", "start"])}.should raise_error(::Win32::Service::Error)
+ expect {service_manager.run(["-a", "start"])}.to raise_error(::Win32::Service::Error)
end
end
diff --git a/spec/functional/win32/versions_spec.rb b/spec/functional/win32/versions_spec.rb
index 6c8f6b2aaa..38af47b0c9 100644
--- a/spec/functional/win32/versions_spec.rb
+++ b/spec/functional/win32/versions_spec.rb
@@ -62,8 +62,8 @@ describe "Chef::ReservedNames::Win32::Version", :windows_only, :not_supported_on
it "should have have one method for each marketing version" do
versions = 0
for_each_windows_version { versions += 1 }
- versions.should > 0
- versions.should == Chef::ReservedNames::Win32::Version::WIN_VERSIONS.length
+ expect(versions).to be > 0
+ expect(versions).to eq(Chef::ReservedNames::Win32::Version::WIN_VERSIONS.length)
end
it "should only contain version methods with legal method names" do
@@ -71,8 +71,8 @@ describe "Chef::ReservedNames::Win32::Version", :windows_only, :not_supported_on
for_each_windows_version do |method_name|
method_match = method_name_pattern.match(method_name.to_s)
- method_match.should_not be_nil
- method_name.to_s.should == method_match[0]
+ expect(method_match).not_to be_nil
+ expect(method_name.to_s).to eq(method_match[0])
end
end
@@ -81,7 +81,7 @@ describe "Chef::ReservedNames::Win32::Version", :windows_only, :not_supported_on
for_each_windows_version do |method_name|
true_versions += 1 if @version.send(method_name)
end
- true_versions.should == 1
+ expect(true_versions).to eq(1)
end
it "should successfully execute all version methods" do
@@ -91,7 +91,7 @@ describe "Chef::ReservedNames::Win32::Version", :windows_only, :not_supported_on
context "Windows Operating System version" do
it "should match the version from WMI" do
- @current_os_version.should include(@version.marketing_name)
+ expect(@current_os_version).to include(@version.marketing_name)
end
end
diff --git a/spec/integration/client/client_spec.rb b/spec/integration/client/client_spec.rb
index 0144ae0ce3..8afb52e29a 100644
--- a/spec/integration/client/client_spec.rb
+++ b/spec/integration/client/client_spec.rb
@@ -1,5 +1,34 @@
require 'support/shared/integration/integration_helper'
require 'chef/mixin/shell_out'
+require 'tiny_server'
+require 'tmpdir'
+
+def recipes_filename
+ File.join(CHEF_SPEC_DATA, 'recipes.tgz')
+end
+
+def start_tiny_server(server_opts={})
+ recipes_size = File::Stat.new(recipes_filename).size
+ @server = TinyServer::Manager.new(server_opts)
+ @server.start
+ @api = TinyServer::API.instance
+ @api.clear
+ #
+ # trivial endpoints
+ #
+ # just a normal file
+ # (expected_content should be uncompressed)
+ @api.get("/recipes.tgz", 200) {
+ File.open(recipes_filename, "rb") do |f|
+ f.read
+ end
+ }
+end
+
+def stop_tiny_server
+ @server.stop
+ @server = @api = nil
+end
describe "chef-client" do
include IntegrationSupport
@@ -44,7 +73,7 @@ EOM
it 'should fail when cwd is below high above and paths are not specified' do
result = shell_out("#{chef_client} -z -o 'x::default' --disable-config", :cwd => File.expand_path('..', path_to('')))
- result.exitstatus.should == 1
+ expect(result.exitstatus).to eq(1)
end
end
@@ -54,7 +83,7 @@ EOM
it 'should load .chef/knife.rb when -z is specified' do
result = shell_out("#{chef_client} -z -o 'x::default'", :cwd => path_to(''))
# FATAL: Configuration error NoMethodError: undefined method `xxx' for nil:NilClass
- result.stdout.should include("xxx")
+ expect(result.stdout).to include("xxx")
end
end
@@ -135,8 +164,8 @@ EOM
result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" #{path_to('arbitrary.rb')} #{path_to('arbitrary2.rb')}", :cwd => chef_dir)
result.error!
- IO.read(path_to('tempfile.txt')).should == '1'
- IO.read(path_to('tempfile2.txt')).should == '2'
+ expect(IO.read(path_to('tempfile.txt'))).to eq('1')
+ expect(IO.read(path_to('tempfile2.txt'))).to eq('2')
end
it "should run recipes specified as relative paths directly on the command line" do
@@ -155,7 +184,7 @@ EOM
result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" arbitrary.rb", :cwd => path_to(''))
result.error!
- IO.read(path_to('tempfile.txt')).should == '1'
+ expect(IO.read(path_to('tempfile.txt'))).to eq('1')
end
it "should run recipes specified directly on the command line AFTER recipes in the run list" do
@@ -179,7 +208,7 @@ EOM
result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o x::constant_definition arbitrary.rb", :cwd => path_to(''))
result.error!
- IO.read(path_to('tempfile.txt')).should == '1'
+ expect(IO.read(path_to('tempfile.txt'))).to eq('1')
end
end
@@ -211,7 +240,7 @@ cookbook_path "#{path_to('cookbooks')}"
EOM
result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o 'x::default' --local-mode", :cwd => chef_dir)
- result.stdout.should_not include("SSL validation of HTTPS requests is disabled.")
+ expect(result.stdout).not_to include("SSL validation of HTTPS requests is disabled.")
result.error!
end
@@ -232,11 +261,75 @@ cookbook_path "#{path_to('cookbooks')}"
EOM
result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" -r 'x::default' -z", :cwd => chef_dir)
- result.stdout.should_not include("Overridden Run List")
- result.stdout.should include("Run List is [recipe[x::default]]")
+ expect(result.stdout).not_to include("Overridden Run List")
+ expect(result.stdout).to include("Run List is [recipe[x::default]]")
#puts result.stdout
result.error!
end
end
+
+ when_the_repository "has a cookbook with only an audit recipe" do
+
+ before do
+ file 'config/client.rb', <<EOM
+local_mode true
+cookbook_path "#{path_to('cookbooks')}"
+audit_mode :enabled
+EOM
+ end
+
+ it "should exit with a zero code when there is not an audit failure" do
+ file 'cookbooks/audit_test/recipes/succeed.rb', <<-RECIPE
+control_group "control group without top level control" do
+ it "should succeed" do
+ expect(2 - 2).to eq(0)
+ end
+end
+ RECIPE
+
+ result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o 'audit_test::succeed'", :cwd => chef_dir)
+ expect(result.error?).to be_falsey
+ expect(result.stdout).to include("Successfully executed all `control_group` blocks and contained examples")
+ end
+
+ it "should exit with a non-zero code when there is an audit failure" do
+ file 'cookbooks/audit_test/recipes/fail.rb', <<-RECIPE
+control_group "control group without top level control" do
+ it "should fail" do
+ expect(2 - 2).to eq(1)
+ end
+end
+ RECIPE
+
+ result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o 'audit_test::fail'", :cwd => chef_dir)
+ expect(result.error?).to be_truthy
+ expect(result.stdout).to include("Failure/Error: expect(2 - 2).to eq(1)")
+ end
+ end
+
+ context "when using recipe-url" do
+ before(:all) do
+ start_tiny_server
+ end
+
+ after(:all) do
+ stop_tiny_server
+ end
+
+ let(:tmp_dir) { Dir.mktmpdir("recipe-url") }
+
+ it "should complete with success when passed -z and --recipe-url" do
+ file 'config/client.rb', <<EOM
+chef_repo_path "#{tmp_dir}"
+EOM
+ result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" --recipe-url=http://localhost:9000/recipes.tgz -o 'x::default' -z", :cwd => tmp_dir)
+ result.error!
+ end
+
+ it 'should fail when passed --recipe-url and not passed -z' do
+ result = shell_out("#{chef_client} --recipe-url=http://localhost:9000/recipes.tgz", :cwd => tmp_dir)
+ expect(result.exitstatus).to eq(1)
+ end
+ end
end
diff --git a/spec/integration/knife/chef_fs_data_store_spec.rb b/spec/integration/knife/chef_fs_data_store_spec.rb
index a4d62673de..c1f2c7134f 100644
--- a/spec/integration/knife/chef_fs_data_store_spec.rb
+++ b/spec/integration/knife/chef_fs_data_store_spec.rb
@@ -138,6 +138,7 @@ EOM
context 'PUT /TYPE/NAME' do
before do
file 'empty.json', {}
+ file 'dummynode.json', { "name" => "x", "chef_environment" => "rspec" , "json_class" => "Chef::Node", "normal" => {"foo" => "bar"}}
file 'rolestuff.json', '{"description":"hi there","name":"x"}'
file 'cookbooks_to_upload/x/metadata.rb', cookbook_x_100_metadata_rb
end
@@ -165,9 +166,10 @@ EOM
knife('list --local /environments').should_succeed "/environments/x.json\n"
end
- it 'knife raw -z -i empty.json -m PUT /nodes/x' do
- knife("raw -z -i #{path_to('empty.json')} -m PUT /nodes/x").should_succeed( /"x"/ )
+ it 'knife raw -z -i dummynode.json -m PUT /nodes/x' do
+ knife("raw -z -i #{path_to('dummynode.json')} -m PUT /nodes/x").should_succeed( /"x"/ )
knife('list --local /nodes').should_succeed "/nodes/x.json\n"
+ knife('show -z /nodes/x.json --verbose').should_succeed /"bar"/
end
it 'knife raw -z -i empty.json -m PUT /roles/x' do
@@ -180,9 +182,9 @@ EOM
knife('list --local /users').should_succeed "/users/x.json\n"
end
- it 'After knife raw -z -i rolestuff.json -m PUT /roles/x, the output is pretty', :pending => (RUBY_VERSION < "1.9") do
+ it 'After knife raw -z -i rolestuff.json -m PUT /roles/x, the output is pretty', :skip => (RUBY_VERSION < "1.9") do
knife("raw -z -i #{path_to('rolestuff.json')} -m PUT /roles/x").should_succeed( /"x"/ )
- IO.read(path_to('roles/x.json')).should == <<EOM.strip
+ expect(IO.read(path_to('roles/x.json'))).to eq <<EOM.strip
{
"name": "x",
"description": "hi there"
@@ -196,6 +198,7 @@ EOM
context 'POST /TYPE/NAME' do
before do
file 'empty.json', { 'name' => 'z' }
+ file 'dummynode.json', { "name" => "z", "chef_environment" => "rspec" , "json_class" => "Chef::Node", "normal" => {"foo" => "bar"}}
file 'empty_x.json', { 'name' => 'x' }
file 'empty_id.json', { 'id' => 'z' }
file 'rolestuff.json', '{"description":"hi there","name":"x"}'
@@ -231,9 +234,10 @@ EOM
knife('list --local /environments').should_succeed "/environments/z.json\n"
end
- it 'knife raw -z -i empty.json -m POST /nodes' do
- knife("raw -z -i #{path_to('empty.json')} -m POST /nodes").should_succeed( /uri/ )
+ it 'knife raw -z -i dummynode.json -m POST /nodes' do
+ knife("raw -z -i #{path_to('dummynode.json')} -m POST /nodes").should_succeed( /uri/ )
knife('list --local /nodes').should_succeed "/nodes/z.json\n"
+ knife('show -z /nodes/z.json').should_succeed /"bar"/
end
it 'knife raw -z -i empty.json -m POST /roles' do
@@ -246,9 +250,9 @@ EOM
knife('list --local /users').should_succeed "/users/z.json\n"
end
- it 'After knife raw -z -i rolestuff.json -m POST /roles, the output is pretty', :pending => (RUBY_VERSION < "1.9") do
+ it 'After knife raw -z -i rolestuff.json -m POST /roles, the output is pretty', :skip => (RUBY_VERSION < "1.9") do
knife("raw -z -i #{path_to('rolestuff.json')} -m POST /roles").should_succeed( /uri/ )
- IO.read(path_to('roles/x.json')).should == <<EOM.strip
+ expect(IO.read(path_to('roles/x.json'))).to eq <<EOM.strip
{
"name": "x",
"description": "hi there"
diff --git a/spec/integration/knife/common_options_spec.rb b/spec/integration/knife/common_options_spec.rb
index dfc1e024f9..ec76738b6f 100644
--- a/spec/integration/knife/common_options_spec.rb
+++ b/spec/integration/knife/common_options_spec.rb
@@ -39,7 +39,7 @@ describe 'knife common options', :workstation do
it 'knife raw /nodes/x should retrieve the node' do
knife('raw /nodes/x').should_succeed( /"name": "x"/ )
- Chef::Config.chef_server_url.should == 'http://localhost:9999'
+ expect(Chef::Config.chef_server_url).to eq('http://localhost:9999')
end
end
@@ -101,7 +101,7 @@ EOM
it 'knife raw -z --chef-zero-port=9999 /nodes/x retrieves the node' do
knife('raw -z --chef-zero-port=9999 /nodes/x').should_succeed( /"name": "x"/ )
- Chef::Config.chef_server_url.should == 'http://localhost:9999'
+ expect(Chef::Config.chef_server_url).to eq('http://localhost:9999')
end
context 'when the default port (8889) is already bound' do
@@ -149,7 +149,7 @@ EOM
it 'knife raw -z --chef-zero-port=9999 /nodes/x retrieves the node' do
knife('raw -z --chef-zero-port=9999 /nodes/x').should_succeed( /"name": "x"/ )
- Chef::Config.chef_server_url.should == 'http://localhost:9999'
+ expect(Chef::Config.chef_server_url).to eq('http://localhost:9999')
end
end
end
diff --git a/spec/integration/knife/cookbook_api_ipv6_spec.rb b/spec/integration/knife/cookbook_api_ipv6_spec.rb
index e59c8912bd..3d468be7f6 100644
--- a/spec/integration/knife/cookbook_api_ipv6_spec.rb
+++ b/spec/integration/knife/cookbook_api_ipv6_spec.rb
@@ -92,7 +92,7 @@ END_CLIENT_RB
shell_out!("#{knife} cookbook upload apache2 #{knife_config_flag}", :cwd => chef_dir)
versions_list_json = Chef::HTTP::Simple.new("http://[::1]:8900").get("/cookbooks/apache2", "accept" => "application/json")
versions_list = Chef::JSONCompat.from_json(versions_list_json)
- versions_list["apache2"]["versions"].should_not be_empty
+ expect(versions_list["apache2"]["versions"]).not_to be_empty
end
context "and the cookbook has been uploaded to the server" do
@@ -102,7 +102,7 @@ END_CLIENT_RB
it "downloads the cookbook" do
shell_out!("knife cookbook download apache2 #{knife_config_flag} -d #{cache_path}", :cwd => chef_dir)
- Dir["#{cache_path}/*"].map {|entry| File.basename(entry)}.should include("apache2-0.0.1")
+ expect(Dir["#{cache_path}/*"].map {|entry| File.basename(entry)}).to include("apache2-0.0.1")
end
end
diff --git a/spec/integration/knife/deps_spec.rb b/spec/integration/knife/deps_spec.rb
index 8b4d71906b..3120db4940 100644
--- a/spec/integration/knife/deps_spec.rb
+++ b/spec/integration/knife/deps_spec.rb
@@ -251,8 +251,8 @@ EOM
end
it 'knife deps --tree prints each once' do
knife('deps --tree /roles/foo.json /roles/self.json') do
- stdout.should == "/roles/foo.json\n /roles/bar.json\n /roles/baz.json\n /roles/foo.json\n/roles/self.json\n /roles/self.json\n"
- stderr.should == "WARNING: No knife configuration file found\n"
+ expect(stdout).to eq("/roles/foo.json\n /roles/bar.json\n /roles/baz.json\n /roles/foo.json\n/roles/self.json\n /roles/self.json\n")
+ expect(stderr).to eq("WARNING: No knife configuration file found\n")
end
end
end
@@ -589,8 +589,8 @@ EOM
end
it 'knife deps --tree prints each once' do
knife('deps --remote --tree /roles/foo.json /roles/self.json') do
- stdout.should == "/roles/foo.json\n /roles/bar.json\n /roles/baz.json\n /roles/foo.json\n/roles/self.json\n /roles/self.json\n"
- stderr.should == "WARNING: No knife configuration file found\n"
+ expect(stdout).to eq("/roles/foo.json\n /roles/bar.json\n /roles/baz.json\n /roles/foo.json\n/roles/self.json\n /roles/self.json\n")
+ expect(stderr).to eq("WARNING: No knife configuration file found\n")
end
end
end
diff --git a/spec/integration/knife/diff_spec.rb b/spec/integration/knife/diff_spec.rb
index c12ebbcf8f..465383437f 100644
--- a/spec/integration/knife/diff_spec.rb
+++ b/spec/integration/knife/diff_spec.rb
@@ -247,7 +247,7 @@ EOM
end
when_the_chef_server 'has an environment with a different value' do
before { environment 'x', { 'description' => 'hi' } }
- it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife diff reports the difference', :skip => (RUBY_VERSION < "1.9") do
knife('diff /environments/x.json').should_succeed(/
{
- "name": "x",
@@ -277,7 +277,7 @@ EOM
environment 'x', {}
end
- it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife diff reports the difference', :skip => (RUBY_VERSION < "1.9") do
knife('diff /environments/x.json').should_succeed(/
{
- "name": "x"
@@ -291,7 +291,7 @@ EOM
before do
environment 'x', { 'description' => 'lo' }
end
- it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife diff reports the difference', :skip => (RUBY_VERSION < "1.9") do
knife('diff /environments/x.json').should_succeed(/
{
"name": "x",
@@ -533,7 +533,7 @@ EOM
end
when_the_chef_server 'has an environment with a different value' do
before { environment 'x', { 'description' => 'hi' } }
- it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife diff reports the difference', :skip => (RUBY_VERSION < "1.9") do
knife('diff /environments/x.json').should_succeed(/
{
- "name": "x",
@@ -560,7 +560,7 @@ EOM
end
when_the_chef_server 'has an environment with no value' do
before { environment 'x', {} }
- it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife diff reports the difference', :skip => (RUBY_VERSION < "1.9") do
knife('diff /environments/x.json').should_succeed(/
{
- "name": "x"
@@ -574,7 +574,7 @@ EOM
before do
environment 'x', { 'description' => 'lo' }
end
- it 'knife diff reports the difference', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife diff reports the difference', :skip => (RUBY_VERSION < "1.9") do
knife('diff /environments/x.json').should_succeed(/
{
"name": "x",
diff --git a/spec/integration/knife/download_spec.rb b/spec/integration/knife/download_spec.rb
index 0c2b907f1e..c87e6fe20a 100644
--- a/spec/integration/knife/download_spec.rb
+++ b/spec/integration/knife/download_spec.rb
@@ -1069,19 +1069,19 @@ EOM
end
when_the_repository 'is empty' do
- it 'knife download /cookbooks/x signs all requests', :ruby_gte_19_only do
+ it 'knife download /cookbooks/x signs all requests' do
# Check that BasicClient.request() always gets called with X-OPS-USERID
original_new = Chef::HTTP::BasicClient.method(:new)
- Chef::HTTP::BasicClient.should_receive(:new) do |args|
+ expect(Chef::HTTP::BasicClient).to receive(:new) { |args|
new_result = original_new.call(*args)
original_request = new_result.method(:request)
- new_result.should_receive(:request) do |method, url, body, headers, &response_handler|
- headers['X-OPS-USERID'].should_not be_nil
+ expect(new_result).to receive(:request) { |method, url, body, headers, &response_handler|
+ expect(headers['X-OPS-USERID']).not_to be_nil
original_request.call(method, url, body, headers, &response_handler)
- end.at_least(:once)
+ }.at_least(:once)
new_result
- end.at_least(:once)
+ }.at_least(:once)
knife('download /cookbooks/x').should_succeed <<EOM
Created /cookbooks
diff --git a/spec/integration/knife/list_spec.rb b/spec/integration/knife/list_spec.rb
index 3d8b83001d..911b56ef18 100644
--- a/spec/integration/knife/list_spec.rb
+++ b/spec/integration/knife/list_spec.rb
@@ -471,7 +471,7 @@ EOM
end
end
- when_the_repository 'has a cookbooks directory and a symlinked cookbooks directory', :pending => (Chef::Platform.windows?) do
+ when_the_repository 'has a cookbooks directory and a symlinked cookbooks directory', :skip => (Chef::Platform.windows?) do
before do
directory 'cookbooks'
symlink 'symlinked', 'cookbooks'
@@ -508,7 +508,7 @@ EOM
end
end
- when_the_repository 'has a real_cookbooks directory and a cookbooks symlink to it', :pending => (Chef::Platform.windows?) do
+ when_the_repository 'has a real_cookbooks directory and a cookbooks symlink to it', :skip => (Chef::Platform.windows?) do
before do
directory 'real_cookbooks'
symlink 'cookbooks', 'real_cookbooks'
diff --git a/spec/integration/knife/raw_spec.rb b/spec/integration/knife/raw_spec.rb
index 2b49d2ebb2..75fc8fa55e 100644
--- a/spec/integration/knife/raw_spec.rb
+++ b/spec/integration/knife/raw_spec.rb
@@ -38,7 +38,7 @@ describe 'knife raw', :workstation do
user 'x', '{}'
end
- it 'knife raw /nodes/x returns the node', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife raw /nodes/x returns the node', :skip => (RUBY_VERSION < "1.9") do
knife('raw /nodes/x').should_succeed <<EOM
{
"name": "x",
@@ -68,7 +68,7 @@ EOM
knife('raw /blarghle').should_fail(/ERROR: Server responded with error 404 "Not Found\s*"/)
end
- it 'knife raw -m DELETE /roles/x succeeds', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife raw -m DELETE /roles/x succeeds', :skip => (RUBY_VERSION < "1.9") do
knife('raw -m DELETE /roles/x').should_succeed <<EOM
{
"name": "x",
@@ -92,7 +92,7 @@ EOM
knife('show /roles/x.json').should_fail "ERROR: /roles/x.json: No such file or directory\n"
end
- it 'knife raw -m PUT -i blah.txt /roles/x succeeds', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife raw -m PUT -i blah.txt /roles/x succeeds', :skip => (RUBY_VERSION < "1.9") do
Tempfile.open('raw_put_input') do |file|
file.write <<EOM
{
@@ -146,7 +146,7 @@ EOM
end
end
- it 'knife raw -m POST -i blah.txt /roles succeeds', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife raw -m POST -i blah.txt /roles succeeds', :skip => (RUBY_VERSION < "1.9") do
Tempfile.open('raw_put_input') do |file|
file.write <<EOM
{
@@ -196,7 +196,7 @@ EOM
@raw_server_thread.kill if @raw_server_thread
end
- it 'knife raw /blah returns the prettified json', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife raw /blah returns the prettified json', :skip => (RUBY_VERSION < "1.9") do
knife('raw /blah').should_succeed <<EOM
{
"x": "y",
diff --git a/spec/integration/knife/serve_spec.rb b/spec/integration/knife/serve_spec.rb
index 3c859b794e..7bf7d29b40 100644
--- a/spec/integration/knife/serve_spec.rb
+++ b/spec/integration/knife/serve_spec.rb
@@ -31,18 +31,18 @@ describe 'knife serve', :workstation do
exception = nil
t = Thread.new do
begin
- knife('serve --chef-zero-port=8889')
+ knife('serve --chef-zero-port=8890')
rescue
exception = $!
end
end
begin
Chef::Config.log_level = :debug
- Chef::Config.chef_server_url = 'http://localhost:8889'
+ Chef::Config.chef_server_url = 'http://localhost:8890'
Chef::Config.node_name = nil
Chef::Config.client_key = nil
api = Chef::ServerAPI.new
- api.get('nodes/x')['name'].should == 'x'
+ expect(api.get('nodes/x')['name']).to eq('x')
rescue
if exception
raise exception
diff --git a/spec/integration/knife/show_spec.rb b/spec/integration/knife/show_spec.rb
index bc7f1cf6d3..8f1887e738 100644
--- a/spec/integration/knife/show_spec.rb
+++ b/spec/integration/knife/show_spec.rb
@@ -76,7 +76,7 @@ EOM
}
EOM
end
- it 'knife show /environments/x.json shows the remote version', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife show /environments/x.json shows the remote version', :skip => (RUBY_VERSION < "1.9") do
knife('show /environments/x.json').should_succeed <<EOM
/environments/x.json:
{
@@ -92,7 +92,7 @@ EOM
}
EOM
end
- it 'knife show /roles/x.json shows the remote version', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife show /roles/x.json shows the remote version', :skip => (RUBY_VERSION < "1.9") do
knife('show /roles/x.json').should_succeed <<EOM
/roles/x.json:
{
@@ -135,7 +135,7 @@ EOM
'name' => 'x'
}
end
- it 'knife show shows the attributes in a predetermined order', :pending => (RUBY_VERSION < "1.9") do
+ it 'knife show shows the attributes in a predetermined order', :skip => (RUBY_VERSION < "1.9") do
knife('show /environments/x.json').should_succeed <<EOM
/environments/x.json:
{
diff --git a/spec/integration/knife/upload_spec.rb b/spec/integration/knife/upload_spec.rb
index dade476889..cef4f54e97 100644
--- a/spec/integration/knife/upload_spec.rb
+++ b/spec/integration/knife/upload_spec.rb
@@ -262,7 +262,7 @@ Created /data_bags/x/y.json
EOM
knife('diff --name-status /data_bags').should_succeed <<EOM
EOM
- Chef::JSONCompat.parse(knife('raw /data/x/y').stdout, :create_additions => false).keys.sort.should == [ 'foo', 'id' ]
+ expect(Chef::JSONCompat.parse(knife('raw /data/x/y').stdout, :create_additions => false).keys.sort).to eq([ 'foo', 'id' ])
end
it 'knife upload /data_bags/x /data_bags/x/y.json uploads x once' do
@@ -286,9 +286,9 @@ Created /data_bags/x/y.json
EOM
knife('diff --name-status /data_bags').should_succeed ''
result = Chef::JSONCompat.parse(knife('raw /data/x/y').stdout, :create_additions => false)
- result.keys.sort.should == [ 'chef_type', 'data_bag', 'id' ]
- result['chef_type'].should == 'aaa'
- result['data_bag'].should == 'bbb'
+ expect(result.keys.sort).to eq([ 'chef_type', 'data_bag', 'id' ])
+ expect(result['chef_type']).to eq('aaa')
+ expect(result['data_bag']).to eq('bbb')
end
end
@@ -1268,8 +1268,8 @@ Created /nodes/x.json
Updated /org.json
Created /roles/x.json
EOM
- api.get('association_requests').map { |a| a['username'] }.should == [ 'foo' ]
- api.get('users').map { |a| a['user']['username'] }.should == [ 'bar' ]
+ expect(api.get('association_requests').map { |a| a['username'] }).to eq([ 'foo' ])
+ expect(api.get('users').map { |a| a['user']['username'] }).to eq([ 'bar' ])
end
end
@@ -1280,7 +1280,7 @@ EOM
it 'knife upload / emits a warning for bar and adds foo and foobar' do
knife('upload /').should_succeed ''
- api.get('/')['full_name'].should == 'Something'
+ expect(api.get('/')['full_name']).to eq('Something')
end
end
@@ -1291,7 +1291,7 @@ EOM
it 'knife upload / emits a warning for bar and adds foo and foobar' do
knife('upload /').should_succeed "Updated /org.json\n"
- api.get('/')['full_name'].should == 'Something Else'
+ expect(api.get('/')['full_name']).to eq('Something Else')
end
end
@@ -1306,8 +1306,8 @@ EOM
it 'knife upload / emits a warning for bar and invites foobar' do
knife('upload /').should_succeed "Updated /invitations.json\n", :stderr => "WARN: Could not invite bar to organization foo: User bar is already in organization foo\n"
- api.get('association_requests').map { |a| a['username'] }.should == [ 'foo', 'foobar' ]
- api.get('users').map { |a| a['user']['username'] }.should == [ 'bar' ]
+ expect(api.get('association_requests').map { |a| a['username'] }).to eq([ 'foo', 'foobar' ])
+ expect(api.get('users').map { |a| a['user']['username'] }).to eq([ 'bar' ])
end
end
@@ -1318,8 +1318,8 @@ EOM
it 'knife upload / emits a warning for bar and adds foo and foobar' do
knife('upload /').should_succeed "Updated /members.json\n"
- api.get('association_requests').map { |a| a['username'] }.should == [ ]
- api.get('users').map { |a| a['user']['username'] }.should == [ 'bar', 'foo', 'foobar' ]
+ expect(api.get('association_requests').map { |a| a['username'] }).to eq([ ])
+ expect(api.get('users').map { |a| a['user']['username'] }).to eq([ 'bar', 'foo', 'foobar' ])
end
end
@@ -1331,8 +1331,8 @@ EOM
it 'knife upload / does nothing' do
knife('upload /').should_succeed ''
- api.get('association_requests').map { |a| a['username'] }.should == [ 'foo' ]
- api.get('users').map { |a| a['user']['username'] }.should == [ 'bar' ]
+ expect(api.get('association_requests').map { |a| a['username'] }).to eq([ 'foo' ])
+ expect(api.get('users').map { |a| a['user']['username'] }).to eq([ 'bar' ])
end
end
end
@@ -1347,8 +1347,8 @@ EOM
it 'knife upload / does nothing' do
knife('upload /').should_succeed ''
- api.get('association_requests').map { |a| a['username'] }.should == [ 'bar', 'foo' ]
- api.get('users').map { |a| a['user']['username'] }.should == [ ]
+ expect(api.get('association_requests').map { |a| a['username'] }).to eq([ 'bar', 'foo' ])
+ expect(api.get('users').map { |a| a['user']['username'] }).to eq([ ])
end
end
end
@@ -1363,8 +1363,8 @@ EOM
it 'knife upload / does nothing' do
knife('upload /').should_succeed ''
- api.get('association_requests').map { |a| a['username'] }.should == [ ]
- api.get('users').map { |a| a['user']['username'] }.should == [ 'bar', 'foo' ]
+ expect(api.get('association_requests').map { |a| a['username'] }).to eq([ ])
+ expect(api.get('users').map { |a| a['user']['username'] }).to eq([ 'bar', 'foo' ])
end
end
end
diff --git a/spec/integration/recipes/lwrp_inline_resources_spec.rb b/spec/integration/recipes/lwrp_inline_resources_spec.rb
index a0c13da6f7..a3baba8b0f 100644
--- a/spec/integration/recipes/lwrp_inline_resources_spec.rb
+++ b/spec/integration/recipes/lwrp_inline_resources_spec.rb
@@ -71,7 +71,7 @@ EOM
(up to date)
EOM
expected = expected.lines.map { |l| l.chomp }.join("\n")
- actual.should include(expected)
+ expect(actual).to include(expected)
result.error!
end
end
diff --git a/spec/integration/solo/solo_spec.rb b/spec/integration/solo/solo_spec.rb
index 793789b754..41f5f5506f 100644
--- a/spec/integration/solo/solo_spec.rb
+++ b/spec/integration/solo/solo_spec.rb
@@ -28,7 +28,7 @@ file_cache_path "#{path_to('config/cache')}"
EOM
result = shell_out("ruby bin/chef-solo -c \"#{path_to('config/solo.rb')}\" -o 'x::default' -l debug", :cwd => chef_dir)
result.error!
- result.stdout.should include("ITWORKS")
+ expect(result.stdout).to include("ITWORKS")
end
it "should evaluate its node.json file" do
@@ -43,7 +43,7 @@ E
result = shell_out("ruby bin/chef-solo -c \"#{path_to('config/solo.rb')}\" -j '#{path_to('config/node.json')}' -l debug", :cwd => chef_dir)
result.error!
- result.stdout.should include("ITWORKS")
+ expect(result.stdout).to include("ITWORKS")
end
end
@@ -63,8 +63,8 @@ cookbook_path "#{path_to('cookbooks')}"
file_cache_path "#{path_to('config/cache')}"
EOM
result = shell_out("ruby bin/chef-solo -c \"#{path_to('config/solo.rb')}\" -o 'x::default' -l debug", :cwd => chef_dir)
- result.exitstatus.should == 0 # For CHEF-5120 this becomes 1
- result.stdout.should include("WARN: MissingCookbookDependency")
+ expect(result.exitstatus).to eq(0) # For CHEF-5120 this becomes 1
+ expect(result.stdout).to include("WARN: MissingCookbookDependency")
end
end
@@ -83,15 +83,14 @@ end
EOM
end
- # Ruby 1.8.7 doesn't have Process.spawn :(
- it "while running solo concurrently", :ruby_gte_19_only => true do
+ it "while running solo concurrently" do
file 'config/solo.rb', <<EOM
cookbook_path "#{path_to('cookbooks')}"
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.
- lambda {
+ expect {
Timeout.timeout(120) do
chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..")
@@ -109,7 +108,7 @@ EOM
Process.waitpid(s1)
Process.waitpid(s2)
end
- }.should_not raise_error
+ }.not_to raise_error
# Unfortunately file / directory helpers in integration tests
# are implemented using before(:each) so we need to do all below
@@ -117,13 +116,13 @@ EOM
run_log = File.read(path_to('logs/runs.log'))
# both of the runs should succeed
- run_log.lines.reject {|l| !l.include? "INFO: Chef Run complete in"}.length.should == 2
+ 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:"}
- pid_lines.length.should == 2
+ expect(pid_lines.length).to eq(2)
pids = pid_lines.map {|l| l.split(" ").last}
- run_log.should include("Chef client #{pids[0]} is running, will wait for it to finish and then run.")
+ 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 = [ ]
@@ -135,7 +134,7 @@ EOM
ends << index
end
end
- starts[1].should > ends[0]
+ expect(starts[1]).to be > ends[0]
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index cc5ba8c3ac..8888efc424 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -18,12 +18,6 @@
# If you need to add anything in here, don't.
# Add it to one of the files in spec/support
-# Configure this first so it doesn't trigger annoying warning when we use it.
-# Main rspec configuration comes later
-RSpec.configure do |config|
- config.treat_symbols_as_metadata_keys_with_true_values = true
-end
-
# Abuse ruby's constant lookup to avoid undefined constant errors
module Shell
JUST_TESTING_MOVE_ALONG = true unless defined? JUST_TESTING_MOVE_ALONG
@@ -89,14 +83,27 @@ Dir["spec/support/**/*.rb"].
OHAI_SYSTEM = Ohai::System.new
OHAI_SYSTEM.all_plugins("platform")
-TEST_PLATFORM = OHAI_SYSTEM["platform"].dup.freeze
-TEST_PLATFORM_VERSION = OHAI_SYSTEM["platform_version"].dup.freeze
+
+TEST_PLATFORM =
+ (OHAI_SYSTEM['platform'] ||
+ 'unknown_test_platform').dup.freeze
+TEST_PLATFORM_VERSION =
+ (OHAI_SYSTEM['platform_version'] ||
+ 'unknown_platform_version').dup.freeze
RSpec.configure do |config|
config.include(Matchers)
config.filter_run :focus => true
config.filter_run_excluding :external => true
+ # Explicitly disable :should syntax
+ config.expect_with :rspec do |c|
+ c.syntax = :expect
+ end
+ config.mock_with :rspec do |c|
+ c.syntax = :expect
+ end
+
# Only run these tests on platforms that are also chef workstations
config.filter_run_excluding :workstation if solaris? or aix?
@@ -122,19 +129,19 @@ RSpec.configure do |config|
config.filter_run_excluding :aix_only => true unless aix?
config.filter_run_excluding :supports_cloexec => true unless supports_cloexec?
config.filter_run_excluding :selinux_only => true unless selinux_enabled?
- config.filter_run_excluding :ruby_18_only => true unless ruby_18?
- config.filter_run_excluding :ruby_19_only => true unless ruby_19?
- config.filter_run_excluding :ruby_gte_19_only => true unless ruby_gte_19?
config.filter_run_excluding :ruby_20_only => true unless ruby_20?
- config.filter_run_excluding :ruby_gte_20_only => true unless ruby_gte_20?
+ # chef_gte_XX_only and chef_lt_XX_only pair up correctly with the same XX
+ # number. please conserve this pattern & resist filling out all the operators
+ config.filter_run_excluding :chef_gte_13_only => true unless chef_gte_13?
+ config.filter_run_excluding :chef_lt_13_only => true unless chef_lt_13?
config.filter_run_excluding :requires_root => true unless root?
config.filter_run_excluding :requires_root_or_running_windows => true unless (root? || windows?)
config.filter_run_excluding :requires_unprivileged_user => true if root?
config.filter_run_excluding :uses_diff => true unless has_diff?
- config.filter_run_excluding :ruby_gte_20_and_openssl_gte_101 => true unless (ruby_gte_20? && openssl_gte_101?)
+ config.filter_run_excluding :openssl_gte_101 => true unless openssl_gte_101?
config.filter_run_excluding :openssl_lt_101 => true unless openssl_lt_101?
- config.filter_run_excluding :ruby_lt_20 => true unless ruby_lt_20?
config.filter_run_excluding :aes_256_gcm_only => true unless aes_256_gcm?
+ config.filter_run_excluding :broken => true
running_platform_arch = `uname -m`.strip
@@ -159,10 +166,15 @@ RSpec.configure do |config|
}
config.run_all_when_everything_filtered = true
- config.treat_symbols_as_metadata_keys_with_true_values = true
config.before(:each) do
Chef::Config.reset
+
+ # By default, treat deprecation warnings as errors in tests.
+ Chef::Config.treat_deprecation_warnings_as_errors(true)
+
+ # Set environment variable so the setting persists in child processes
+ ENV['CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS'] = "1"
end
config.before(:suite) do
diff --git a/spec/stress/win32/file_spec.rb b/spec/stress/win32/file_spec.rb
index 0341f62d30..6c4b26b05c 100644
--- a/spec/stress/win32/file_spec.rb
+++ b/spec/stress/win32/file_spec.rb
@@ -26,12 +26,12 @@ describe 'Chef::ReservedNames::Win32::File', :windows_only do
it "should not leak significant memory", :volatile do
test = lambda { Chef::ReservedNames::Win32::File.symlink?(@path) }
- test.should_not leak_memory(:warmup => 50000, :iterations => 50000)
+ expect(test).not_to leak_memory(:warmup => 50000, :iterations => 50000)
end
it "should not leak handles", :volatile do
test = lambda { Chef::ReservedNames::Win32::File.symlink?(@path) }
- test.should_not leak_handles(:warmup => 50, :iterations => 100)
+ expect(test).not_to leak_handles(:warmup => 50, :iterations => 100)
end
end
diff --git a/spec/stress/win32/security_spec.rb b/spec/stress/win32/security_spec.rb
index e506b71be1..cb520e515e 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
- lambda {
+ expect {
sids = Chef::ReservedNames::Win32::Security::SecurableObject.new(@monkeyfoo).security_descriptor.dacl.select { |ace| ace.sid }
GC.start
- }.should_not leak_memory(:warmup => 50, :iterations => 100)
+ }.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)
- lambda {
+ expect {
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
- }.should_not leak_memory(:warmup => 50, :iterations => 100)
+ }.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 237543748c..851b1dce0a 100644
--- a/spec/support/chef_helpers.rb
+++ b/spec/support/chef_helpers.rb
@@ -67,15 +67,15 @@ end
# win32/service gem. windows_service_manager tests create a windows
# service that starts with the system ruby and requires this gem.
def system_windows_service_gem?
- windows_service_gem_check_command = "ruby -e 'require \"win32/daemon\"' > /dev/null 2>&1"
+ windows_service_gem_check_command = %q{ruby -r "win32/daemon" -e ":noop"}
if defined?(Bundler)
Bundler.with_clean_env do
# This returns true if the gem can be loaded
- system windows_service_gem_check_command
+ system(windows_service_gem_check_command)
end
else
# This returns true if the gem can be loaded
- system windows_service_gem_check_command
+ system(windows_service_gem_check_command)
end
end
diff --git a/spec/support/matchers/leak.rb b/spec/support/matchers/leak.rb
index cc7d265a3c..01d1e53f92 100644
--- a/spec/support/matchers/leak.rb
+++ b/spec/support/matchers/leak.rb
@@ -26,11 +26,11 @@ module Matchers
@variance = opts[:variance] || 5000
end
- def failure_message_for_should
+ def failure_message
"expected final measure [#{@final_measure}] to be greater than or within +/- #{@variance} delta of initial measure [#{@initial_measure}]"
end
- def failure_message_for_should_not
+ def failure_message_when_negated
"expected final measure [#{@final_measure}] to be less than or within +/- #{@variance} delta of initial measure [#{@initial_measure}]"
end
diff --git a/spec/support/mock/platform.rb b/spec/support/mock/platform.rb
index 46e76d48c5..ab2c19baff 100644
--- a/spec/support/mock/platform.rb
+++ b/spec/support/mock/platform.rb
@@ -6,7 +6,7 @@
# testing code that mixes in platform specific modules like +Chef::Mixin::Securable+
# or +Chef::FileAccessControl+
def platform_mock(platform = :unix, &block)
- Chef::Platform.stub(:windows?).and_return(platform == :windows ? true : false)
+ allow(Chef::Platform).to receive(:windows?).and_return(platform == :windows ? true : false)
ENV['SYSTEMDRIVE'] = (platform == :windows ? 'C:' : nil)
if platform == :windows
diff --git a/spec/support/pedant/Gemfile b/spec/support/pedant/Gemfile
new file mode 100644
index 0000000000..d4224cd439
--- /dev/null
+++ b/spec/support/pedant/Gemfile
@@ -0,0 +1,3 @@
+source "https://rubygems.org"
+
+gem 'chef-pedant', :github => 'opscode/chef-pedant', :ref => "server-cli-option"
diff --git a/spec/support/pedant/pedant_config.rb b/spec/support/pedant/pedant_config.rb
index 6818d29d74..3f8219fc59 100644
--- a/spec/support/pedant/pedant_config.rb
+++ b/spec/support/pedant/pedant_config.rb
@@ -26,7 +26,7 @@
# If you are doing development testing, you can specify the address of
# the Solr server. The presence of this parameter will enable tests
-# to force commits to Solr, greatly decreasing the amout of time
+# to force commits to Solr, greatly decreasing the amount of time
# needed for testing the search endpoint. This is only an
# optimization for development! If you are testing a "live" Chef
# Server, or otherwise do not have access to the Solr server from your
@@ -36,7 +36,7 @@
#search_server "http://localhost:8983"
# Related to the 'search_server' parameter, this specifies the maximum
-# amout of time (in seconds) that search endpoint requests should be
+# amount of time (in seconds) that search endpoint requests should be
# retried before giving up. If not explicitly set, it will default to
# 65 seconds; only set it if you know that your Solr commit interval
# differs significantly from this.
@@ -72,6 +72,13 @@ superuser_name 'admin'
superuser_key key
webui_key key
+# When we updated Chef to RSpec 3 there were gem conflicts with chef-pedant.
+# We removed chef as a chef-pedant gem dependency in pedant.gemfile, but this
+# caused chef-pedant to fail because it could not query for the chef version
+# on the box pedant is running on. X-Chef-Version isn't needed in server
+# requests for these tests, so we've disabled it.
+ingore_x_chef_version true
+
# Set the platform_class
platform_class Pedant::OpenSourcePlatform
diff --git a/spec/support/pedant/run_pedant.rb b/spec/support/pedant/run_pedant.rb
index abee67103c..aac2c2df1a 100644
--- a/spec/support/pedant/run_pedant.rb
+++ b/spec/support/pedant/run_pedant.rb
@@ -8,6 +8,7 @@ require 'chef/chef_fs/config'
require 'tmpdir'
require 'fileutils'
require 'chef/version'
+require 'chef/mixin/shell_out'
def start_server(chef_repo_path)
Dir.mkdir(chef_repo_path) if !File.exists?(chef_repo_path)
@@ -37,28 +38,26 @@ begin
# Capture setup data into master_chef_repo_path
server = start_server(chef_repo_path)
+ so = nil
- require 'pedant'
- require 'pedant/opensource'
+ include Chef::Mixin::ShellOut
- #Pedant::Config.rerun = true
+ Bundler.with_clean_env do
- Pedant.config.suite = 'api'
- Pedant.config[:config_file] = 'spec/support/pedant/pedant_config.rb'
- Pedant.config.chef_server = server.url
- Pedant.setup([
- '--skip-knife',
- '--skip-validation',
- '--skip-authentication',
- '--skip-authorization',
- '--skip-omnibus'
- ])
+ shell_out("bundle install --gemfile spec/support/pedant/Gemfile", :live_stream => STDOUT)
- result = RSpec::Core::Runner.run(Pedant.config.rspec_args)
+ pedant_cmd = "chef-pedant " +
+ " --config spec/support/pedant/pedant_config.rb" +
+ " --server '#{server.url}'" +
+ " --skip-knife --skip-validation --skip-authentication" +
+ " --skip-authorization --skip-omnibus"
+ so = shell_out("bundle exec #{pedant_cmd}", :live_stream => STDOUT, :env => {'BUNDLE_GEMFILE' => 'spec/support/pedant/Gemfile'})
+
+ end
- server.stop if server.running?
ensure
+ server.stop if server && server.running?
FileUtils.remove_entry_secure(tmpdir) if tmpdir
end
-exit(result)
+exit(so.exitstatus)
diff --git a/spec/support/platform_helpers.rb b/spec/support/platform_helpers.rb
index 2f21fe4401..a412fe38e1 100644
--- a/spec/support/platform_helpers.rb
+++ b/spec/support/platform_helpers.rb
@@ -6,28 +6,24 @@ class ShellHelpers
extend Chef::Mixin::ShellOut
end
-def ruby_gte_20?
- RUBY_VERSION.to_f >= 2.0
-end
-
def ruby_lt_20?
!ruby_gte_20?
end
-def ruby_gte_19?
- RUBY_VERSION.to_f >= 1.9
+def chef_gte_13?
+ Chef::VERSION.split('.').first.to_i >= 13
end
-def ruby_20?
- !!(RUBY_VERSION =~ /^2.0/)
+def chef_lt_13?
+ Chef::VERSION.split('.').first.to_i < 13
end
-def ruby_19?
- !!(RUBY_VERSION =~ /^1.9/)
+def ruby_gte_19?
+ RUBY_VERSION.to_f >= 1.9
end
-def ruby_18?
- !!(RUBY_VERSION =~ /^1.8/)
+def ruby_20?
+ !!(RUBY_VERSION =~ /^2.0/)
end
def windows?
diff --git a/spec/support/shared/functional/directory_resource.rb b/spec/support/shared/functional/directory_resource.rb
index ee9085424e..39bdc313e5 100644
--- a/spec/support/shared/functional/directory_resource.rb
+++ b/spec/support/shared/functional/directory_resource.rb
@@ -25,7 +25,7 @@ shared_examples_for "a directory resource" do
context "when the target directory does not exist" do
before do
# assert pre-condition
- File.should_not exist(path)
+ expect(File).not_to exist(path)
end
describe "when running action :create" do
@@ -35,17 +35,17 @@ shared_examples_for "a directory resource" do
end
it "creates the directory when the :create action is run" do
- File.should exist(path)
+ expect(File).to exist(path)
end
it "is marked updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
context "and the recursive option is set" do
before do
- File.should_not exist(path)
+ expect(File).not_to exist(path)
resource.recursive(true)
@recursive_path = File.join(path, 'red-headed-stepchild')
@@ -54,12 +54,12 @@ shared_examples_for "a directory resource" do
end
it "recursively creates required directories" do
- File.should exist(path)
- File.should exist(@recursive_path)
+ expect(File).to exist(path)
+ expect(File).to exist(@recursive_path)
end
it "is marked updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
end
@@ -97,7 +97,7 @@ shared_examples_for "a directory resource" do
# so we run the resource twice--otherwise the updated_by_last_action test
# will fail.
resource.dup.run_action(:create)
- File.should exist(path)
+ expect(File).to exist(path)
resource.run_action(:create)
end
@@ -108,11 +108,11 @@ shared_examples_for "a directory resource" do
end
it "does not re-create the directory" do
- File.should exist(path)
+ expect(File).to exist(path)
end
it "is not marked updated by last action" do
- resource.should_not be_updated_by_last_action
+ expect(resource).not_to be_updated_by_last_action
end
end
@@ -123,11 +123,11 @@ shared_examples_for "a directory resource" do
end
it "deletes the directory" do
- File.should_not exist(path)
+ expect(File).not_to exist(path)
end
it "is marked as updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
@@ -139,7 +139,7 @@ shared_examples_for "a directory resource" do
end
it "recursively deletes directories" do
- File.should_not exist(path)
+ expect(File).not_to exist(path)
end
end
end
diff --git a/spec/support/shared/functional/file_resource.rb b/spec/support/shared/functional/file_resource.rb
index 72b72912bd..4f8e2f5b71 100644
--- a/spec/support/shared/functional/file_resource.rb
+++ b/spec/support/shared/functional/file_resource.rb
@@ -48,10 +48,10 @@ end
shared_examples_for "a file with the wrong content" do
before do
# Assert starting state is as expected
- File.should exist(path)
+ expect(File).to exist(path)
# Kinda weird, in this case @expected_checksum is the cksum of the file
# with incorrect content.
- sha256_checksum(path).should == @expected_checksum
+ expect(sha256_checksum(path)).to eq(@expected_checksum)
end
describe "when diff is disabled" do
@@ -65,20 +65,20 @@ shared_examples_for "a file with the wrong content" do
end
it "overwrites the file with the updated content when the :create action is run" do
- File.stat(path).mtime.should > @expected_mtime
- sha256_checksum(path).should_not == @expected_checksum
+ expect(File.stat(path).mtime).to be > @expected_mtime
+ expect(sha256_checksum(path)).not_to eq(@expected_checksum)
end
it "backs up the existing file" do
- Dir.glob(backup_glob).size.should equal(1)
+ expect(Dir.glob(backup_glob).size).to equal(1)
end
it "is marked as updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
it "should restore the security contexts on selinux", :selinux_only do
- selinux_security_context_restored?(path).should be_true
+ expect(selinux_security_context_restored?(path)).to be_truthy
end
end
@@ -89,11 +89,11 @@ shared_examples_for "a file with the wrong content" do
end
it "should not attempt to backup the existing file if :backup == 0" do
- Dir.glob(backup_glob).size.should equal(0)
+ expect(Dir.glob(backup_glob).size).to equal(0)
end
it "should restore the security contexts on selinux", :selinux_only do
- selinux_security_context_restored?(path).should be_true
+ expect(selinux_security_context_restored?(path)).to be_truthy
end
end
@@ -114,16 +114,16 @@ shared_examples_for "a file with the wrong content" do
end
it "doesn't overwrite the file when the :create_if_missing action is run" do
- File.stat(path).mtime.should == @expected_mtime
- sha256_checksum(path).should == @expected_checksum
+ expect(File.stat(path).mtime).to eq(@expected_mtime)
+ expect(sha256_checksum(path)).to eq(@expected_checksum)
end
it "is not marked as updated" do
- resource.should_not be_updated_by_last_action
+ expect(resource).not_to be_updated_by_last_action
end
it "should restore the security contexts on selinux", :selinux_only do
- selinux_security_context_restored?(path).should be_true
+ expect(selinux_security_context_restored?(path)).to be_truthy
end
end
@@ -133,11 +133,11 @@ shared_examples_for "a file with the wrong content" do
end
it "deletes the file" do
- File.should_not exist(path)
+ expect(File).not_to exist(path)
end
it "is marked as updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
@@ -146,14 +146,14 @@ shared_examples_for "a file with the wrong content" do
context "when diff is enabled" do
describe 'sensitive attribute' do
context "should be insensitive by default" do
- it { expect(resource.sensitive).to(be_false) }
+ it { expect(resource.sensitive).to(be_falsey) }
end
context "when set" do
before { resource.sensitive(true) }
it "should be set on the resource" do
- expect(resource.sensitive).to(be_true)
+ expect(resource.sensitive).to(be_truthy)
end
context "when running :create action" do
@@ -181,8 +181,8 @@ end
shared_examples_for "a file with the correct content" do
before do
# Assert starting state is as expected
- File.should exist(path)
- sha256_checksum(path).should == @expected_checksum
+ expect(File).to exist(path)
+ expect(sha256_checksum(path)).to eq(@expected_checksum)
end
include_context "diff disabled"
@@ -192,19 +192,19 @@ shared_examples_for "a file with the correct content" do
resource.run_action(:create)
end
it "does not overwrite the original when the :create action is run" do
- sha256_checksum(path).should == @expected_checksum
+ expect(sha256_checksum(path)).to eq(@expected_checksum)
end
it "does not update the mtime of the file when the :create action is run" do
- File.stat(path).mtime.should == @expected_mtime
+ expect(File.stat(path).mtime).to eq(@expected_mtime)
end
it "is not marked as updated by last action" do
- resource.should_not be_updated_by_last_action
+ expect(resource).not_to be_updated_by_last_action
end
it "should restore the security contexts on selinux", :selinux_only do
- selinux_security_context_restored?(path).should be_true
+ expect(selinux_security_context_restored?(path)).to be_truthy
end
end
@@ -214,15 +214,15 @@ shared_examples_for "a file with the correct content" do
end
it "doesn't overwrite the file when the :create_if_missing action is run" do
- sha256_checksum(path).should == @expected_checksum
+ expect(sha256_checksum(path)).to eq(@expected_checksum)
end
it "is not marked as updated by last action" do
- resource.should_not be_updated_by_last_action
+ expect(resource).not_to be_updated_by_last_action
end
it "should restore the security contexts on selinux", :selinux_only do
- selinux_security_context_restored?(path).should be_true
+ expect(selinux_security_context_restored?(path)).to be_truthy
end
end
@@ -232,11 +232,11 @@ shared_examples_for "a file with the correct content" do
end
it "deletes the file when the :delete action is run" do
- File.should_not exist(path)
+ expect(File).not_to exist(path)
end
it "is marked as updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
end
@@ -300,7 +300,7 @@ shared_examples_for "a file resource" do
it "successfully doesn't create the file" do
resource.run_action(:create) # should not raise
- File.should_not exist(path)
+ expect(File).not_to exist(path)
end
end
@@ -308,14 +308,14 @@ shared_examples_for "a file resource" do
describe "when setting atomic_update" do
it "booleans should work" do
- lambda {resource.atomic_update(true)}.should_not raise_error
- lambda {resource.atomic_update(false)}.should_not raise_error
+ expect {resource.atomic_update(true)}.not_to raise_error
+ expect {resource.atomic_update(false)}.not_to raise_error
end
it "anything else should raise an error" do
- lambda {resource.atomic_update(:copy)}.should raise_error(ArgumentError)
- lambda {resource.atomic_update(:move)}.should raise_error(ArgumentError)
- lambda {resource.atomic_update(958)}.should raise_error(ArgumentError)
+ expect {resource.atomic_update(:copy)}.to raise_error(ArgumentError)
+ expect {resource.atomic_update(:move)}.to raise_error(ArgumentError)
+ expect {resource.atomic_update(958)}.to raise_error(ArgumentError)
end
end
@@ -340,24 +340,24 @@ shared_examples_for "file resource not pointing to a real file" do
describe "when force_unlink is set to true" do
it ":create unlinks the target" do
- real_file?(path).should be_false
+ expect(real_file?(path)).to be_falsey
resource.force_unlink(true)
resource.run_action(:create)
- real_file?(path).should be_true
- binread(path).should == expected_content
- resource.should be_updated_by_last_action
+ expect(real_file?(path)).to be_truthy
+ expect(binread(path)).to eq(expected_content)
+ expect(resource).to be_updated_by_last_action
end
end
describe "when force_unlink is set to false" do
it ":create raises an error" do
- lambda {resource.run_action(:create) }.should raise_error(Chef::Exceptions::FileTypeMismatch)
+ expect {resource.run_action(:create) }.to raise_error(Chef::Exceptions::FileTypeMismatch)
end
end
describe "when force_unlink is not set (default)" do
it ":create raises an error" do
- lambda {resource.run_action(:create) }.should raise_error(Chef::Exceptions::FileTypeMismatch)
+ expect {resource.run_action(:create) }.to raise_error(Chef::Exceptions::FileTypeMismatch)
end
end
end
@@ -441,7 +441,7 @@ shared_examples_for "a configured file resource" do
after(:each) do
# symlink should never be followed
- binread(symlink_target).should == "This is so wrong!!!"
+ expect(binread(symlink_target)).to eq("This is so wrong!!!")
end
it_behaves_like "file resource not pointing to a real file"
@@ -477,7 +477,7 @@ shared_examples_for "a configured file resource" do
end
it "raises an InvalidSymlink error" do
- lambda { resource.run_action(:create) }.should raise_error(Chef::Exceptions::InvalidSymlink)
+ expect { resource.run_action(:create) }.to raise_error(Chef::Exceptions::InvalidSymlink)
end
it "issues a warning/assumption in whyrun mode" do
@@ -505,7 +505,7 @@ shared_examples_for "a configured file resource" do
FileUtils.rm_rf(link_path)
end
it "raises an InvalidSymlink error" do
- lambda { resource.run_action(:create) }.should raise_error(Chef::Exceptions::InvalidSymlink)
+ expect { resource.run_action(:create) }.to raise_error(Chef::Exceptions::InvalidSymlink)
end
it "issues a warning/assumption in whyrun mode" do
@@ -536,7 +536,7 @@ shared_examples_for "a configured file resource" do
end
it "raises an InvalidSymlink error" do
- lambda { resource.run_action(:create) }.should raise_error(Chef::Exceptions::FileTypeMismatch)
+ expect { resource.run_action(:create) }.to raise_error(Chef::Exceptions::FileTypeMismatch)
end
it "issues a warning/assumption in whyrun mode" do
@@ -564,7 +564,7 @@ shared_examples_for "a configured file resource" do
after(:each) do
# shared examples should not change our test setup of a file resource
# pointing at a symlink:
- resource.path.should == link_path
+ expect(resource.path).to eq(link_path)
FileUtils.rm_rf(link_path)
end
@@ -581,7 +581,7 @@ shared_examples_for "a configured file resource" do
it "does not replace the symlink with a real file" do
resource.run_action(:create)
- File.should be_symlink(link_path)
+ expect(File).to be_symlink(link_path)
end
end
@@ -593,17 +593,17 @@ shared_examples_for "a configured file resource" do
end
it "updates the source file content" do
- pending
+ skip
end
it "marks the resource as updated" do
resource.run_action(:create)
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
it "does not replace the symlink with a real file" do
resource.run_action(:create)
- File.should be_symlink(link_path)
+ expect(File).to be_symlink(link_path)
end
end
@@ -646,15 +646,15 @@ shared_examples_for "a configured file resource" do
after(:each) do
# shared examples should not change our test setup of a file resource
# pointing at a symlink:
- resource.path.should == link_to_link_path
+ expect(resource.path).to eq(link_to_link_path)
FileUtils.rm_rf(link_to_file_path)
FileUtils.rm_rf(link_to_link_path)
end
it "does not replace the symlink with a real file" do
resource.run_action(:create)
- File.should be_symlink(link_to_link_path)
- File.should be_symlink(link_to_file_path)
+ expect(File).to be_symlink(link_to_link_path)
+ expect(File).to be_symlink(link_to_file_path)
end
end
@@ -686,9 +686,9 @@ shared_examples_for "a configured file resource" do
it ":create updates the target" do
resource.force_unlink(true)
resource.run_action(:create)
- real_file?(path).should be_true
- binread(path).should == expected_content
- resource.should be_updated_by_last_action
+ expect(real_file?(path)).to be_truthy
+ expect(binread(path)).to eq(expected_content)
+ expect(resource).to be_updated_by_last_action
end
end
@@ -696,9 +696,9 @@ shared_examples_for "a configured file resource" do
it ":create updates the target" do
resource.force_unlink(true)
resource.run_action(:create)
- real_file?(path).should be_true
- binread(path).should == expected_content
- resource.should be_updated_by_last_action
+ expect(real_file?(path)).to be_truthy
+ expect(binread(path)).to eq(expected_content)
+ expect(resource).to be_updated_by_last_action
end
end
@@ -706,9 +706,9 @@ shared_examples_for "a configured file resource" do
it ":create updates the target" do
resource.force_unlink(true)
resource.run_action(:create)
- real_file?(path).should be_true
- binread(path).should == expected_content
- resource.should be_updated_by_last_action
+ expect(real_file?(path)).to be_truthy
+ expect(binread(path)).to eq(expected_content)
+ expect(resource).to be_updated_by_last_action
end
end
end
@@ -800,7 +800,7 @@ shared_examples_for "a configured file resource" do
end
before(:each) do
- path.bytesize.should <= 104
+ expect(path.bytesize).to be <= 104
UNIXServer.new(path)
end
@@ -813,7 +813,7 @@ shared_examples_for "a configured file resource" do
# Regression test for http://tickets.opscode.com/browse/CHEF-4082
context "when notification is configured" do
- describe "when path is specified with normal seperator" do
+ describe "when path is specified with normal separator" do
before do
@notified_resource = Chef::Resource.new("punk", resource.run_context)
resource.notifies(:run, @notified_resource, :immediately)
@@ -821,12 +821,12 @@ shared_examples_for "a configured file resource" do
end
it "should notify the other resources correctly" do
- resource.should be_updated_by_last_action
- resource.run_context.immediate_notifications(resource).length.should == 1
+ expect(resource).to be_updated_by_last_action
+ expect(resource.run_context.immediate_notifications(resource).length).to eq(1)
end
end
- describe "when path is specified with windows seperator", :windows_only do
+ describe "when path is specified with windows separator", :windows_only do
let(:path) {
File.join(test_file_dir, make_tmpname(file_base)).gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR)
}
@@ -838,8 +838,8 @@ shared_examples_for "a configured file resource" do
end
it "should notify the other resources correctly" do
- resource.should be_updated_by_last_action
- resource.run_context.immediate_notifications(resource).length.should == 1
+ expect(resource).to be_updated_by_last_action
+ expect(resource.run_context.immediate_notifications(resource).length).to eq(1)
end
end
end
@@ -847,7 +847,7 @@ shared_examples_for "a configured file resource" do
context "when the target file does not exist" do
before do
# Assert starting state is expected
- File.should_not exist(path)
+ expect(File).not_to exist(path)
end
describe "when running action :create" do
@@ -856,19 +856,19 @@ shared_examples_for "a configured file resource" do
end
it "creates the file when the :create action is run" do
- File.should exist(path)
+ expect(File).to exist(path)
end
it "creates the file with the correct content when the :create action is run" do
- binread(path).should == expected_content
+ expect(binread(path)).to eq(expected_content)
end
it "is marked as updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
it "should restore the security contexts on selinux", :selinux_only do
- selinux_security_context_restored?(path).should be_true
+ expect(selinux_security_context_restored?(path)).to be_truthy
end
end
@@ -878,15 +878,15 @@ shared_examples_for "a configured file resource" do
end
it "creates the file with the correct content" do
- binread(path).should == expected_content
+ expect(binread(path)).to eq(expected_content)
end
it "is marked as updated by last action" do
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
it "should restore the security contexts on selinux", :selinux_only do
- selinux_security_context_restored?(path).should be_true
+ expect(selinux_security_context_restored?(path)).to be_truthy
end
end
@@ -896,11 +896,11 @@ shared_examples_for "a configured file resource" do
end
it "deletes the file when the :delete action is run" do
- File.should_not exist(path)
+ expect(File).not_to exist(path)
end
it "is not marked updated by last action" do
- resource.should_not be_updated_by_last_action
+ expect(resource).not_to be_updated_by_last_action
end
end
end
@@ -1001,21 +1001,21 @@ shared_examples_for "a configured file resource" do
describe ":create action should run without any updates" do
before do
# Assert starting state is as expected
- File.should exist(path)
- sha256_checksum(path).should == @expected_checksum
+ expect(File).to exist(path)
+ expect(sha256_checksum(path)).to eq(@expected_checksum)
resource.run_action(:create)
end
it "does not overwrite the original when the :create action is run" do
- sha256_checksum(path).should == @expected_checksum
+ expect(sha256_checksum(path)).to eq(@expected_checksum)
end
it "does not update the mtime of the file when the :create action is run" do
- File.stat(path).mtime.should == @expected_mtime
+ expect(File.stat(path).mtime).to eq(@expected_mtime)
end
it "is not marked as updated by last action" do
- resource.should_not be_updated_by_last_action
+ expect(resource).not_to be_updated_by_last_action
end
end
end
diff --git a/spec/support/shared/functional/http.rb b/spec/support/shared/functional/http.rb
index 9a3389306d..963fbf1c5b 100644
--- a/spec/support/shared/functional/http.rb
+++ b/spec/support/shared/functional/http.rb
@@ -131,7 +131,7 @@ module ChefHTTPShared
}
#
- # in the presense of a transfer-encoding header, we must ignore the content-length (this bad content-length should work)
+ # in the presence of a transfer-encoding header, we must ignore the content-length (this bad content-length should work)
#
# (expected_content should be uncompressed)
diff --git a/spec/support/shared/functional/securable_resource.rb b/spec/support/shared/functional/securable_resource.rb
index 9999146dee..e016bb685d 100644
--- a/spec/support/shared/functional/securable_resource.rb
+++ b/spec/support/shared/functional/securable_resource.rb
@@ -163,8 +163,8 @@ shared_examples_for "a securable resource with existing target" do
let(:desired_gid) { 1337 }
let(:expected_gid) { 1337 }
- pending "should set an owner (Rerun specs under root)", :requires_unprivileged_user => true
- pending "should set a group (Rerun specs under root)", :requires_unprivileged_user => true
+ skip "should set an owner (Rerun specs under root)", :requires_unprivileged_user => true
+ skip "should set a group (Rerun specs under root)", :requires_unprivileged_user => true
describe "when setting the owner", :requires_root do
before do
@@ -173,11 +173,11 @@ shared_examples_for "a securable resource with existing target" do
end
it "should set an owner" do
- File.lstat(path).uid.should == expected_uid
+ expect(File.lstat(path).uid).to eq(expected_uid)
end
it "is marked as updated only if changes are made" do
- resource.updated_by_last_action?.should == expect_updated?
+ expect(resource.updated_by_last_action?).to eq(expect_updated?)
end
end
@@ -189,11 +189,11 @@ shared_examples_for "a securable resource with existing target" do
end
it "should set a group" do
- File.lstat(path).gid.should == expected_gid
+ expect(File.lstat(path).gid).to eq(expected_gid)
end
it "is marked as updated only if changes are made" do
- resource.updated_by_last_action?.should == expect_updated?
+ expect(resource.updated_by_last_action?).to eq(expect_updated?)
end
end
@@ -206,13 +206,12 @@ shared_examples_for "a securable resource with existing target" do
end
it "should set permissions as specified" do
- pending('Linux does not support lchmod', :if => resource.instance_of?(Chef::Resource::Link) && !os_x? && !freebsd?) do
- (File.lstat(path).mode & 007777).should == (@mode_string.oct & 007777)
- end
+ pending("Linux does not support lchmod")
+ expect{ File.lstat(path).mode & 007777 }.to eq(@mode_string.oct & 007777)
end
it "is marked as updated only if changes are made" do
- resource.updated_by_last_action?.should == expect_updated?
+ expect(resource.updated_by_last_action?).to eq(expect_updated?)
end
end
@@ -224,13 +223,12 @@ shared_examples_for "a securable resource with existing target" do
end
it "should set permissions in numeric form as a ruby-interpreted octal" do
- pending('Linux does not support lchmod', :if => resource.instance_of?(Chef::Resource::Link) && !os_x? && !freebsd?) do
- (File.lstat(path).mode & 007777).should == (@mode_integer & 007777)
- end
+ pending('Linux does not support lchmod')
+ expect{ File.lstat(path).mode & 007777 }.to eq(@mode_integer & 007777)
end
it "is marked as updated only if changes are made" do
- resource.updated_by_last_action?.should == expect_updated?
+ expect(resource.updated_by_last_action?).to eq(expect_updated?)
end
end
end
@@ -245,11 +243,11 @@ shared_examples_for "a securable resource with existing target" do
end
it "should set the owner" do
- descriptor.owner.should == SID.Administrator
+ expect(descriptor.owner).to eq(SID.Administrator)
end
it "is marked as updated only if changes are made" do
- resource.updated_by_last_action?.should == expect_updated?
+ expect(resource.updated_by_last_action?).to eq(expect_updated?)
end
end
@@ -260,11 +258,11 @@ shared_examples_for "a securable resource with existing target" do
end
it "should set the group" do
- descriptor.group.should == SID.Administrators
+ expect(descriptor.group).to eq(SID.Administrators)
end
it "is marked as updated only if changes are made" do
- resource.updated_by_last_action?.should == expect_updated?
+ expect(resource.updated_by_last_action?).to eq(expect_updated?)
end
end
@@ -276,11 +274,11 @@ shared_examples_for "a securable resource with existing target" do
end
it "should set the rights and deny_rights" do
- explicit_aces.should == denied_acl(SID.Guest, expected_modify_perms) + allowed_acl(SID.Guest, expected_read_perms)
+ expect(explicit_aces).to eq(denied_acl(SID.Guest, expected_modify_perms) + allowed_acl(SID.Guest, expected_read_perms))
end
it "is marked as updated only if changes are made" do
- resource.updated_by_last_action?.should == expect_updated?
+ expect(resource.updated_by_last_action?).to eq(expect_updated?)
end
end
end
@@ -291,81 +289,80 @@ shared_examples_for "a securable resource without existing target" do
include_context "diff disabled"
context "on Unix", :unix_only do
- pending "if we need any securable resource tests on Unix without existing target resource."
+ skip "if we need any securable resource tests on Unix without existing target resource."
end
context "on Windows", :windows_only do
include_context "use Windows permissions"
it "sets owner to Administrators on create if owner is not specified" do
- File.exist?(path).should == false
+ expect(File.exist?(path)).to eq(false)
resource.run_action(:create)
- descriptor.owner.should == SID.Administrators
+ expect(descriptor.owner).to eq(SID.Administrators)
end
it "sets owner when owner is specified" do
resource.owner 'Guest'
resource.run_action(:create)
- descriptor.owner.should == SID.Guest
+ expect(descriptor.owner).to eq(SID.Guest)
end
it "fails to set owner when owner has invalid characters" do
- lambda { resource.owner 'Lance "The Nose" Glindenberry III' }.should raise_error#(Chef::Exceptions::ValidationFailed)
+ expect { resource.owner 'Lance "The Nose" Glindenberry III' }.to raise_error#(Chef::Exceptions::ValidationFailed)
end
it "sets owner when owner is specified with a \\" do
resource.owner "#{ENV['USERDOMAIN']}\\Guest"
resource.run_action(:create)
- descriptor.owner.should == SID.Guest
+ expect(descriptor.owner).to eq(SID.Guest)
end
it "leaves owner alone if owner is not specified and resource already exists" do
# Set owner to Guest so it's not the same as the current user (which is the default on create)
resource.owner 'Guest'
resource.run_action(:create)
- descriptor.owner.should == SID.Guest
+ expect(descriptor.owner).to eq(SID.Guest)
new_resource = create_resource
- new_resource.owner.should == nil
+ expect(new_resource.owner).to eq(nil)
new_resource.run_action(:create)
- descriptor.owner.should == SID.Guest
+ expect(descriptor.owner).to eq(SID.Guest)
end
it "sets group to None on create if group is not specified" do
- resource.group.should == nil
- File.exist?(path).should == false
+ expect(resource.group).to eq(nil)
+ expect(File.exist?(path)).to eq(false)
resource.run_action(:create)
- descriptor.group.should == SID.None
+ expect(descriptor.group).to eq(SID.None)
end
it "sets group when group is specified" do
resource.group 'Everyone'
resource.run_action(:create)
- descriptor.group.should == SID.Everyone
+ expect(descriptor.group).to eq(SID.Everyone)
end
it "fails to set group when group has invalid characters" do
- lambda { resource.group 'Lance "The Nose" Glindenberry III' }.should raise_error(Chef::Exceptions::ValidationFailed)
+ expect { resource.group 'Lance "The Nose" Glindenberry III' }.to raise_error(Chef::Exceptions::ValidationFailed)
end
it "sets group when group is specified with a \\" do
- pending "Need to find a group containing a backslash that is on most peoples' machines" do
- resource.group "#{ENV['COMPUTERNAME']}\\Administrators"
- resource.run_action(:create)
- descriptor.group.should == SID.Everyone
- end
+ pending("Need to find a group containing a backslash that is on most peoples' machines")
+ resource.group "#{ENV['COMPUTERNAME']}\\Administrators"
+ resource.run_action(:create)
+ expect{ descriptor.group }.to eq(SID.Everyone)
end
it "leaves group alone if group is not specified and resource already exists" do
# Set group to Everyone so it's not the default (None)
resource.group 'Everyone'
resource.run_action(:create)
- descriptor.group.should == SID.Everyone
+ expect(descriptor.group).to eq(SID.Everyone)
new_resource = create_resource
- new_resource.group.should == nil
+ expect(new_resource.group).to eq(nil)
new_resource.run_action(:create)
- descriptor.group.should == SID.Everyone
+ expect(descriptor.group).to eq(SID.Everyone)
end
describe "with rights and deny_rights attributes" do
@@ -373,38 +370,38 @@ shared_examples_for "a securable resource without existing target" do
it "correctly sets :read rights" do
resource.rights(:read, 'Guest')
resource.run_action(:create)
- explicit_aces.should == allowed_acl(SID.Guest, expected_read_perms)
+ expect(explicit_aces).to eq(allowed_acl(SID.Guest, expected_read_perms))
end
it "correctly sets :read_execute rights" do
resource.rights(:read_execute, 'Guest')
resource.run_action(:create)
- explicit_aces.should == allowed_acl(SID.Guest, expected_read_execute_perms)
+ expect(explicit_aces).to eq(allowed_acl(SID.Guest, expected_read_execute_perms))
end
it "correctly sets :write rights" do
resource.rights(:write, 'Guest')
resource.run_action(:create)
- explicit_aces.should == allowed_acl(SID.Guest, expected_write_perms)
+ expect(explicit_aces).to eq(allowed_acl(SID.Guest, expected_write_perms))
end
it "correctly sets :modify rights" do
resource.rights(:modify, 'Guest')
resource.run_action(:create)
- explicit_aces.should == allowed_acl(SID.Guest, expected_modify_perms)
+ expect(explicit_aces).to eq(allowed_acl(SID.Guest, expected_modify_perms))
end
it "correctly sets :full_control rights" do
resource.rights(:full_control, 'Guest')
resource.run_action(:create)
- explicit_aces.should == allowed_acl(SID.Guest, expected_full_control_perms)
+ expect(explicit_aces).to eq(allowed_acl(SID.Guest, expected_full_control_perms))
end
it "correctly sets deny_rights" do
# deny is an ACE with full rights, but is a deny type ace, not an allow type
resource.deny_rights(:full_control, 'Guest')
resource.run_action(:create)
- explicit_aces.should == denied_acl(SID.Guest, expected_full_control_perms)
+ expect(explicit_aces).to eq(denied_acl(SID.Guest, expected_full_control_perms))
end
it "Sets multiple rights" do
@@ -412,9 +409,10 @@ shared_examples_for "a securable resource without existing target" do
resource.rights(:modify, 'Guest')
resource.run_action(:create)
- explicit_aces.should ==
+ expect(explicit_aces).to eq(
allowed_acl(SID.Everyone, expected_read_perms) +
allowed_acl(SID.Guest, expected_modify_perms)
+ )
end
it "Sets deny_rights ahead of rights" do
@@ -422,9 +420,10 @@ shared_examples_for "a securable resource without existing target" do
resource.deny_rights(:modify, 'Guest')
resource.run_action(:create)
- explicit_aces.should ==
+ expect(explicit_aces).to eq(
denied_acl(SID.Guest, expected_modify_perms) +
allowed_acl(SID.Everyone, expected_read_perms)
+ )
end
it "Sets deny_rights ahead of rights when specified in reverse order" do
@@ -432,9 +431,10 @@ shared_examples_for "a securable resource without existing target" do
resource.rights(:read, 'Everyone')
resource.run_action(:create)
- explicit_aces.should ==
+ expect(explicit_aces).to eq(
denied_acl(SID.Guest, expected_modify_perms) +
allowed_acl(SID.Everyone, expected_read_perms)
+ )
end
end
@@ -452,7 +452,7 @@ shared_examples_for "a securable resource without existing target" do
resource.group 'Everyone'
resource.run_action(:create)
- explicit_aces.should == [ ACE.access_allowed(SID.Guest, Security::FILE_GENERIC_READ) ]
+ expect(explicit_aces).to eq([ ACE.access_allowed(SID.Guest, Security::FILE_GENERIC_READ) ])
end
it "respects mode in numeric form as a ruby-interpreted octal" do
@@ -460,7 +460,7 @@ shared_examples_for "a securable resource without existing target" do
resource.owner 'Guest'
resource.run_action(:create)
- explicit_aces.should == [ ACE.access_allowed(SID.Guest, Security::FILE_GENERIC_READ | Security::FILE_GENERIC_WRITE | Security::FILE_GENERIC_EXECUTE | Security::DELETE) ]
+ expect(explicit_aces).to eq([ ACE.access_allowed(SID.Guest, Security::FILE_GENERIC_READ | Security::FILE_GENERIC_WRITE | Security::FILE_GENERIC_EXECUTE | Security::DELETE) ])
end
it "respects the owner, group and everyone bits of mode" do
@@ -469,11 +469,11 @@ shared_examples_for "a securable resource without existing target" do
resource.group 'Administrators'
resource.run_action(:create)
- explicit_aces.should == [
+ expect(explicit_aces).to eq([
ACE.access_allowed(SID.Guest, Security::FILE_GENERIC_READ | Security::FILE_GENERIC_WRITE | Security::FILE_GENERIC_EXECUTE | Security::DELETE),
ACE.access_allowed(SID.Administrators, Security::FILE_GENERIC_READ | Security::FILE_GENERIC_EXECUTE),
ACE.access_allowed(SID.Everyone, Security::FILE_GENERIC_READ)
- ]
+ ])
end
it "respects the individual read, write and execute bits of mode" do
@@ -482,31 +482,31 @@ shared_examples_for "a securable resource without existing target" do
resource.group 'Administrators'
resource.run_action(:create)
- explicit_aces.should == [
+ expect(explicit_aces).to eq([
ACE.access_allowed(SID.Guest, Security::FILE_GENERIC_READ),
ACE.access_allowed(SID.Administrators, Security::FILE_GENERIC_WRITE | Security::DELETE),
ACE.access_allowed(SID.Everyone, Security::FILE_GENERIC_EXECUTE)
- ]
+ ])
end
it 'warns when mode tries to set owner bits but owner is not specified' do
@warn = []
- Chef::Log.stub(:warn) { |msg| @warn << msg }
+ allow(Chef::Log).to receive(:warn) { |msg| @warn << msg }
resource.mode 0400
resource.run_action(:create)
- @warn.include?("Mode 400 includes bits for the owner, but owner is not specified").should be_true
+ expect(@warn.include?("Mode 400 includes bits for the owner, but owner is not specified")).to be_truthy
end
it 'warns when mode tries to set group bits but group is not specified' do
@warn = []
- Chef::Log.stub(:warn) { |msg| @warn << msg }
+ allow(Chef::Log).to receive(:warn) { |msg| @warn << msg }
resource.mode 0040
resource.run_action(:create)
- @warn.include?("Mode 040 includes bits for the group, but group is not specified").should be_true
+ expect(@warn.include?("Mode 040 includes bits for the group, but group is not specified")).to be_truthy
end
end
@@ -518,12 +518,12 @@ shared_examples_for "a securable resource without existing target" do
resource.run_action(:create)
descriptor.dacl.each do | ace |
- ace.inherited?.should == false
+ expect(ace.inherited?).to eq(false)
end
end
it "has the inheritable acls of parent directory if no acl is specified" do
- File.exist?(path).should == false
+ expect(File.exist?(path)).to eq(false)
# Collect the inheritable acls form the parent by creating a file without
# any specific ACLs
@@ -542,7 +542,7 @@ shared_examples_for "a securable resource without existing target" do
ace.inherited?
end
- resource_inherited_acls.should == parent_inherited_acls
+ expect(resource_inherited_acls).to eq(parent_inherited_acls)
end
end
diff --git a/spec/support/shared/functional/securable_resource_with_reporting.rb b/spec/support/shared/functional/securable_resource_with_reporting.rb
index b02137a06c..8a2ceed837 100644
--- a/spec/support/shared/functional/securable_resource_with_reporting.rb
+++ b/spec/support/shared/functional/securable_resource_with_reporting.rb
@@ -56,18 +56,18 @@ shared_examples_for "a securable resource with reporting" do
end
it "has empty values for file metadata in 'current_resource'" do
- current_resource.owner.should be_nil
- current_resource.group.should be_nil
- current_resource.mode.should be_nil
+ expect(current_resource.owner).to be_nil
+ expect(current_resource.group).to be_nil
+ expect(current_resource.mode).to be_nil
end
context "and no security metadata is specified in new_resource" do
it "sets the metadata values on the new_resource as strings after creating" do
resource.run_action(:create)
# TODO: most stable way to specify?
- resource.owner.should == Etc.getpwuid(Process.uid).name
- resource.group.should == @expected_group_name
- resource.mode.should == "0#{default_mode}"
+ expect(resource.owner).to eq(Etc.getpwuid(Process.uid).name)
+ expect(resource.group).to eq(@expected_group_name)
+ expect(resource.mode).to eq("0#{default_mode}")
end
end
@@ -87,7 +87,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets the owner on new_resource to the username (String) of the desired owner" do
- resource.owner.should == expected_user_name
+ expect(resource.owner).to eq(expected_user_name)
end
end
@@ -110,7 +110,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets the owner on new_resource to the uid (Integer) of the desired owner" do
- resource.owner.should == expected_uid
+ expect(resource.owner).to eq(expected_uid)
end
end
@@ -124,7 +124,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets the group on new_resource to the group name (String) of the group" do
- resource.group.should == expected_group_name
+ expect(resource.group).to eq(expected_group_name)
end
end
@@ -138,7 +138,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets the group on new_resource to the gid (Integer)" do
- resource.group.should == expected_gid
+ expect(resource.group).to eq(expected_gid)
end
end
@@ -155,7 +155,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets mode on the new_resource as a String" do
- resource.mode.should == expected_mode
+ expect(resource.mode).to eq(expected_mode)
end
end
@@ -169,7 +169,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets mode on the new resource as a String" do
- resource.mode.should == expected_mode
+ expect(resource.mode).to eq(expected_mode)
end
end
end
@@ -183,9 +183,9 @@ shared_examples_for "a securable resource with reporting" do
context "and no security metadata is specified in new_resource" do
it "sets the current values on current resource as strings" do
# TODO: most stable way to specify?
- current_resource.owner.should == Etc.getpwuid(Process.uid).name
- current_resource.group.should == @expected_group_name
- current_resource.mode.should == "0#{((0100666 - File.umask) & 07777).to_s(8)}"
+ expect(current_resource.owner).to eq(Etc.getpwuid(Process.uid).name)
+ expect(current_resource.group).to eq(@expected_group_name)
+ expect(current_resource.mode).to eq("0#{((0100666 - File.umask) & 07777).to_s(8)}")
end
end
@@ -198,7 +198,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets the owner on new_resource to the username (String) of the desired owner" do
- current_resource.owner.should == expected_user_name
+ expect(current_resource.owner).to eq(expected_user_name)
end
end
@@ -212,7 +212,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets the owner on new_resource to the uid (Integer) of the desired owner" do
- current_resource.owner.should == expected_uid
+ expect(current_resource.owner).to eq(expected_uid)
end
end
@@ -222,7 +222,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets the group on new_resource to the group name (String) of the group" do
- current_resource.group.should == @expected_group_name
+ expect(current_resource.group).to eq(@expected_group_name)
end
end
@@ -233,7 +233,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets the group on new_resource to the gid (Integer)" do
- current_resource.group.should == @expected_gid
+ expect(current_resource.group).to eq(@expected_gid)
end
end
@@ -247,7 +247,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets mode on the new_resource as a String" do
- current_resource.mode.should == expected_mode
+ expect(current_resource.mode).to eq(expected_mode)
end
end
@@ -260,7 +260,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets mode on the new resource as a String" do
- current_resource.mode.should == expected_mode
+ expect(current_resource.mode).to eq(expected_mode)
end
end
end
@@ -268,11 +268,6 @@ shared_examples_for "a securable resource with reporting" do
describe "reading file security metadata for reporting on windows", :windows_only do
- before do
- pending "windows reporting not yet fully supported"
- end
-
-
context "when the target file doesn't exist" do
# Windows reporting data should look like this (+/- ish):
@@ -284,23 +279,28 @@ shared_examples_for "a securable resource with reporting" do
end
it "has empty values for file metadata in 'current_resource'" do
- current_resource.owner.should be_nil
- current_resource.expanded_rights.should be_nil
+ pending "windows reporting not yet fully supported"
+ expect(current_resource.owner).to be_nil
+ expect(current_resource.expanded_rights).to be_nil
end
context "and no security metadata is specified in new_resource" do
+ before do
+ pending "windows reporting not yet fully supported"
+ end
+
it "sets the metadata values on the new_resource as strings after creating" do
resource.run_action(:create)
# TODO: most stable way to specify?
- resource.owner.should == etc.getpwuid(process.uid).name
- resource.state[:expanded_rights].should == { "CURRENTUSER" => { "permissions" => ALL_EXPANDED_PERMISSIONS, "flags" => [] }}
- resource.state[:expanded_deny_rights].should == {}
- resource.state[:inherits].should be_true
+ expect(resource.owner).to eq(etc.getpwuid(process.uid).name)
+ expect(resource.state[:expanded_rights]).to eq({ "CURRENTUSER" => { "permissions" => ALL_EXPANDED_PERMISSIONS, "flags" => [] }})
+ expect(resource.state[:expanded_deny_rights]).to eq({})
+ expect(resource.state[:inherits]).to be_truthy
end
end
- context "and owner is specified with a string (username) in new_resource" do
+ context "and owner is specified with a string (username) in new_resource" do
# TODO/bug: duplicated from the "securable resource" tests
let(:expected_user_name) { 'Guest' }
@@ -311,7 +311,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets the owner on new_resource to the username (string) of the desired owner" do
- resource.owner.should == expected_user_name
+ expect(resource.owner).to eq(expected_user_name)
end
end
@@ -322,12 +322,13 @@ shared_examples_for "a securable resource with reporting" do
let(:expected_user_name) { 'domain\user' }
before do
+ pending "windows reporting not yet fully supported"
resource.owner(expected_user_name)
resource.run_action(:create)
end
it "sets the owner on new_resource to the fully qualified name of the desired owner" do
- resource.owner.should == expected_user_name
+ expect(resource.owner).to eq(expected_user_name)
end
end
@@ -335,6 +336,7 @@ shared_examples_for "a securable resource with reporting" do
context "when the target file exists" do
before do
+ pending "windows reporting not yet fully supported"
FileUtils.touch(resource.path)
resource.action(:create)
end
@@ -342,8 +344,8 @@ shared_examples_for "a securable resource with reporting" do
context "and no security metadata is specified in new_resource" do
it "sets the current values on current resource as strings" do
# TODO: most stable way to specify?
- current_resource.owner.should == etc.getpwuid(process.uid).name
- current_resource.expanded_rights.should == { "CURRENTUSER" => ALL_EXPANDED_PERMISSIONS }
+ expect(current_resource.owner).to eq(etc.getpwuid(process.uid).name)
+ expect(current_resource.expanded_rights).to eq({ "CURRENTUSER" => ALL_EXPANDED_PERMISSIONS })
end
end
@@ -356,7 +358,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets the owner on current_resource to the username (string) of the desired owner" do
- current_resource.owner.should == expected_user_name
+ expect(current_resource.owner).to eq(expected_user_name)
end
end
@@ -370,7 +372,7 @@ shared_examples_for "a securable resource with reporting" do
end
it "sets the owner on current_resource to the fully qualified name of the desired owner" do
- current_resource.owner.should == expected_uid
+ expect(current_resource.owner).to eq(expected_uid)
end
end
@@ -378,7 +380,7 @@ shared_examples_for "a securable resource with reporting" do
# TODO: before do blah
it "sets the expanded_rights on the current resource" do
- pending
+ skip
end
end
@@ -386,7 +388,7 @@ shared_examples_for "a securable resource with reporting" do
# TODO: before do blah
it "sets the expanded rights on the current resource" do
- pending
+ skip
end
end
diff --git a/spec/support/shared/functional/win32_service.rb b/spec/support/shared/functional/win32_service.rb
new file mode 100644
index 0000000000..7dd1920418
--- /dev/null
+++ b/spec/support/shared/functional/win32_service.rb
@@ -0,0 +1,60 @@
+
+require 'chef/application/windows_service_manager'
+
+shared_context "using Win32::Service" do
+ # Some helper methods.
+
+ def test_service_exists?
+ ::Win32::Service.exists?("spec-service")
+ end
+
+ def test_service_state
+ ::Win32::Service.status("spec-service").current_state
+ end
+
+ def service_manager
+ Chef::Application::WindowsServiceManager.new(test_service)
+ end
+
+ def cleanup
+ # Uninstall if the test service is installed.
+ if test_service_exists?
+
+ # 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
+ end
+
+ ::Win32::Service.delete("spec-service")
+ end
+
+ # Delete the test_service_file if it exists
+ if File.exists?(test_service_file)
+ File.delete(test_service_file)
+ end
+
+ end
+
+
+ # Definition for the test-service
+
+ let(:test_service) {
+ {
+ :service_name => "spec-service",
+ :service_display_name => "Spec Test Service",
+ :service_description => "Service for testing Chef::Application::WindowsServiceManager.",
+ :service_file_path => File.expand_path(File.join(File.dirname(__FILE__), '../../platforms/win32/spec_service.rb'))
+ }
+ }
+
+ # 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) {
+ "#{ENV['SystemDrive']}\\windows\\temp\\spec_service_file"
+ }
+end
diff --git a/spec/support/shared/functional/windows_script.rb b/spec/support/shared/functional/windows_script.rb
index 866caf4b20..35b86dc4e8 100644
--- a/spec/support/shared/functional/windows_script.rb
+++ b/spec/support/shared/functional/windows_script.rb
@@ -83,29 +83,29 @@ shared_context Chef::Resource::WindowsScript do
it "should create a process with the expected architecture" do
resource.run_action(:run)
- get_process_architecture.should == expected_architecture_output.downcase
+ expect(get_process_architecture).to eq(expected_architecture_output.downcase)
end
it "should execute guards with the same architecture as the resource" do
resource.only_if resource_guard_command
resource.run_action(:run)
- get_process_architecture.should == expected_architecture_output.downcase
- get_guard_process_architecture.should == expected_architecture_output.downcase
- get_guard_process_architecture.should == get_process_architecture
+ expect(get_process_architecture).to eq(expected_architecture_output.downcase)
+ expect(get_guard_process_architecture).to eq(expected_architecture_output.downcase)
+ expect(get_guard_process_architecture).to eq(get_process_architecture)
end
let (:architecture) { :x86_64 }
it "should execute a 64-bit guard if the guard's architecture is specified as 64-bit", :windows64_only do
resource.only_if resource_guard_command, :architecture => :x86_64
resource.run_action(:run)
- get_guard_process_architecture.should == 'amd64'
+ expect(get_guard_process_architecture).to eq('amd64')
end
let (:architecture) { :i386 }
it "should execute a 32-bit guard if the guard's architecture is specified as 32-bit" do
resource.only_if resource_guard_command, :architecture => :i386
resource.run_action(:run)
- get_guard_process_architecture.should == 'x86'
+ expect(get_guard_process_architecture).to eq('x86')
end
end
end
@@ -122,11 +122,11 @@ shared_context Chef::Resource::WindowsScript do
context "when evaluating guards" do
it "has a guard_interpreter attribute set to the short name of the resource" do
- resource.guard_interpreter.should == resource.resource_name
+ expect(resource.guard_interpreter).to eq(resource.resource_name)
resource.not_if "findstr.exe /thiscommandhasnonzeroexitstatus"
expect(Chef::Resource).to receive(:resource_for_node).and_call_original
expect(resource.class).to receive(:new).and_call_original
- resource.should_skip?(:run).should be_false
+ expect(resource.should_skip?(:run)).to be_falsey
end
end
diff --git a/spec/support/shared/integration/knife_support.rb b/spec/support/shared/integration/knife_support.rb
index fd12998152..30293be6cf 100644
--- a/spec/support/shared/integration/knife_support.rb
+++ b/spec/support/shared/integration/knife_support.rb
@@ -103,6 +103,9 @@ module KnifeSupport
private
class KnifeResult
+
+ include ::RSpec::Matchers
+
def initialize(stdout, stderr, exit_code)
@stdout = stdout
@stderr = stderr
@@ -150,20 +153,20 @@ module KnifeSupport
stderr_actual = @stderr.sub(/^WARNING: No knife configuration file found\n/, '')
if expected[:stderr].is_a?(Regexp)
- stderr_actual.should =~ expected[:stderr]
+ expect(stderr_actual).to match(expected[:stderr])
else
- stderr_actual.should == expected[:stderr]
+ expect(stderr_actual).to eq(expected[:stderr])
end
stdout_actual = @stdout
if Chef::Platform.windows?
stderr_actual = stderr_actual.gsub("\r\n", "\n")
stdout_actual = stdout_actual.gsub("\r\n", "\n")
end
- @exit_code.should == expected[:exit_code]
+ expect(@exit_code).to eq(expected[:exit_code])
if expected[:stdout].is_a?(Regexp)
- stdout_actual.should =~ expected[:stdout]
+ expect(stdout_actual).to match(expected[:stdout])
else
- stdout_actual.should == expected[:stdout]
+ expect(stdout_actual).to eq(expected[:stdout])
end
end
end
diff --git a/spec/support/shared/matchers/exit_with_code.rb b/spec/support/shared/matchers/exit_with_code.rb
index 957586c85d..32ebf8db15 100644
--- a/spec/support/shared/matchers/exit_with_code.rb
+++ b/spec/support/shared/matchers/exit_with_code.rb
@@ -12,12 +12,12 @@ RSpec::Matchers.define :exit_with_code do |exp_code|
actual and actual == exp_code
end
- failure_message_for_should do |block|
+ failure_message do |block|
"expected block to call exit(#{exp_code}) but exit" +
(actual.nil? ? " not called" : "(#{actual}) was called")
end
- failure_message_for_should_not do |block|
+ failure_message_when_negated do |block|
"expected block not to call exit(#{exp_code})"
end
@@ -25,4 +25,8 @@ RSpec::Matchers.define :exit_with_code do |exp_code|
"expect block to call exit(#{exp_code})"
end
+ def supports_block_expectations?
+ true
+ end
+
end
diff --git a/spec/support/shared/unit/api_error_inspector.rb b/spec/support/shared/unit/api_error_inspector.rb
index 7577cb6c12..29faa07f29 100644
--- a/spec/support/shared/unit/api_error_inspector.rb
+++ b/spec/support/shared/unit/api_error_inspector.rb
@@ -23,7 +23,7 @@
# runs without error, but don't make assertions about the output. This is
# because aspects such as how information gets formatted, what's included, etc.
# are still in flux. When testing an inspector, change the outputter to use
-# STDOUT and manually check the ouput.
+# STDOUT and manually check the output.
shared_examples_for "an api error inspector" do
@@ -72,7 +72,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "synchronize the clock on your host"
@response = Net::HTTPUnauthorized.new("1.1", "401", "(response) unauthorized")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) unauthorized", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
@@ -88,7 +88,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "check your key and node name"
@response = Net::HTTPUnauthorized.new("1.1", "401", "(response) unauthorized")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) unauthorized", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
@@ -104,7 +104,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "forbidden"
@response = Net::HTTPForbidden.new("1.1", "403", "(response) forbidden")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) forbidden", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
@@ -120,7 +120,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "didn't like your data"
@response = Net::HTTPBadRequest.new("1.1", "400", "(response) bad request")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) bad request", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
@@ -136,7 +136,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "probably caused by a redirect to a get"
@response = Net::HTTPNotFound.new("1.1", "404", "(response) not found")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) not found", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
@@ -151,7 +151,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "sad trombone"
@response = Net::HTTPInternalServerError.new("1.1", "500", "(response) internal server error")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPFatalError.new("(exception) internal server error", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
@@ -166,7 +166,7 @@ shared_examples_for "an api error inspector" do
before do
@response_body = "sad trombone orchestra"
@response = Net::HTTPBadGateway.new("1.1", "502", "(response) bad gateway")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPFatalError.new("(exception) bad gateway", @response)
@inspector = described_class.new(@node_name, @exception, @config)
@inspector.add_explanation(@description)
diff --git a/spec/support/shared/unit/execute_resource.rb b/spec/support/shared/unit/execute_resource.rb
index 104aa7694e..e969a2ebd5 100644
--- a/spec/support/shared/unit/execute_resource.rb
+++ b/spec/support/shared/unit/execute_resource.rb
@@ -26,85 +26,89 @@ shared_examples_for "an execute resource" do
end
it "should create a new Chef::Resource::Execute" do
- @resource.should be_a_kind_of(Chef::Resource)
- @resource.should be_a_kind_of(Chef::Resource::Execute)
+ expect(@resource).to be_a_kind_of(Chef::Resource)
+ expect(@resource).to be_a_kind_of(Chef::Resource::Execute)
end
it "should set the command to the first argument to new" do
- @resource.command.should eql(resource_instance_name)
+ expect(@resource.command).to eql(resource_instance_name)
end
it "should accept an array on instantiation, too" do
resource = Chef::Resource::Execute.new(%w{something else})
- resource.should be_a_kind_of(Chef::Resource)
- resource.should be_a_kind_of(Chef::Resource::Execute)
- resource.command.should eql(%w{something else})
+ expect(resource).to be_a_kind_of(Chef::Resource)
+ expect(resource).to be_a_kind_of(Chef::Resource::Execute)
+ expect(resource.command).to eql(%w{something else})
end
it "should accept a string for the command to run" do
@resource.command "something"
- @resource.command.should eql("something")
+ expect(@resource.command).to eql("something")
end
it "should accept an array for the command to run" do
@resource.command %w{something else}
- @resource.command.should eql(%w{something else})
+ expect(@resource.command).to eql(%w{something else})
end
it "should accept a string for the cwd" do
@resource.cwd "something"
- @resource.cwd.should eql("something")
+ expect(@resource.cwd).to eql("something")
end
it "should accept a hash for the environment" do
test_hash = { :one => :two }
@resource.environment(test_hash)
- @resource.environment.should eql(test_hash)
+ expect(@resource.environment).to eql(test_hash)
end
it "allows the environment to be specified with #env" do
- @resource.should respond_to(:env)
+ expect(@resource).to respond_to(:env)
end
it "should accept a string for the group" do
@resource.group "something"
- @resource.group.should eql("something")
+ expect(@resource.group).to eql("something")
end
it "should accept an integer for the group" do
@resource.group 1
- @resource.group.should eql(1)
+ expect(@resource.group).to eql(1)
end
- it "should accept an array for the execution path in Chef-12 and log deprecation message" do
+ it "should accept an array for the execution path in Chef-12 and log deprecation message", :chef_lt_13_only do
expect(Chef::Log).to receive(:warn).at_least(:once)
@resource.path ["woot"]
expect(@resource.path).to eql(["woot"])
end
+ it "should raise an exception in chef-13", :chef_gte_13_only do
+ expect(@resource.path [ "woot" ]).to raise_error
+ end
+
it "should accept an integer for the return code" do
@resource.returns 1
- @resource.returns.should eql(1)
+ expect(@resource.returns).to eql(1)
end
it "should accept an integer for the timeout" do
@resource.timeout 1
- @resource.timeout.should eql(1)
+ expect(@resource.timeout).to eql(1)
end
it "should accept a string for the user" do
@resource.user "something"
- @resource.user.should eql("something")
+ expect(@resource.user).to eql("something")
end
it "should accept an integer for the user" do
@resource.user 1
- @resource.user.should eql(1)
+ expect(@resource.user).to eql(1)
end
it "should accept a string for creates" do
@resource.creates "something"
- @resource.creates.should eql("something")
+ expect(@resource.creates).to eql("something")
end
describe "when it has cwd, environment, group, path, return value, and a user" do
@@ -118,7 +122,7 @@ shared_examples_for "an execute resource" do
end
it "returns the command as its identity" do
- @resource.identity.should == "grep"
+ expect(@resource.identity).to eq("grep")
end
end
end
diff --git a/spec/support/shared/unit/file_system_support.rb b/spec/support/shared/unit/file_system_support.rb
index 3e771dd187..358f0c405c 100644
--- a/spec/support/shared/unit/file_system_support.rb
+++ b/spec/support/shared/unit/file_system_support.rb
@@ -56,7 +56,7 @@ module FileSystemSupport
def no_blocking_calls_allowed
[ Chef::ChefFS::FileSystem::MemoryFile, Chef::ChefFS::FileSystem::MemoryDir ].each do |c|
[ :children, :exists?, :read ].each do |m|
- c.any_instance.stub(m).and_raise("#{m.to_s} should not be called")
+ allow_any_instance_of(c).to receive(m).and_raise("#{m.to_s} should not be called")
end
end
end
@@ -64,7 +64,7 @@ module FileSystemSupport
def list_should_yield_paths(fs, pattern_str, *expected_paths)
result_paths = []
Chef::ChefFS::FileSystem.list(fs, pattern(pattern_str)).each { |result| result_paths << result.path }
- result_paths.should =~ expected_paths
+ expect(result_paths).to match_array(expected_paths)
end
end
diff --git a/spec/support/shared/unit/platform_introspector.rb b/spec/support/shared/unit/platform_introspector.rb
index f76ddbdf9e..9f42c985f8 100644
--- a/spec/support/shared/unit/platform_introspector.rb
+++ b/spec/support/shared/unit/platform_introspector.rb
@@ -44,49 +44,49 @@ shared_examples_for "a platform introspector" do
it "returns a default value when there is no known platform" do
node = Hash.new
- platform_introspector.value_for_platform(@platform_hash).should == "default"
+ expect(platform_introspector.value_for_platform(@platform_hash)).to eq("default")
end
it "returns a default value when there is no known platform family" do
- platform_introspector.value_for_platform_family(@platform_family_hash).should == "default value"
+ expect(platform_introspector.value_for_platform_family(@platform_family_hash)).to eq("default value")
end
it "returns a default value when the current platform doesn't match" do
node.automatic_attrs[:platform] = "not-a-known-platform"
- platform_introspector.value_for_platform(@platform_hash).should == "default"
+ expect(platform_introspector.value_for_platform(@platform_hash)).to eq("default")
end
it "returns a default value when current platform_family doesn't match" do
node.automatic_attrs[:platform_family] = "ultra-derived-linux"
- platform_introspector.value_for_platform_family(@platform_family_hash).should == "default value"
+ expect(platform_introspector.value_for_platform_family(@platform_family_hash)).to eq("default value")
end
it "returns a value based on the current platform" do
node.automatic_attrs[:platform] = "openbsd"
- platform_introspector.value_for_platform(@platform_hash).should == "openbsd"
+ expect(platform_introspector.value_for_platform(@platform_hash)).to eq("openbsd")
end
it "returns a value based on the current platform family" do
node.automatic_attrs[:platform_family] = "debian"
- platform_introspector.value_for_platform_family(@platform_family_hash).should == "debian value"
+ expect(platform_introspector.value_for_platform_family(@platform_family_hash)).to eq("debian value")
end
it "returns a version-specific value based on the current platform" do
node.automatic_attrs[:platform] = "openbsd"
node.automatic_attrs[:platform_version] = "1.2.3"
- platform_introspector.value_for_platform(@platform_hash).should == "openbsd-1.2.3"
+ expect(platform_introspector.value_for_platform(@platform_hash)).to eq("openbsd-1.2.3")
end
it "returns a value based on the current platform if version not found" do
node.automatic_attrs[:platform] = "openbsd"
node.automatic_attrs[:platform_version] = "0.0.0"
- platform_introspector.value_for_platform(@platform_hash).should == "openbsd"
+ expect(platform_introspector.value_for_platform(@platform_hash)).to eq("openbsd")
end
it 'returns the exact match' do
node.automatic_attrs[:platform] = 'exact_match'
node.automatic_attrs[:platform_version] = '1.2.3'
- platform_introspector.value_for_platform(@platform_hash).should == 'exact'
+ expect(platform_introspector.value_for_platform(@platform_hash)).to eq('exact')
end
it 'raises RuntimeError' do
@@ -98,20 +98,20 @@ shared_examples_for "a platform introspector" do
it 'should return the value for that match' do
node.automatic_attrs[:platform] = 'successful_matches'
node.automatic_attrs[:platform_version] = '2.9'
- platform_introspector.value_for_platform(@platform_hash).should == 'matched < 3.0'
+ expect(platform_introspector.value_for_platform(@platform_hash)).to eq('matched < 3.0')
end
describe "when platform versions is an array" do
it "returns a version-specific value based on the current platform" do
node.automatic_attrs[:platform] = "debian"
node.automatic_attrs[:platform_version] = "6"
- platform_introspector.value_for_platform(@platform_hash).should == "debian-5/6"
+ expect(platform_introspector.value_for_platform(@platform_hash)).to eq("debian-5/6")
end
it "returns a value based on the current platform if version not found" do
node.automatic_attrs[:platform] = "debian"
node.automatic_attrs[:platform_version] = "0.0.0"
- platform_introspector.value_for_platform(@platform_hash).should == "debian"
+ expect(platform_introspector.value_for_platform(@platform_hash)).to eq("debian")
end
end
@@ -119,17 +119,17 @@ shared_examples_for "a platform introspector" do
it "returns true if the node is a provided platform and platforms are provided as symbols" do
node.automatic_attrs[:platform] = 'ubuntu'
- platform_introspector.platform?([:redhat, :ubuntu]).should == true
+ expect(platform_introspector.platform?([:redhat, :ubuntu])).to eq(true)
end
it "returns true if the node is a provided platform and platforms are provided as strings" do
node.automatic_attrs[:platform] = 'ubuntu'
- platform_introspector.platform?(["redhat", "ubuntu"]).should == true
+ expect(platform_introspector.platform?(["redhat", "ubuntu"])).to eq(true)
end
it "returns false if the node is not of the provided platforms" do
node.automatic_attrs[:platform] = 'ubuntu'
- platform_introspector.platform?(:splatlinux).should == false
+ expect(platform_introspector.platform?(:splatlinux)).to eq(false)
end
end
@@ -137,21 +137,21 @@ shared_examples_for "a platform introspector" do
it "returns true if the node is in a provided platform family and families are provided as symbols" do
node.automatic_attrs[:platform_family] = 'debian'
- platform_introspector.platform_family?([:rhel, :debian]).should == true
+ expect(platform_introspector.platform_family?([:rhel, :debian])).to eq(true)
end
it "returns true if the node is a provided platform and platforms are provided as strings" do
node.automatic_attrs[:platform_family] = 'rhel'
- platform_introspector.platform_family?(["rhel", "debian"]).should == true
+ expect(platform_introspector.platform_family?(["rhel", "debian"])).to eq(true)
end
it "returns false if the node is not of the provided platforms" do
node.automatic_attrs[:platform_family] = 'suse'
- platform_introspector.platform_family?(:splatlinux).should == false
+ expect(platform_introspector.platform_family?(:splatlinux)).to eq(false)
end
it "returns false if the node is not of the provided platforms and platform_family is not set" do
- platform_introspector.platform_family?(:splatlinux).should == false
+ expect(platform_introspector.platform_family?(:splatlinux)).to eq(false)
end
end
@@ -170,13 +170,13 @@ shared_examples_for "a platform introspector" do
it "returns the correct default for a given platform" do
node.automatic_attrs[:platform] = "debian"
node.automatic_attrs[:platform_version] = '9000'
- platform_introspector.value_for_platform(@platform_hash).should == [ :restart, :reload, :status ]
+ expect(platform_introspector.value_for_platform(@platform_hash)).to eq([ :restart, :reload, :status ])
end
it "returns the correct platform+version specific value " do
node.automatic_attrs[:platform] = "debian"
node.automatic_attrs[:platform_version] = '4.0'
- platform_introspector.value_for_platform(@platform_hash).should == [:restart, :reload]
+ expect(platform_introspector.value_for_platform(@platform_hash)).to eq([:restart, :reload])
end
end
diff --git a/spec/support/shared/unit/provider/file.rb b/spec/support/shared/unit/provider/file.rb
index 85c8e2fb34..86f32c9e89 100644
--- a/spec/support/shared/unit/provider/file.rb
+++ b/spec/support/shared/unit/provider/file.rb
@@ -43,67 +43,67 @@ end
# this is all getting a bit stupid, CHEF-4802 cut to remove all this
def setup_normal_file
[ resource_path, normalized_path, windows_path].each do |path|
- File.stub(:file?).with(path).and_return(true)
- File.stub(:exists?).with(path).and_return(true)
- File.stub(:exist?).with(path).and_return(true)
- File.stub(:directory?).with(path).and_return(false)
- File.stub(:writable?).with(path).and_return(true)
- file_symlink_class.stub(:symlink?).with(path).and_return(false)
- File.stub(:realpath?).with(path).and_return(normalized_path)
+ allow(File).to receive(:file?).with(path).and_return(true)
+ allow(File).to receive(:exists?).with(path).and_return(true)
+ allow(File).to receive(:exist?).with(path).and_return(true)
+ allow(File).to receive(:directory?).with(path).and_return(false)
+ allow(File).to receive(:writable?).with(path).and_return(true)
+ allow(file_symlink_class).to receive(:symlink?).with(path).and_return(false)
+ allow(File).to receive(:realpath?).with(path).and_return(normalized_path)
end
- File.stub(:directory?).with(enclosing_directory).and_return(true)
+ allow(File).to receive(:directory?).with(enclosing_directory).and_return(true)
end
def setup_missing_file
[ resource_path, normalized_path, windows_path].each do |path|
- File.stub(:file?).with(path).and_return(false)
- File.stub(:realpath?).with(path).and_return(resource_path)
- File.stub(:exists?).with(path).and_return(false)
- File.stub(:exist?).with(path).and_return(false)
- File.stub(:directory?).with(path).and_return(false)
- File.stub(:writable?).with(path).and_return(false)
- file_symlink_class.stub(:symlink?).with(path).and_return(false)
+ allow(File).to receive(:file?).with(path).and_return(false)
+ allow(File).to receive(:realpath?).with(path).and_return(resource_path)
+ allow(File).to receive(:exists?).with(path).and_return(false)
+ allow(File).to receive(:exist?).with(path).and_return(false)
+ allow(File).to receive(:directory?).with(path).and_return(false)
+ allow(File).to receive(:writable?).with(path).and_return(false)
+ allow(file_symlink_class).to receive(:symlink?).with(path).and_return(false)
end
- File.stub(:directory?).with(enclosing_directory).and_return(true)
+ allow(File).to receive(:directory?).with(enclosing_directory).and_return(true)
end
def setup_symlink
[ resource_path, normalized_path, windows_path].each do |path|
- File.stub(:file?).with(path).and_return(true)
- File.stub(:realpath?).with(path).and_return(normalized_path)
- File.stub(:exists?).with(path).and_return(true)
- File.stub(:exist?).with(path).and_return(true)
- File.stub(:directory?).with(path).and_return(false)
- File.stub(:writable?).with(path).and_return(true)
- file_symlink_class.stub(:symlink?).with(path).and_return(true)
+ allow(File).to receive(:file?).with(path).and_return(true)
+ allow(File).to receive(:realpath?).with(path).and_return(normalized_path)
+ allow(File).to receive(:exists?).with(path).and_return(true)
+ allow(File).to receive(:exist?).with(path).and_return(true)
+ allow(File).to receive(:directory?).with(path).and_return(false)
+ allow(File).to receive(:writable?).with(path).and_return(true)
+ allow(file_symlink_class).to receive(:symlink?).with(path).and_return(true)
end
- File.stub(:directory?).with(enclosing_directory).and_return(true)
+ allow(File).to receive(:directory?).with(enclosing_directory).and_return(true)
end
def setup_unwritable_file
[ resource_path, normalized_path, windows_path].each do |path|
- File.stub(:file?).with(path).and_return(false)
- File.stub(:realpath?).with(path).and_raise(Errno::ENOENT)
- File.stub(:exists?).with(path).and_return(true)
- File.stub(:exist?).with(path).and_return(true)
- File.stub(:directory?).with(path).and_return(false)
- File.stub(:writable?).with(path).and_return(false)
- file_symlink_class.stub(:symlink?).with(path).and_return(false)
+ allow(File).to receive(:file?).with(path).and_return(false)
+ allow(File).to receive(:realpath?).with(path).and_raise(Errno::ENOENT)
+ allow(File).to receive(:exists?).with(path).and_return(true)
+ allow(File).to receive(:exist?).with(path).and_return(true)
+ allow(File).to receive(:directory?).with(path).and_return(false)
+ allow(File).to receive(:writable?).with(path).and_return(false)
+ allow(file_symlink_class).to receive(:symlink?).with(path).and_return(false)
end
- File.stub(:directory?).with(enclosing_directory).and_return(true)
+ allow(File).to receive(:directory?).with(enclosing_directory).and_return(true)
end
def setup_missing_enclosing_directory
[ resource_path, normalized_path, windows_path].each do |path|
- File.stub(:file?).with(path).and_return(false)
- File.stub(:realpath?).with(path).and_raise(Errno::ENOENT)
- File.stub(:exists?).with(path).and_return(false)
- File.stub(:exist?).with(path).and_return(false)
- File.stub(:directory?).with(path).and_return(false)
- File.stub(:writable?).with(path).and_return(false)
- file_symlink_class.stub(:symlink?).with(path).and_return(false)
+ allow(File).to receive(:file?).with(path).and_return(false)
+ allow(File).to receive(:realpath?).with(path).and_raise(Errno::ENOENT)
+ allow(File).to receive(:exists?).with(path).and_return(false)
+ allow(File).to receive(:exist?).with(path).and_return(false)
+ allow(File).to receive(:directory?).with(path).and_return(false)
+ allow(File).to receive(:writable?).with(path).and_return(false)
+ allow(file_symlink_class).to receive(:symlink?).with(path).and_return(false)
end
- File.stub(:directory?).with(enclosing_directory).and_return(false)
+ allow(File).to receive(:directory?).with(enclosing_directory).and_return(false)
end
# A File subclass that we use as a replacement for Tempfile. Some versions of
@@ -136,9 +136,9 @@ shared_examples_for Chef::Provider::File do
end
before(:each) do
- content.stub(:tempfile).and_return(tempfile)
- File.stub(:exist?).with(tempfile.path).and_call_original
- File.stub(:exists?).with(tempfile.path).and_call_original
+ allow(content).to receive(:tempfile).and_return(tempfile)
+ allow(File).to receive(:exist?).with(tempfile.path).and_call_original
+ allow(File).to receive(:exists?).with(tempfile.path).and_call_original
end
after do
@@ -147,15 +147,15 @@ shared_examples_for Chef::Provider::File do
end
it "should return a #{described_class}" do
- provider.should be_a_kind_of(described_class)
+ expect(provider).to be_a_kind_of(described_class)
end
it "should store the resource passed to new as new_resource" do
- provider.new_resource.should eql(resource)
+ expect(provider.new_resource).to eql(resource)
end
it "should store the node passed to new as node" do
- provider.node.should eql(node)
+ expect(provider.node).to eql(node)
end
context "when loading the current resource" do
@@ -167,15 +167,15 @@ shared_examples_for Chef::Provider::File do
#
it "should not try to load the content when the file is present" do
setup_normal_file
- provider.should_not_receive(:tempfile)
- provider.should_not_receive(:content)
+ expect(provider).not_to receive(:tempfile)
+ expect(provider).not_to receive(:content)
provider.load_current_resource
end
it "should not try to load the content when the file is missing" do
setup_missing_file
- provider.should_not_receive(:tempfile)
- provider.should_not_receive(:content)
+ expect(provider).not_to receive(:tempfile)
+ expect(provider).not_to receive(:content)
provider.load_current_resource
end
end
@@ -189,33 +189,33 @@ shared_examples_for Chef::Provider::File do
it "should load a current resource based on the one specified at construction" do
provider.load_current_resource
- provider.current_resource.should be_a_kind_of(Chef::Resource::File)
+ expect(provider.current_resource).to be_a_kind_of(Chef::Resource::File)
end
it "the loaded current_resource name should be the same as the resource name" do
provider.load_current_resource
- provider.current_resource.name.should eql(resource.name)
+ expect(provider.current_resource.name).to eql(resource.name)
end
it "the loaded current_resource path should be the same as the resoure path" do
provider.load_current_resource
- provider.current_resource.path.should eql(resource.path)
+ expect(provider.current_resource.path).to eql(resource.path)
end
it "the loaded current_resource content should be nil" do
provider.load_current_resource
- provider.current_resource.content.should eql(nil)
+ expect(provider.current_resource.content).to eql(nil)
end
it "it should call checksum if we are managing content" do
- provider.should_receive(:managing_content?).at_least(:once).and_return(true)
- provider.should_receive(:checksum).with(resource.path).and_return(tempfile_sha256)
+ expect(provider).to receive(:managing_content?).at_least(:once).and_return(true)
+ expect(provider).to receive(:checksum).with(resource.path).and_return(tempfile_sha256)
provider.load_current_resource
end
it "it should not call checksum if we are not managing content" do
- provider.should_receive(:managing_content?).at_least(:once).and_return(false)
- provider.should_not_receive(:checksum)
+ expect(provider).to receive(:managing_content?).at_least(:once).and_return(false)
+ expect(provider).not_to receive(:checksum)
provider.load_current_resource
end
end
@@ -227,27 +227,27 @@ shared_examples_for Chef::Provider::File do
it "the current_resource should be a Chef::Resource::File" do
provider.load_current_resource
- provider.current_resource.should be_a_kind_of(Chef::Resource::File)
+ expect(provider.current_resource).to be_a_kind_of(Chef::Resource::File)
end
it "the current_resource name should be the same as the resource name" do
provider.load_current_resource
- provider.current_resource.name.should eql(resource.name)
+ expect(provider.current_resource.name).to eql(resource.name)
end
it "the current_resource path should be the same as the resource path" do
provider.load_current_resource
- provider.current_resource.path.should eql(resource.path)
+ expect(provider.current_resource.path).to eql(resource.path)
end
it "the loaded current_resource content should be nil" do
provider.load_current_resource
- provider.current_resource.content.should eql(nil)
+ expect(provider.current_resource.content).to eql(nil)
end
it "it should not call checksum if we are not managing content" do
- provider.should_not_receive(:managing_content?)
- provider.should_not_receive(:checksum)
+ expect(provider).not_to receive(:managing_content?)
+ expect(provider).not_to receive(:checksum)
provider.load_current_resource
end
end
@@ -255,14 +255,14 @@ shared_examples_for Chef::Provider::File do
context "examining file security metadata on Unix with a file that exists" do
before do
# fake that we're on unix even if we're on windows
- Chef::Platform.stub(:windows?).and_return(false)
+ allow(Chef::Platform).to receive(:windows?).and_return(false)
# mock up the filesystem to behave like unix
setup_normal_file
stat_struct = double("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000)
resource_real_path = File.realpath(resource.path)
- File.should_receive(:stat).with(resource_real_path).at_least(:once).and_return(stat_struct)
- Etc.stub(:getgrgid).with(0).and_return(double("Group Ent", :name => "wheel"))
- Etc.stub(:getpwuid).with(0).and_return(double("User Ent", :name => "root"))
+ expect(File).to receive(:stat).with(resource_real_path).at_least(:once).and_return(stat_struct)
+ allow(Etc).to receive(:getgrgid).with(0).and_return(double("Group Ent", :name => "wheel"))
+ allow(Etc).to receive(:getpwuid).with(0).and_return(double("User Ent", :name => "root"))
end
context "when the new_resource does not specify any state" do
@@ -271,15 +271,15 @@ shared_examples_for Chef::Provider::File do
end
it "should load the permissions into the current_resource" do
- provider.current_resource.mode.should == "0600"
- provider.current_resource.owner.should == "root"
- provider.current_resource.group.should == "wheel"
+ expect(provider.current_resource.mode).to eq("0600")
+ expect(provider.current_resource.owner).to eq("root")
+ expect(provider.current_resource.group).to eq("wheel")
end
it "should not set the new_resource permissions" do
- provider.new_resource.group.should be_nil
- provider.new_resource.owner.should be_nil
- provider.new_resource.mode.should be_nil
+ expect(provider.new_resource.group).to be_nil
+ expect(provider.new_resource.owner).to be_nil
+ expect(provider.new_resource.mode).to be_nil
end
end
@@ -293,15 +293,15 @@ shared_examples_for Chef::Provider::File do
it "should load the permissions into the current_resource as numbers" do
# Mode is always loaded as string for reporting purposes.
- provider.current_resource.mode.should == "0600"
- provider.current_resource.owner.should == 0
- provider.current_resource.group.should == 0
+ expect(provider.current_resource.mode).to eq("0600")
+ expect(provider.current_resource.owner).to eq(0)
+ expect(provider.current_resource.group).to eq(0)
end
it "should not set the new_resource permissions" do
- provider.new_resource.group.should == 1
- provider.new_resource.owner.should == 1
- provider.new_resource.mode.should == 0644
+ expect(provider.new_resource.group).to eq(1)
+ expect(provider.new_resource.owner).to eq(1)
+ expect(provider.new_resource.mode).to eq(0644)
end
end
@@ -314,15 +314,15 @@ shared_examples_for Chef::Provider::File do
end
it "should load the permissions into the current_resource as symbols" do
- provider.current_resource.mode.should == "0600"
- provider.current_resource.owner.should == "root"
- provider.current_resource.group.should == "wheel"
+ expect(provider.current_resource.mode).to eq("0600")
+ expect(provider.current_resource.owner).to eq("root")
+ expect(provider.current_resource.group).to eq("wheel")
end
it "should not set the new_resource permissions" do
- provider.new_resource.group.should == "seattlehiphop"
- provider.new_resource.owner.should == "macklemore"
- provider.new_resource.mode.should == "0321"
+ expect(provider.new_resource.group).to eq("seattlehiphop")
+ expect(provider.new_resource.owner).to eq("macklemore")
+ expect(provider.new_resource.mode).to eq("0321")
end
end
@@ -331,7 +331,7 @@ shared_examples_for Chef::Provider::File do
context "examining file security metadata on Unix with a file that does not exist" do
before do
# fake that we're on unix even if we're on windows
- Chef::Platform.stub(:windows?).and_return(false)
+ allow(Chef::Platform).to receive(:windows?).and_return(false)
setup_missing_file
end
@@ -341,15 +341,15 @@ shared_examples_for Chef::Provider::File do
end
it "the current_resource permissions should be nil" do
- provider.current_resource.mode.should be_nil
- provider.current_resource.owner.should be_nil
- provider.current_resource.group.should be_nil
+ expect(provider.current_resource.mode).to be_nil
+ expect(provider.current_resource.owner).to be_nil
+ expect(provider.current_resource.group).to be_nil
end
it "should not set the new_resource permissions" do
- provider.new_resource.group.should be_nil
- provider.new_resource.owner.should be_nil
- provider.new_resource.mode.should be_nil
+ expect(provider.new_resource.group).to be_nil
+ expect(provider.new_resource.owner).to be_nil
+ expect(provider.new_resource.mode).to be_nil
end
end
@@ -362,15 +362,15 @@ shared_examples_for Chef::Provider::File do
end
it "the current_resource permissions should be nil" do
- provider.current_resource.mode.should be_nil
- provider.current_resource.owner.should be_nil
- provider.current_resource.group.should be_nil
+ expect(provider.current_resource.mode).to be_nil
+ expect(provider.current_resource.owner).to be_nil
+ expect(provider.current_resource.group).to be_nil
end
it "should not set the new_resource permissions" do
- provider.new_resource.group.should == 51948
- provider.new_resource.owner.should == 63945
- provider.new_resource.mode.should == 0123
+ expect(provider.new_resource.group).to eq(51948)
+ expect(provider.new_resource.owner).to eq(63945)
+ expect(provider.new_resource.mode).to eq(0123)
end
end
end
@@ -380,35 +380,35 @@ shared_examples_for Chef::Provider::File do
before do
# fake that we're on unix even if we're on windows
- Chef::Platform.stub(:windows?).and_return(false)
+ allow(Chef::Platform).to receive(:windows?).and_return(false)
# mock up the filesystem to behave like unix
setup_normal_file
stat_struct = double("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000)
resource_real_path = File.realpath(resource.path)
- File.stub(:stat).with(resource_real_path).and_return(stat_struct)
- Etc.stub(:getgrgid).with(0).and_return(double("Group Ent", :name => "wheel"))
- Etc.stub(:getpwuid).with(0).and_return(double("User Ent", :name => "root"))
+ allow(File).to receive(:stat).with(resource_real_path).and_return(stat_struct)
+ allow(Etc).to receive(:getgrgid).with(0).and_return(double("Group Ent", :name => "wheel"))
+ allow(Etc).to receive(:getpwuid).with(0).and_return(double("User Ent", :name => "root"))
provider.send(:load_resource_attributes_from_file, resource)
end
it "new_resource should record the new permission information" do
- provider.new_resource.group.should == "wheel"
- provider.new_resource.owner.should == "root"
- provider.new_resource.mode.should == "0600"
+ expect(provider.new_resource.group).to eq("wheel")
+ expect(provider.new_resource.owner).to eq("root")
+ expect(provider.new_resource.mode).to eq("0600")
end
end
context "when reporting security metadata on windows" do
it "records the file owner" do
- pending
+ skip
end
it "records rights for each user in the ACL" do
- pending
+ skip
end
it "records deny_rights for each user in the ACL" do
- pending
+ skip
end
end
@@ -419,12 +419,12 @@ shared_examples_for Chef::Provider::File do
[:create, :create_if_missing, :touch].each do |action|
context "action #{action}" do
it "raises EnclosingDirectoryDoesNotExist" do
- lambda {provider.run_action(action)}.should raise_error(Chef::Exceptions::EnclosingDirectoryDoesNotExist)
+ expect {provider.run_action(action)}.to raise_error(Chef::Exceptions::EnclosingDirectoryDoesNotExist)
end
it "does not raise an exception in why-run mode" do
Chef::Config[:why_run] = true
- lambda {provider.run_action(action)}.should_not raise_error
+ expect {provider.run_action(action)}.not_to raise_error
Chef::Config[:why_run] = false
end
end
@@ -435,12 +435,12 @@ shared_examples_for Chef::Provider::File do
before { setup_unwritable_file }
it "action delete raises InsufficientPermissions" do
- lambda {provider.run_action(:delete)}.should raise_error(Chef::Exceptions::InsufficientPermissions)
+ expect {provider.run_action(:delete)}.to raise_error(Chef::Exceptions::InsufficientPermissions)
end
it "action delete also raises InsufficientPermissions in why-run mode" do
Chef::Config[:why_run] = true
- lambda {provider.run_action(:delete)}.should raise_error(Chef::Exceptions::InsufficientPermissions)
+ expect {provider.run_action(:delete)}.to raise_error(Chef::Exceptions::InsufficientPermissions)
Chef::Config[:why_run] = false
end
end
@@ -449,30 +449,60 @@ shared_examples_for Chef::Provider::File do
context "action create" do
it "should create the file, update its contents and then set the acls on the file" do
setup_missing_file
- provider.should_receive(:do_create_file)
- provider.should_receive(:do_contents_changes)
- provider.should_receive(:do_acl_changes)
- provider.should_receive(:load_resource_attributes_from_file)
+ expect(provider).to receive(:do_create_file)
+ expect(provider).to receive(:do_contents_changes)
+ expect(provider).to receive(:do_acl_changes)
+ expect(provider).to receive(:load_resource_attributes_from_file)
provider.run_action(:create)
end
+ context "do_validate_content" do
+ before { setup_normal_file }
+
+ let(:tempfile) {
+ t = double('Tempfile', :path => "/tmp/foo-bar-baz", :closed? => true)
+ allow(content).to receive(:tempfile).and_return(t)
+ t
+ }
+
+ let(:verification) { double("Verification") }
+
+ context "with user-supplied verifications" do
+ it "calls #verify on each verification with tempfile path" do
+ allow(Chef::Resource::File::Verification).to receive(:new).and_return(verification)
+ provider.new_resource.verify "true"
+ provider.new_resource.verify "true"
+ expect(verification).to receive(:verify).with(tempfile.path).twice.and_return(true)
+ provider.send(:do_validate_content)
+ end
+
+ it "raises an exception if any verification fails" do
+ provider.new_resource.verify "true"
+ provider.new_resource.verify "false"
+ allow(verification).to receive(:verify).with("true").and_return(true)
+ allow(verification).to receive(:verify).with("false").and_return(false)
+ expect{provider.send(:do_validate_content)}.to raise_error(Chef::Exceptions::ValidationFailed)
+ end
+ end
+ end
+
context "do_create_file" do
context "when the file exists" do
before { setup_normal_file }
it "should not create the file" do
provider.load_current_resource
- provider.deployment_strategy.should_not_receive(:create).with(resource_path)
+ expect(provider.deployment_strategy).not_to receive(:create).with(resource_path)
provider.send(:do_create_file)
- provider.send(:needs_creating?).should == false
+ expect(provider.send(:needs_creating?)).to eq(false)
end
end
context "when the file does not exist" do
before { setup_missing_file }
it "should create the file" do
provider.load_current_resource
- provider.deployment_strategy.should_receive(:create).with(resource_path)
+ expect(provider.deployment_strategy).to receive(:create).with(resource_path)
provider.send(:do_create_file)
- provider.send(:needs_creating?).should == true
+ expect(provider.send(:needs_creating?)).to eq(true)
end
end
end
@@ -483,10 +513,10 @@ shared_examples_for Chef::Provider::File do
setup_normal_file
provider.load_current_resource
tempfile = double('Tempfile', :path => "/tmp/foo-bar-baz")
- content.stub(:tempfile).and_return(tempfile)
- File.should_receive(:exists?).with("/tmp/foo-bar-baz").and_return(true)
- tempfile.should_receive(:close).once
- tempfile.should_receive(:unlink).once
+ allow(content).to receive(:tempfile).and_return(tempfile)
+ expect(File).to receive(:exists?).with("/tmp/foo-bar-baz").and_return(true)
+ expect(tempfile).to receive(:close).once
+ expect(tempfile).to receive(:unlink).once
end
context "when the contents have changed" do
@@ -494,64 +524,64 @@ shared_examples_for Chef::Provider::File do
let(:tempfile_sha256) { "42971f0ddce0cb20cf7660a123ffa1a1543beb2f1e7cd9d65858764a27f3201d" }
let(:diff_for_reporting) { "+++\n---\n+foo\n-bar\n" }
before do
- provider.stub(:contents_changed?).and_return(true)
+ allow(provider).to receive(:contents_changed?).and_return(true)
diff = double('Diff', :for_output => ['+++','---','+foo','-bar'],
:for_reporting => diff_for_reporting )
- diff.stub(:diff).with(resource_path, tempfile_path).and_return(true)
- provider.should_receive(:diff).at_least(:once).and_return(diff)
- provider.should_receive(:managing_content?).at_least(:once).and_return(true)
- provider.should_receive(:checksum).with(tempfile_path).and_return(tempfile_sha256)
- provider.should_receive(:checksum).with(resource_path).and_return(tempfile_sha256)
- provider.deployment_strategy.should_receive(:deploy).with(tempfile_path, normalized_path)
+ allow(diff).to receive(:diff).with(resource_path, tempfile_path).and_return(true)
+ expect(provider).to receive(:diff).at_least(:once).and_return(diff)
+ expect(provider).to receive(:managing_content?).at_least(:once).and_return(true)
+ expect(provider).to receive(:checksum).with(tempfile_path).and_return(tempfile_sha256)
+ expect(provider).to receive(:checksum).with(resource_path).and_return(tempfile_sha256)
+ expect(provider.deployment_strategy).to receive(:deploy).with(tempfile_path, normalized_path)
end
context "when the file was created" do
- before { provider.should_receive(:needs_creating?).at_least(:once).and_return(true) }
+ before { expect(provider).to receive(:needs_creating?).at_least(:once).and_return(true) }
it "does not backup the file and does not produce a diff for reporting" do
- provider.should_not_receive(:do_backup)
+ expect(provider).not_to receive(:do_backup)
provider.send(:do_contents_changes)
- resource.diff.should be_nil
+ expect(resource.diff).to be_nil
end
end
context "when the file was not created" do
- before { provider.should_receive(:needs_creating?).at_least(:once).and_return(false) }
+ before { expect(provider).to receive(:needs_creating?).at_least(:once).and_return(false) }
it "backs up the file and produces a diff for reporting" do
- provider.should_receive(:do_backup)
+ expect(provider).to receive(:do_backup)
provider.send(:do_contents_changes)
- resource.diff.should == diff_for_reporting
+ expect(resource.diff).to eq(diff_for_reporting)
end
end
end
it "does nothing when the contents have not changed" do
- provider.stub(:contents_changed?).and_return(false)
- provider.should_not_receive(:diff)
+ allow(provider).to receive(:contents_changed?).and_return(false)
+ expect(provider).not_to receive(:diff)
provider.send(:do_contents_changes)
end
end
it "does nothing when there is no content to deploy (tempfile returned from contents is nil)" do
- provider.send(:content).should_receive(:tempfile).at_least(:once).and_return(nil)
- provider.should_not_receive(:diff)
- lambda{ provider.send(:do_contents_changes) }.should_not raise_error
+ expect(provider.send(:content)).to receive(:tempfile).at_least(:once).and_return(nil)
+ expect(provider).not_to receive(:diff)
+ expect{ provider.send(:do_contents_changes) }.not_to raise_error
end
it "raises an exception when the content object returns a tempfile with a nil path" do
tempfile = double('Tempfile', :path => nil)
- provider.send(:content).should_receive(:tempfile).at_least(:once).and_return(tempfile)
- lambda{ provider.send(:do_contents_changes) }.should raise_error
+ expect(provider.send(:content)).to receive(:tempfile).at_least(:once).and_return(tempfile)
+ expect{ provider.send(:do_contents_changes) }.to raise_error
end
it "raises an exception when the content object returns a tempfile that does not exist" do
tempfile = double('Tempfile', :path => "/tmp/foo-bar-baz")
- provider.send(:content).should_receive(:tempfile).at_least(:once).and_return(tempfile)
- File.should_receive(:exists?).with("/tmp/foo-bar-baz").and_return(false)
- lambda{ provider.send(:do_contents_changes) }.should raise_error
+ expect(provider.send(:content)).to receive(:tempfile).at_least(:once).and_return(tempfile)
+ expect(File).to receive(:exists?).with("/tmp/foo-bar-baz").and_return(false)
+ expect{ provider.send(:do_contents_changes) }.to raise_error
end
end
context "do_acl_changes" do
it "needs tests" do
- pending
+ skip
end
end
@@ -560,11 +590,11 @@ shared_examples_for Chef::Provider::File do
before do
setup_normal_file
provider.load_current_resource
- provider.stub(:resource_updated?).and_return(true)
+ allow(provider).to receive(:resource_updated?).and_return(true)
end
it "should check for selinux_enabled? by default" do
- provider.should_receive(:selinux_enabled?)
+ expect(provider).to receive(:selinux_enabled?)
provider.send(:do_selinux)
end
@@ -580,27 +610,27 @@ shared_examples_for Chef::Provider::File do
context "when selinux is enabled on the system" do
before do
- provider.should_receive(:selinux_enabled?).and_return(true)
+ expect(provider).to receive(:selinux_enabled?).and_return(true)
end
it "restores security context on the file" do
- provider.should_receive(:restore_security_context).with(normalized_path, false)
+ expect(provider).to receive(:restore_security_context).with(normalized_path, false)
provider.send(:do_selinux)
end
it "restores security context recursively when told so" do
- provider.should_receive(:restore_security_context).with(normalized_path, true)
+ expect(provider).to receive(:restore_security_context).with(normalized_path, true)
provider.send(:do_selinux, true)
end
end
context "when selinux is disabled on the system" do
before do
- provider.should_receive(:selinux_enabled?).and_return(false)
+ expect(provider).to receive(:selinux_enabled?).and_return(false)
end
it "should not restore security context" do
- provider.should_not_receive(:restore_security_context)
+ expect(provider).not_to receive(:restore_security_context)
provider.send(:do_selinux)
end
end
@@ -617,7 +647,7 @@ shared_examples_for Chef::Provider::File do
end
it "should not check for selinux_enabled?" do
- provider.should_not_receive(:selinux_enabled?)
+ expect(provider).not_to receive(:selinux_enabled?)
provider.send(:do_selinux)
end
end
@@ -625,11 +655,11 @@ shared_examples_for Chef::Provider::File do
context "when resource is not updated" do
before do
- provider.stub(:resource_updated?).and_return(false)
+ allow(provider).to receive(:resource_updated?).and_return(false)
end
it "should not check for selinux_enabled?" do
- provider.should_not_receive(:selinux_enabled?)
+ expect(provider).not_to receive(:selinux_enabled?)
provider.send(:do_selinux)
end
end
@@ -643,29 +673,29 @@ shared_examples_for Chef::Provider::File do
context "when the file is not a symlink" do
before { setup_normal_file }
it "should backup and delete the file and be updated by the last action" do
- provider.should_receive(:do_backup).at_least(:once).and_return(true)
- File.should_receive(:delete).with(resource_path).and_return(true)
+ expect(provider).to receive(:do_backup).at_least(:once).and_return(true)
+ expect(File).to receive(:delete).with(resource_path).and_return(true)
provider.run_action(:delete)
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
context "when the file is a symlink" do
before { setup_symlink }
it "should not backup the symlink" do
- provider.should_not_receive(:do_backup)
- File.should_receive(:delete).with(resource_path).and_return(true)
+ expect(provider).not_to receive(:do_backup)
+ expect(File).to receive(:delete).with(resource_path).and_return(true)
provider.run_action(:delete)
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
end
context "when the file is not writable" do
before { setup_unwritable_file }
it "should not try to backup or delete the file, and should not be updated by last action" do
- provider.should_not_receive(:do_backup)
- File.should_not_receive(:delete)
- lambda { provider.run_action(:delete) }.should raise_error()
- resource.should_not be_updated_by_last_action
+ expect(provider).not_to receive(:do_backup)
+ expect(File).not_to receive(:delete)
+ expect { provider.run_action(:delete) }.to raise_error()
+ expect(resource).not_to be_updated_by_last_action
end
end
end
@@ -674,10 +704,10 @@ shared_examples_for Chef::Provider::File do
before { setup_missing_file }
it "should not try to backup or delete the file, and should not be updated by last action" do
- provider.should_not_receive(:do_backup)
- File.should_not_receive(:delete)
- lambda { provider.run_action(:delete) }.should_not raise_error
- resource.should_not be_updated_by_last_action
+ expect(provider).not_to receive(:do_backup)
+ expect(File).not_to receive(:delete)
+ expect { provider.run_action(:delete) }.not_to raise_error
+ expect(resource).not_to be_updated_by_last_action
end
end
end
@@ -686,19 +716,19 @@ shared_examples_for Chef::Provider::File do
context "when the file does not exist" do
before { setup_missing_file }
it "should update the atime/mtime on action_touch" do
- File.should_receive(:utime).once
- provider.should_receive(:action_create)
+ expect(File).to receive(:utime).once
+ expect(provider).to receive(:action_create)
provider.run_action(:touch)
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
context "when the file exists" do
before { setup_normal_file }
it "should update the atime/mtime on action_touch" do
- File.should_receive(:utime).once
- provider.should_receive(:action_create)
+ expect(File).to receive(:utime).once
+ expect(provider).to receive(:action_create)
provider.run_action(:touch)
- resource.should be_updated_by_last_action
+ expect(resource).to be_updated_by_last_action
end
end
end
@@ -707,7 +737,7 @@ shared_examples_for Chef::Provider::File do
context "when the file does not exist" do
before { setup_missing_file }
it "should call action_create" do
- provider.should_receive(:action_create)
+ expect(provider).to receive(:action_create)
provider.run_action(:create_if_missing)
end
end
@@ -715,7 +745,7 @@ shared_examples_for Chef::Provider::File do
context "when the file exists" do
before { setup_normal_file }
it "should not call action_create" do
- provider.should_not_receive(:action_create)
+ expect(provider).not_to receive(:action_create)
provider.run_action(:create_if_missing)
end
end
@@ -728,27 +758,27 @@ shared_examples_for "a file provider with content field" do
context "when testing managing_content?" do
it "should be false when creating a file without content" do
provider.action = :create
- resource.stub(:content).and_return(nil)
- resource.stub(:checksum).and_return(nil)
- expect(provider.send(:managing_content?)).to be_false
+ allow(resource).to receive(:content).and_return(nil)
+ allow(resource).to receive(:checksum).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_falsey
end
it "should be true when creating a file with content" do
provider.action = :create
- resource.stub(:content).and_return("flurbleblobbleblooble")
- resource.stub(:checksum).and_return(nil)
- expect(provider.send(:managing_content?)).to be_true
+ allow(resource).to receive(:content).and_return("flurbleblobbleblooble")
+ allow(resource).to receive(:checksum).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_truthy
end
it "should be true when checksum is set on the content (no matter how crazy)" do
provider.action = :create_if_missing
- resource.stub(:checksum).and_return("1234123234234234")
- resource.stub(:content).and_return(nil)
- expect(provider.send(:managing_content?)).to be_true
+ allow(resource).to receive(:checksum).and_return("1234123234234234")
+ allow(resource).to receive(:content).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_truthy
end
it "should be false when action is create_if_missing" do
provider.action = :create_if_missing
- resource.stub(:content).and_return("flurbleblobbleblooble")
- resource.stub(:checksum).and_return(nil)
- expect(provider.send(:managing_content?)).to be_false
+ allow(resource).to receive(:content).and_return("flurbleblobbleblooble")
+ allow(resource).to receive(:checksum).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_falsey
end
end
end
@@ -757,32 +787,31 @@ shared_examples_for "a file provider with source field" do
context "when testing managing_content?" do
it "should be false when creating a file without content" do
provider.action = :create
- resource.stub(:content).and_return(nil)
- resource.stub(:source).and_return(nil)
- resource.stub(:checksum).and_return(nil)
- expect(provider.send(:managing_content?)).to be_false
+ allow(resource).to receive(:content).and_return(nil)
+ allow(resource).to receive(:source).and_return(nil)
+ allow(resource).to receive(:checksum).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_falsey
end
it "should be true when creating a file with content" do
provider.action = :create
- resource.stub(:content).and_return(nil)
- resource.stub(:source).and_return("http://somewhere.com/something.php")
- resource.stub(:checksum).and_return(nil)
- expect(provider.send(:managing_content?)).to be_true
+ allow(resource).to receive(:content).and_return(nil)
+ allow(resource).to receive(:source).and_return("http://somewhere.com/something.php")
+ allow(resource).to receive(:checksum).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_truthy
end
it "should be true when checksum is set on the content (no matter how crazy)" do
provider.action = :create_if_missing
- resource.stub(:content).and_return(nil)
- resource.stub(:source).and_return(nil)
- resource.stub(:checksum).and_return("1234123234234234")
- expect(provider.send(:managing_content?)).to be_true
+ allow(resource).to receive(:content).and_return(nil)
+ allow(resource).to receive(:source).and_return(nil)
+ allow(resource).to receive(:checksum).and_return("1234123234234234")
+ expect(provider.send(:managing_content?)).to be_truthy
end
it "should be false when action is create_if_missing" do
provider.action = :create_if_missing
- resource.stub(:content).and_return(nil)
- resource.stub(:source).and_return("http://somewhere.com/something.php")
- resource.stub(:checksum).and_return(nil)
- expect(provider.send(:managing_content?)).to be_false
+ allow(resource).to receive(:content).and_return(nil)
+ allow(resource).to receive(:source).and_return("http://somewhere.com/something.php")
+ allow(resource).to receive(:checksum).and_return(nil)
+ expect(provider.send(:managing_content?)).to be_falsey
end
end
end
-
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 42f948d494..fc7c79ef7d 100644
--- a/spec/support/shared/unit/provider/useradd_based_user_provider.rb
+++ b/spec/support/shared/unit/provider/useradd_based_user_provider.rb
@@ -53,39 +53,39 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
supported_useradd_options.each do |attribute, option|
it "should check for differences in #{attribute} between the new and current resources" do
- @current_resource.should_receive(attribute)
- @new_resource.should_receive(attribute)
+ expect(@current_resource).to receive(attribute)
+ expect(@new_resource).to receive(attribute)
provider.universal_options
end
it "should set the option for #{attribute} if the new resources #{attribute} is not nil" do
- @new_resource.stub(attribute).and_return("hola")
- provider.universal_options.should eql([option, 'hola'])
+ allow(@new_resource).to receive(attribute).and_return("hola")
+ expect(provider.universal_options).to eql([option, 'hola'])
end
it "should set the option for #{attribute} if the new resources #{attribute} is not nil, without homedir management" do
- @new_resource.stub(:supports).and_return({:manage_home => false,
+ allow(@new_resource).to receive(:supports).and_return({:manage_home => false,
:non_unique => false})
- @new_resource.stub(attribute).and_return("hola")
- provider.universal_options.should eql([option, 'hola'])
+ allow(@new_resource).to receive(attribute).and_return("hola")
+ expect(provider.universal_options).to eql([option, 'hola'])
end
it "should set the option for #{attribute} if the new resources #{attribute} is not nil, without homedir management (using real attributes)" do
- @new_resource.stub(:manage_home).and_return(false)
- @new_resource.stub(:non_unique).and_return(false)
- @new_resource.stub(:non_unique).and_return(false)
- @new_resource.stub(attribute).and_return("hola")
- provider.universal_options.should eql([option, 'hola'])
+ allow(@new_resource).to receive(:manage_home).and_return(false)
+ allow(@new_resource).to receive(:non_unique).and_return(false)
+ allow(@new_resource).to receive(:non_unique).and_return(false)
+ allow(@new_resource).to receive(attribute).and_return("hola")
+ expect(provider.universal_options).to eql([option, 'hola'])
end
end
it "should combine all the possible options" do
combined_opts = []
supported_useradd_options.sort{ |a,b| a[0] <=> b[0] }.each do |attribute, option|
- @new_resource.stub(attribute).and_return("hola")
+ allow(@new_resource).to receive(attribute).and_return("hola")
combined_opts << option << 'hola'
end
- provider.universal_options.should eql(combined_opts)
+ expect(provider.universal_options).to eql(combined_opts)
end
describe "when we want to create a system user" do
@@ -96,55 +96,55 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
it "should set useradd -r" do
@new_resource.system(true)
- provider.useradd_options.should == [ "-r" ]
+ expect(provider.useradd_options).to eq([ "-r" ])
end
end
describe "when the resource has a different home directory and supports home directory management" do
before do
- @new_resource.stub(:home).and_return("/wowaweea")
- @new_resource.stub(:supports).and_return({:manage_home => true,
+ allow(@new_resource).to receive(:home).and_return("/wowaweea")
+ allow(@new_resource).to receive(:supports).and_return({:manage_home => true,
:non_unique => false})
end
it "should set -m -d /homedir" do
- provider.universal_options.should == %w[-d /wowaweea -m]
- provider.useradd_options.should == []
+ expect(provider.universal_options).to eq(%w[-d /wowaweea -m])
+ expect(provider.useradd_options).to eq([])
end
end
describe "when the resource has a different home directory and supports home directory management (using real attributes)" do
before do
- @new_resource.stub(:home).and_return("/wowaweea")
- @new_resource.stub(:manage_home).and_return(true)
- @new_resource.stub(:non_unique).and_return(false)
+ allow(@new_resource).to receive(:home).and_return("/wowaweea")
+ allow(@new_resource).to receive(:manage_home).and_return(true)
+ allow(@new_resource).to receive(:non_unique).and_return(false)
end
it "should set -m -d /homedir" do
- provider.universal_options.should eql(%w[-d /wowaweea -m])
- provider.useradd_options.should == []
+ expect(provider.universal_options).to eql(%w[-d /wowaweea -m])
+ expect(provider.useradd_options).to eq([])
end
end
describe "when the resource supports non_unique ids" do
before do
- @new_resource.stub(:supports).and_return({:manage_home => false,
+ allow(@new_resource).to receive(:supports).and_return({:manage_home => false,
:non_unique => true})
end
it "should set -m -o" do
- provider.universal_options.should eql([ "-o" ])
+ expect(provider.universal_options).to eql([ "-o" ])
end
end
describe "when the resource supports non_unique ids (using real attributes)" do
before do
- @new_resource.stub(:manage_home).and_return(false)
- @new_resource.stub(:non_unique).and_return(true)
+ 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
- provider.universal_options.should eql([ "-o" ])
+ expect(provider.universal_options).to eql([ "-o" ])
end
end
end
@@ -169,7 +169,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
"-d", '/Users/mud',
"-m",
"adam" ])
- provider.should_receive(:shell_out!).with(*command).and_return(true)
+ expect(provider).to receive(:shell_out!).with(*command).and_return(true)
provider.create_user
end
@@ -190,7 +190,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
"-u", '1000',
"-r",
"adam" ])
- provider.should_receive(:shell_out!).with(*command).and_return(true)
+ expect(provider).to receive(:shell_out!).with(*command).and_return(true)
provider.create_user
end
@@ -213,7 +213,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
"-d", '/Users/mud',
"-m",
"adam" ]
- provider.should_receive(:shell_out!).with(*command).and_return(true)
+ expect(provider).to receive(:shell_out!).with(*command).and_return(true)
provider.manage_user
end
@@ -224,16 +224,16 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
"-d", '/Users/mud',
"-m",
"adam" ]
- provider.should_receive(:shell_out!).with(*command).and_return(true)
+ expect(provider).to receive(:shell_out!).with(*command).and_return(true)
provider.manage_user
end
it "CHEF-3429: does not set -m if we aren't changing the home directory" do
- provider.should_receive(:updating_home?).and_return(false)
+ expect(provider).to receive(:updating_home?).and_return(false)
command = ["usermod",
"-g", '23',
"adam" ]
- provider.should_receive(:shell_out!).with(*command).and_return(true)
+ expect(provider).to receive(:shell_out!).with(*command).and_return(true)
provider.manage_user
end
end
@@ -241,27 +241,27 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
describe "when removing a user" do
it "should run userdel with the new resources user name" do
- provider.should_receive(:shell_out!).with("userdel", @new_resource.username).and_return(true)
+ expect(provider).to receive(:shell_out!).with("userdel", @new_resource.username).and_return(true)
provider.remove_user
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})
- provider.should_receive(:shell_out!).with("userdel", "-r", @new_resource.username).and_return(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})
- provider.should_receive(:shell_out!).with("userdel", @new_resource.username).and_return(true)
+ expect(provider).to receive(:shell_out!).with("userdel", @new_resource.username).and_return(true)
provider.remove_user
end
it "should run userdel with the new resources user name and -f if force is true" do
@new_resource.force(true)
- provider.should_receive(:shell_out!).with("userdel", "-f", @new_resource.username).and_return(true)
+ expect(provider).to receive(:shell_out!).with("userdel", "-f", @new_resource.username).and_return(true)
provider.remove_user
end
end
@@ -284,96 +284,96 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
end
it "should return false if status begins with P" do
- provider.should_receive(:shell_out!).
+ expect(provider).to receive(:shell_out!).
with("passwd", "-S", @new_resource.username, {:returns=>[0, 1]}).
and_return(passwd_s_status)
- provider.check_lock.should eql(false)
+ expect(provider.check_lock).to eql(false)
end
it "should return false if status begins with N" do
@stdout = "root N"
- provider.should_receive(:shell_out!).
+ expect(provider).to receive(:shell_out!).
with("passwd", "-S", @new_resource.username, {:returns=>[0, 1]}).
and_return(passwd_s_status)
- provider.check_lock.should eql(false)
+ expect(provider.check_lock).to eql(false)
end
it "should return true if status begins with L" do
@stdout = "root L"
- provider.should_receive(:shell_out!).
+ expect(provider).to receive(:shell_out!).
with("passwd", "-S", @new_resource.username, {:returns=>[0, 1]}).
and_return(passwd_s_status)
- provider.check_lock.should eql(true)
+ expect(provider.check_lock).to eql(true)
end
it "should raise a Chef::Exceptions::User if passwd -S fails on anything other than redhat/centos" do
@node.automatic_attrs[:platform] = 'ubuntu'
- provider.should_receive(:shell_out!).
+ expect(provider).to receive(:shell_out!).
with("passwd", "-S", @new_resource.username, {:returns=>[0, 1]}).
and_return(passwd_s_status)
- passwd_s_status.should_receive(:exitstatus).and_return(1)
- lambda { provider.check_lock }.should raise_error(Chef::Exceptions::User)
+ expect(passwd_s_status).to receive(:exitstatus).and_return(1)
+ expect { provider.check_lock }.to raise_error(Chef::Exceptions::User)
end
['redhat', 'centos'].each do |os|
it "should not raise a Chef::Exceptions::User if passwd -S exits with 1 on #{os} and the passwd package is version 0.73-1" do
@node.automatic_attrs[:platform] = os
- passwd_s_status.should_receive(:exitstatus).and_return(1)
- provider.should_receive(:shell_out!).
+ expect(passwd_s_status).to receive(:exitstatus).and_return(1)
+ expect(provider).to receive(:shell_out!).
with("passwd", "-S", @new_resource.username, {:returns=>[0, 1]}).
and_return(passwd_s_status)
rpm_status = double("Mixlib::ShellOut command", :exitstatus => 0, :stdout => "passwd-0.73-1\n", :stderr => "")
- provider.should_receive(:shell_out!).with("rpm -q passwd").and_return(rpm_status)
- lambda { provider.check_lock }.should_not raise_error
+ expect(provider).to receive(:shell_out!).with("rpm -q passwd").and_return(rpm_status)
+ expect { provider.check_lock }.not_to raise_error
end
it "should raise a Chef::Exceptions::User if passwd -S exits with 1 on #{os} and the passwd package is not version 0.73-1" do
@node.automatic_attrs[:platform] = os
- passwd_s_status.should_receive(:exitstatus).and_return(1)
- provider.should_receive(:shell_out!).
+ expect(passwd_s_status).to receive(:exitstatus).and_return(1)
+ expect(provider).to receive(:shell_out!).
with("passwd", "-S", @new_resource.username, {:returns=>[0, 1]}).
and_return(passwd_s_status)
rpm_status = double("Mixlib::ShellOut command", :exitstatus => 0, :stdout => "passwd-0.73-2\n", :stderr => "")
- provider.should_receive(:shell_out!).with("rpm -q passwd").and_return(rpm_status)
- lambda { provider.check_lock }.should raise_error(Chef::Exceptions::User)
+ expect(provider).to receive(:shell_out!).with("rpm -q passwd").and_return(rpm_status)
+ expect { provider.check_lock }.to raise_error(Chef::Exceptions::User)
end
it "should raise a ShellCommandFailed exception if passwd -S exits with something other than 0 or 1 on #{os}" do
@node.automatic_attrs[:platform] = os
- provider.should_receive(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
- lambda { provider.check_lock }.should raise_error(Mixlib::ShellOut::ShellCommandFailed)
+ expect(provider).to receive(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ expect { provider.check_lock }.to raise_error(Mixlib::ShellOut::ShellCommandFailed)
end
end
context "when in why run mode" do
before do
passwd_status = double("Mixlib::ShellOut command", :exitstatus => 0, :stdout => "", :stderr => "passwd: user 'chef-test' does not exist\n")
- provider.should_receive(:shell_out!).
+ expect(provider).to receive(:shell_out!).
with("passwd", "-S", @new_resource.username, {:returns=>[0, 1]}).
and_return(passwd_status)
Chef::Config[:why_run] = true
end
it "should return false if the user does not exist" do
- provider.check_lock.should eql(false)
+ expect(provider.check_lock).to eql(false)
end
it "should not raise an error if the user does not exist" do
- lambda { provider.check_lock }.should_not raise_error
+ expect { provider.check_lock }.not_to raise_error
end
end
end
describe "when locking the user" do
it "should run usermod -L with the new resources username" do
- provider.should_receive(:shell_out!).with("usermod", "-L", @new_resource.username)
+ expect(provider).to receive(:shell_out!).with("usermod", "-L", @new_resource.username)
provider.lock_user
end
end
describe "when unlocking the user" do
it "should run usermod -L with the new resources username" do
- provider.should_receive(:shell_out!).with("usermod", "-U", @new_resource.username)
+ expect(provider).to receive(:shell_out!).with("usermod", "-U", @new_resource.username)
provider.unlock_user
end
end
@@ -411,12 +411,12 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
provider.new_resource.home home_check["new_resource_home"].first
@new_home_mock = double("Pathname")
- Pathname.should_receive(:new).with(@current_resource.home).and_return(@current_home_mock)
- @current_home_mock.should_receive(:cleanpath).and_return(home_check["current_resource_home"].last)
- Pathname.should_receive(:new).with(@new_resource.home).and_return(@new_home_mock)
- @new_home_mock.should_receive(:cleanpath).and_return(home_check["new_resource_home"].last)
+ expect(Pathname).to receive(:new).with(@current_resource.home).and_return(@current_home_mock)
+ expect(@current_home_mock).to receive(:cleanpath).and_return(home_check["current_resource_home"].last)
+ expect(Pathname).to receive(:new).with(@new_resource.home).and_return(@new_home_mock)
+ expect(@new_home_mock).to receive(:cleanpath).and_return(home_check["new_resource_home"].last)
- provider.updating_home?.should == home_check["expected_result"]
+ expect(provider.updating_home?).to eq(home_check["expected_result"])
end
end
it "should return true if the current home does not exist but a home is specified by the new resource" do
@@ -427,7 +427,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option
@current_resource.home nil
@new_resource.home "/home/kitten"
- provider.updating_home?.should == true
+ expect(provider.updating_home?).to eq(true)
end
end
end
diff --git a/spec/support/shared/unit/script_resource.rb b/spec/support/shared/unit/script_resource.rb
index a34f930fc8..18ee94606e 100644
--- a/spec/support/shared/unit/script_resource.rb
+++ b/spec/support/shared/unit/script_resource.rb
@@ -21,70 +21,78 @@ require 'spec_helper'
shared_examples_for "a script resource" do
- before(:each) do
- @resource = script_resource
- end
-
it "should create a new Chef::Resource::Script" do
- @resource.should be_a_kind_of(Chef::Resource)
- @resource.should be_a_kind_of(Chef::Resource::Script)
+ expect(script_resource).to be_a_kind_of(Chef::Resource)
+ expect(script_resource).to be_a_kind_of(Chef::Resource::Script)
end
it "should have a resource name of :script" do
- @resource.resource_name.should eql(resource_name)
+ expect(script_resource.resource_name).to eql(resource_name)
end
- it "should set command to the argument provided to new" do
- @resource.command.should eql(resource_instance_name)
+ it "should set command to nil on the resource", :chef_gte_13_only do
+ expect(script_resource.command).to be nil
+ end
+
+ it "should set command to the name on the resource", :chef_lt_13_only do
+ expect(script_resource.command).to eql script_resource.name
end
it "should accept a string for the code" do
- @resource.code "hey jude"
- @resource.code.should eql("hey jude")
+ script_resource.code "hey jude"
+ expect(script_resource.code).to eql("hey jude")
end
it "should accept a string for the flags" do
- @resource.flags "-f"
- @resource.flags.should eql("-f")
+ script_resource.flags "-f"
+ expect(script_resource.flags).to eql("-f")
end
- describe "when executing guards" do
- let(:resource) { @resource }
-
- before(:each) do
- node = Chef::Node.new
+ it "should raise an exception if users set command on the resource", :chef_gte_13_only do
+ expect { script_resource.command('foo') }.to raise_error(Chef::Exceptions::Script)
+ end
- node.automatic[:platform] = "debian"
- node.automatic[:platform_version] = "6.0"
+ it "should not raise an exception if users set command on the resource", :chef_lt_13_only do
+ expect { script_resource.command('foo') }.not_to raise_error
+ end
- events = Chef::EventDispatch::Dispatcher.new
- run_context = Chef::RunContext.new(node, {}, events)
+ describe "when executing guards" do
+ let(:resource) {
+ resource = script_resource
resource.run_context = run_context
resource.code 'echo hi'
- end
+ resource
+ }
+ let(:node) {
+ node = Chef::Node.new
+ node.automatic[:platform] = "debian"
+ node.automatic[:platform_version] = "6.0"
+ node
+ }
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
+ let(:run_context) { Chef::RunContext.new(node, {}, events) }
it "inherits exactly the :cwd, :environment, :group, :path, :user, and :umask attributes from a parent resource class" do
inherited_difference = Chef::Resource::Script.guard_inherited_attributes -
[:cwd, :environment, :group, :path, :user, :umask ]
- inherited_difference.should == []
+ expect(inherited_difference).to eq([])
end
it "when guard_interpreter is set to the default value, the guard command string should be evaluated by command execution and not through a resource" do
- Chef::Resource::Conditional.any_instance.should_not_receive(:evaluate_block)
- Chef::GuardInterpreter::ResourceGuardInterpreter.any_instance.should_not_receive(:evaluate_action)
- Chef::GuardInterpreter::DefaultGuardInterpreter.any_instance.should_receive(:evaluate).and_return(true)
+ expect_any_instance_of(Chef::Resource::Conditional).not_to receive(:evaluate_block)
+ expect_any_instance_of(Chef::GuardInterpreter::ResourceGuardInterpreter).not_to receive(:evaluate_action)
+ expect_any_instance_of(Chef::GuardInterpreter::DefaultGuardInterpreter).to receive(:evaluate).and_return(true)
resource.only_if 'echo hi'
- resource.should_skip?(:run).should == nil
+ expect(resource.should_skip?(:run)).to eq(nil)
end
it "when a valid guard_interpreter resource is specified, a block should be used to evaluate the guard" do
- Chef::GuardInterpreter::DefaultGuardInterpreter.any_instance.should_not_receive(:evaluate)
- Chef::GuardInterpreter::ResourceGuardInterpreter.any_instance.should_receive(:evaluate_action).and_return(true)
+ expect_any_instance_of(Chef::GuardInterpreter::DefaultGuardInterpreter).not_to receive(:evaluate)
+ expect_any_instance_of(Chef::GuardInterpreter::ResourceGuardInterpreter).to receive(:evaluate_action).and_return(true)
resource.guard_interpreter :script
resource.only_if 'echo hi'
- resource.should_skip?(:run).should == nil
+ expect(resource.should_skip?(:run)).to eq(nil)
end
end
end
-
diff --git a/spec/support/shared/unit/windows_script_resource.rb b/spec/support/shared/unit/windows_script_resource.rb
index 888ad600c5..a2fc884ff2 100644
--- a/spec/support/shared/unit/windows_script_resource.rb
+++ b/spec/support/shared/unit/windows_script_resource.rb
@@ -35,30 +35,30 @@ shared_examples_for "a Windows script resource" do
end
it "should be a kind of Chef::Resource::WindowsScript" do
- @resource.should be_a_kind_of(Chef::Resource)
- @resource.should be_a_kind_of(Chef::Resource::WindowsScript)
+ expect(@resource).to be_a_kind_of(Chef::Resource)
+ expect(@resource).to be_a_kind_of(Chef::Resource::WindowsScript)
end
context "when evaluating guards" do
it "should have a default_guard_interpreter attribute that is the same as the resource" do
- @resource.default_guard_interpreter.should == @resource.resource_name
+ expect(@resource.default_guard_interpreter).to eq(@resource.resource_name)
end
it "should default to using guard_interpreter attribute that is the same as the resource" do
- @resource.guard_interpreter.should == @resource.resource_name
+ expect(@resource.guard_interpreter).to eq(@resource.resource_name)
end
it "should use a resource to evaluate the guard when guard_interpreter is not specified" do
- Chef::GuardInterpreter::ResourceGuardInterpreter.any_instance.should_receive(:evaluate_action).and_return(true)
- Chef::GuardInterpreter::DefaultGuardInterpreter.any_instance.should_not_receive(:evaluate)
+ expect_any_instance_of(Chef::GuardInterpreter::ResourceGuardInterpreter).to receive(:evaluate_action).and_return(true)
+ expect_any_instance_of(Chef::GuardInterpreter::DefaultGuardInterpreter).not_to receive(:evaluate)
@resource.only_if 'echo hi'
- @resource.should_skip?(:run).should == nil
+ expect(@resource.should_skip?(:run)).to eq(nil)
end
describe "when the guard is given a ruby block" do
it "should evaluate the guard if the guard_interpreter is set to its default value" do
@resource.only_if { true }
- @resource.should_skip?(:run).should == nil
+ expect(@resource.should_skip?(:run)).to eq(nil)
end
it "should raise an exception if the guard_interpreter is overridden from its default value" do
diff --git a/spec/unit/api_client/registration_spec.rb b/spec/unit/api_client/registration_spec.rb
index 455e2d846b..d6230afb6a 100644
--- a/spec/unit/api_client/registration_spec.rb
+++ b/spec/unit/api_client/registration_spec.rb
@@ -85,7 +85,7 @@ describe Chef::ApiClient::Registration do
before do
Chef::Config[:validation_client_name] = "test-validator"
Chef::Config[:validation_key] = File.expand_path('ssl/private_key.pem', CHEF_SPEC_DATA)
- OpenSSL::PKey::RSA.stub(:generate).with(2048).and_return(generated_private_key)
+ allow(OpenSSL::PKey::RSA).to receive(:generate).with(2048).and_return(generated_private_key)
end
after do
@@ -93,51 +93,51 @@ describe Chef::ApiClient::Registration do
end
it "has an HTTP client configured with validator credentials" do
- registration.http_api.should be_a_kind_of(Chef::REST)
- registration.http_api.client_name.should == "test-validator"
- registration.http_api.signing_key.should == private_key_data
+ expect(registration.http_api).to be_a_kind_of(Chef::REST)
+ expect(registration.http_api.client_name).to eq("test-validator")
+ expect(registration.http_api.signing_key).to eq(private_key_data)
end
describe "when creating/updating the client on the server" do
before do
- registration.stub(:http_api).and_return(http_mock)
+ allow(registration).to receive(:http_api).and_return(http_mock)
end
it "posts a locally generated public key to the server to create a client" do
- http_mock.should_receive(:post).
+ expect(http_mock).to receive(:post).
with("clients", expected_post_data).
and_return(create_with_pkey_response)
- registration.create_or_update.should == create_with_pkey_response
- registration.private_key.should == generated_private_key_pem
+ expect(registration.create_or_update).to eq(create_with_pkey_response)
+ expect(registration.private_key).to eq(generated_private_key_pem)
end
it "puts a locally generated public key to the server to update a client" do
- http_mock.should_receive(:post).
+ expect(http_mock).to receive(:post).
with("clients", expected_post_data).
and_raise(exception_409)
- http_mock.should_receive(:put).
+ expect(http_mock).to receive(:put).
with("clients/#{client_name}", expected_put_data).
and_return(update_with_pkey_response)
- registration.create_or_update.should == update_with_pkey_response
- registration.private_key.should == generated_private_key_pem
+ expect(registration.create_or_update).to eq(update_with_pkey_response)
+ expect(registration.private_key).to eq(generated_private_key_pem)
end
it "writes the generated private key to disk" do
- http_mock.should_receive(:post).
+ expect(http_mock).to receive(:post).
with("clients", expected_post_data).
and_return(create_with_pkey_response)
registration.run
- IO.read(key_location).should == generated_private_key_pem
+ expect(IO.read(key_location)).to eq(generated_private_key_pem)
end
context "and the client already exists on a Chef 11 server" do
it "requests a new key from the server and saves it" do
- http_mock.should_receive(:post).and_raise(exception_409)
- http_mock.should_receive(:put).
+ expect(http_mock).to receive(:post).and_raise(exception_409)
+ expect(http_mock).to receive(:put).
with("clients/#{client_name}", expected_put_data).
and_return(update_with_pkey_response)
- registration.create_or_update.should == update_with_pkey_response
- registration.private_key.should == generated_private_key_pem
+ expect(registration.create_or_update).to eq(update_with_pkey_response)
+ expect(registration.private_key).to eq(generated_private_key_pem)
end
end
@@ -153,37 +153,37 @@ describe Chef::ApiClient::Registration do
before do
Chef::Config[:local_key_generation] = false
- OpenSSL::PKey::RSA.should_not_receive(:generate)
+ expect(OpenSSL::PKey::RSA).not_to receive(:generate)
end
it "creates a new ApiClient on the server using the validator identity" do
- http_mock.should_receive(:post).
+ expect(http_mock).to receive(:post).
with("clients", expected_post_data).
and_return(server_v10_response)
- registration.create_or_update.should == server_v10_response
- registration.private_key.should == "--begin rsa key etc--"
+ expect(registration.create_or_update).to eq(server_v10_response)
+ expect(registration.private_key).to eq("--begin rsa key etc--")
end
context "and the client already exists on a Chef 11 server" do
it "requests a new key from the server and saves it" do
- http_mock.should_receive(:post).and_raise(exception_409)
- http_mock.should_receive(:put).
+ expect(http_mock).to receive(:post).and_raise(exception_409)
+ expect(http_mock).to receive(:put).
with("clients/#{client_name}", expected_put_data).
and_return(server_v11_response)
- registration.create_or_update.should == server_v11_response
- registration.private_key.should == "--begin rsa key etc--"
+ expect(registration.create_or_update).to eq(server_v11_response)
+ expect(registration.private_key).to eq("--begin rsa key etc--")
end
end
context "and the client already exists on a Chef 10 server" do
it "requests a new key from the server and saves it" do
- http_mock.should_receive(:post).with("clients", expected_post_data).
+ expect(http_mock).to receive(:post).with("clients", expected_post_data).
and_raise(exception_409)
- http_mock.should_receive(:put).
+ expect(http_mock).to receive(:put).
with("clients/#{client_name}", expected_put_data).
and_return(server_v10_response)
- registration.create_or_update.should == server_v10_response
- registration.private_key.should == "--begin rsa key etc--"
+ expect(registration.create_or_update).to eq(server_v10_response)
+ expect(registration.private_key).to eq("--begin rsa key etc--")
end
end
end
@@ -191,23 +191,23 @@ describe Chef::ApiClient::Registration do
describe "when writing the private key to disk" do
before do
- registration.stub(:private_key).and_return('--begin rsa key etc--')
+ allow(registration).to receive(:private_key).and_return('--begin rsa key etc--')
end
# Permission read via File.stat is busted on windows, though creating the
# file with 0600 has the desired effect of giving access rights to the
# owner only. A platform-specific functional test would be helpful.
it "creates the file with 0600 permissions", :unix_only do
- File.should_not exist(key_location)
+ expect(File).not_to exist(key_location)
registration.write_key
- File.should exist(key_location)
+ expect(File).to exist(key_location)
stat = File.stat(key_location)
- (stat.mode & 07777).should == 0600
+ expect(stat.mode & 07777).to eq(0600)
end
it "writes the private key content to the file" do
registration.write_key
- IO.read(key_location).should == "--begin rsa key etc--"
+ expect(IO.read(key_location)).to eq("--begin rsa key etc--")
end
context 'when the client key location is a symlink' do
@@ -236,37 +236,37 @@ describe Chef::ApiClient::Registration do
describe "when registering a client" do
before do
- registration.stub(:http_api).and_return(http_mock)
+ allow(registration).to receive(:http_api).and_return(http_mock)
end
it "creates the client on the server and writes the key" do
- http_mock.should_receive(:post).ordered.and_return(server_v10_response)
+ expect(http_mock).to receive(:post).ordered.and_return(server_v10_response)
registration.run
- IO.read(key_location).should == generated_private_key_pem
+ expect(IO.read(key_location)).to eq(generated_private_key_pem)
end
it "retries up to 5 times" do
response_500 = Net::HTTPInternalServerError.new("1.1", "500", "Internal Server Error")
exception_500 = Net::HTTPFatalError.new("500 Internal Server Error", response_500)
- http_mock.should_receive(:post).ordered.and_raise(exception_500) # 1
- http_mock.should_receive(:post).ordered.and_raise(exception_500) # 2
- http_mock.should_receive(:post).ordered.and_raise(exception_500) # 3
- http_mock.should_receive(:post).ordered.and_raise(exception_500) # 4
- http_mock.should_receive(:post).ordered.and_raise(exception_500) # 5
+ expect(http_mock).to receive(:post).ordered.and_raise(exception_500) # 1
+ expect(http_mock).to receive(:post).ordered.and_raise(exception_500) # 2
+ expect(http_mock).to receive(:post).ordered.and_raise(exception_500) # 3
+ expect(http_mock).to receive(:post).ordered.and_raise(exception_500) # 4
+ expect(http_mock).to receive(:post).ordered.and_raise(exception_500) # 5
- http_mock.should_receive(:post).ordered.and_return(server_v10_response)
+ expect(http_mock).to receive(:post).ordered.and_return(server_v10_response)
registration.run
- IO.read(key_location).should == generated_private_key_pem
+ expect(IO.read(key_location)).to eq(generated_private_key_pem)
end
it "gives up retrying after the max attempts" do
response_500 = Net::HTTPInternalServerError.new("1.1", "500", "Internal Server Error")
exception_500 = Net::HTTPFatalError.new("500 Internal Server Error", response_500)
- http_mock.should_receive(:post).exactly(6).times.and_raise(exception_500)
+ expect(http_mock).to receive(:post).exactly(6).times.and_raise(exception_500)
- lambda {registration.run}.should raise_error(Net::HTTPFatalError)
+ expect {registration.run}.to raise_error(Net::HTTPFatalError)
end
end
diff --git a/spec/unit/api_client_spec.rb b/spec/unit/api_client_spec.rb
index bd6c5ef7fd..7668e31f5a 100644
--- a/spec/unit/api_client_spec.rb
+++ b/spec/unit/api_client_spec.rb
@@ -28,64 +28,64 @@ describe Chef::ApiClient do
it "has a name attribute" do
@client.name("ops_master")
- @client.name.should == "ops_master"
+ expect(@client.name).to eq("ops_master")
end
it "does not allow spaces in the name" do
- lambda { @client.name "ops master" }.should raise_error(ArgumentError)
+ expect { @client.name "ops master" }.to raise_error(ArgumentError)
end
it "only allows string values for the name" do
- lambda { @client.name Hash.new }.should raise_error(ArgumentError)
+ expect { @client.name Hash.new }.to raise_error(ArgumentError)
end
it "has an admin flag attribute" do
@client.admin(true)
- @client.admin.should be_true
+ expect(@client.admin).to be_truthy
end
it "defaults to non-admin" do
- @client.admin.should be_false
+ expect(@client.admin).to be_falsey
end
it "allows only boolean values for the admin flag" do
- lambda { @client.admin(false) }.should_not raise_error
- lambda { @client.admin(Hash.new) }.should raise_error(ArgumentError)
+ expect { @client.admin(false) }.not_to raise_error
+ expect { @client.admin(Hash.new) }.to raise_error(ArgumentError)
end
it "has a 'validator' flag attribute" do
@client.validator(true)
- @client.validator.should be_true
+ expect(@client.validator).to be_truthy
end
it "defaults to non-validator" do
- @client.validator.should be_false
+ expect(@client.validator).to be_falsey
end
it "allows only boolean values for the 'validator' flag" do
- lambda { @client.validator(false) }.should_not raise_error
- lambda { @client.validator(Hash.new) }.should raise_error(ArgumentError)
+ expect { @client.validator(false) }.not_to raise_error
+ expect { @client.validator(Hash.new) }.to raise_error(ArgumentError)
end
it "has a public key attribute" do
@client.public_key("super public")
- @client.public_key.should == "super public"
+ expect(@client.public_key).to eq("super public")
end
it "accepts only String values for the public key" do
- lambda { @client.public_key "" }.should_not raise_error
- lambda { @client.public_key Hash.new }.should raise_error(ArgumentError)
+ expect { @client.public_key "" }.not_to raise_error
+ expect { @client.public_key Hash.new }.to raise_error(ArgumentError)
end
it "has a private key attribute" do
@client.private_key("super private")
- @client.private_key.should == "super private"
+ expect(@client.private_key).to eq("super private")
end
it "accepts only String values for the private key" do
- lambda { @client.private_key "" }.should_not raise_error
- lambda { @client.private_key Hash.new }.should raise_error(ArgumentError)
+ expect { @client.private_key "" }.not_to raise_error
+ expect { @client.private_key Hash.new }.to raise_error(ArgumentError)
end
describe "when serializing to JSON" do
@@ -96,32 +96,32 @@ describe Chef::ApiClient do
end
it "serializes as a JSON object" do
- @json.should match(/^\{.+\}$/)
+ expect(@json).to match(/^\{.+\}$/)
end
it "includes the name value" do
- @json.should include(%q{"name":"black"})
+ expect(@json).to include(%q{"name":"black"})
end
it "includes the public key value" do
- @json.should include(%{"public_key":"crowes"})
+ expect(@json).to include(%{"public_key":"crowes"})
end
it "includes the 'admin' flag" do
- @json.should include(%q{"admin":false})
+ expect(@json).to include(%q{"admin":false})
end
it "includes the 'validator' flag" do
- @json.should include(%q{"validator":false})
+ expect(@json).to include(%q{"validator":false})
end
it "includes the private key when present" do
@client.private_key("monkeypants")
- @client.to_json.should include(%q{"private_key":"monkeypants"})
+ expect(@client.to_json).to include(%q{"private_key":"monkeypants"})
end
it "does not include the private key if not present" do
- @json.should_not include("private_key")
+ expect(@json).not_to include("private_key")
end
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
@@ -129,43 +129,83 @@ describe Chef::ApiClient do
end
end
- describe "when deserializing from JSON" do
- before(:each) do
- client = {
- "name" => "black",
- "public_key" => "crowes",
- "private_key" => "monkeypants",
- "admin" => true,
- "validator" => true,
- "json_class" => "Chef::ApiClient"
- }
- @client = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(client))
+ describe "when deserializing from JSON (string) using ApiClient#from_json" do
+ let(:client_string) do
+ "{\"name\":\"black\",\"public_key\":\"crowes\",\"private_key\":\"monkeypants\",\"admin\":true,\"validator\":true}"
+ end
+
+ let(:client) do
+ Chef::ApiClient.from_json(client_string)
+ end
+
+ it "does not require a 'json_class' string" do
+ expect(Chef::JSONCompat.parse(client_string)["json_class"]).to eq(nil)
end
it "should deserialize to a Chef::ApiClient object" do
- @client.should be_a_kind_of(Chef::ApiClient)
+ expect(client).to be_a_kind_of(Chef::ApiClient)
end
it "preserves the name" do
- @client.name.should == "black"
+ expect(client.name).to eq("black")
end
it "preserves the public key" do
- @client.public_key.should == "crowes"
+ expect(client.public_key).to eq("crowes")
end
it "preserves the admin status" do
- @client.admin.should be_true
+ expect(client.admin).to be_truthy
end
it "preserves the 'validator' status" do
- @client.validator.should be_true
+ expect(client.validator).to be_truthy
end
it "includes the private key if present" do
- @client.private_key.should == "monkeypants"
+ expect(client.private_key).to eq("monkeypants")
+ end
+ end
+
+ describe "when deserializing from JSON (hash) using JSONCompat#from_json" do
+ let(:client_hash) do
+ {
+ "name" => "black",
+ "public_key" => "crowes",
+ "private_key" => "monkeypants",
+ "admin" => true,
+ "validator" => true,
+ "json_class" => "Chef::ApiClient"
+ }
+ end
+
+ let(:client) do
+ Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(client_hash))
end
+ it "should deserialize to a Chef::ApiClient object" do
+ expect(client).to be_a_kind_of(Chef::ApiClient)
+ end
+
+ it "preserves the name" do
+ expect(client.name).to eq("black")
+ end
+
+ it "preserves the public key" do
+ expect(client.public_key).to eq("crowes")
+ end
+
+ it "preserves the admin status" do
+ expect(client.admin).to be_truthy
+ end
+
+ it "preserves the 'validator' status" do
+ expect(client.validator).to be_truthy
+ end
+
+ it "includes the private key if present" do
+ expect(client.private_key).to eq("monkeypants")
+ end
end
describe "when loading from JSON" do
@@ -183,33 +223,33 @@ describe Chef::ApiClient do
"json_class" => "Chef::ApiClient"
}
@http_client = double("Chef::REST mock")
- Chef::REST.stub(:new).and_return(@http_client)
- @http_client.should_receive(:get).with("clients/black").and_return(client)
+ allow(Chef::REST).to receive(:new).and_return(@http_client)
+ expect(@http_client).to receive(:get).with("clients/black").and_return(client)
@client = Chef::ApiClient.load(client['name'])
end
it "should deserialize to a Chef::ApiClient object" do
- @client.should be_a_kind_of(Chef::ApiClient)
+ expect(@client).to be_a_kind_of(Chef::ApiClient)
end
it "preserves the name" do
- @client.name.should == "black"
+ expect(@client.name).to eq("black")
end
it "preserves the public key" do
- @client.public_key.should == "crowes"
+ expect(@client.public_key).to eq("crowes")
end
it "preserves the admin status" do
- @client.admin.should be_a_kind_of(TrueClass)
+ expect(@client.admin).to be_a_kind_of(TrueClass)
end
it "preserves the 'validator' status" do
- @client.validator.should be_a_kind_of(TrueClass)
+ expect(@client.validator).to be_a_kind_of(TrueClass)
end
it "includes the private key if present" do
- @client.private_key.should == "monkeypants"
+ expect(@client.private_key).to eq("monkeypants")
end
end
@@ -230,9 +270,9 @@ describe Chef::ApiClient do
end
it "has an HTTP client configured with default credentials" do
- @client.http_api.should be_a_kind_of(Chef::REST)
- @client.http_api.client_name.should == "silent-bob"
- @client.http_api.signing_key.to_s.should == private_key_data
+ expect(@client.http_api).to be_a_kind_of(Chef::REST)
+ expect(@client.http_api.client_name).to eq("silent-bob")
+ expect(@client.http_api.signing_key.to_s).to eq(private_key_data)
end
end
@@ -240,7 +280,7 @@ describe Chef::ApiClient do
describe "when requesting a new key" do
before do
@http_client = double("Chef::REST mock")
- Chef::REST.stub(:new).and_return(@http_client)
+ allow(Chef::REST).to receive(:new).and_return(@http_client)
end
context "and the client does not exist on the server" do
@@ -248,11 +288,11 @@ describe Chef::ApiClient do
@a_404_response = Net::HTTPNotFound.new("404 not found and such", nil, nil)
@a_404_exception = Net::HTTPServerException.new("404 not found exception", @a_404_response)
- @http_client.should_receive(:get).with("clients/lost-my-key").and_raise(@a_404_exception)
+ expect(@http_client).to receive(:get).with("clients/lost-my-key").and_raise(@a_404_exception)
end
it "raises a 404 error" do
- lambda { Chef::ApiClient.reregister("lost-my-key") }.should raise_error(Net::HTTPServerException)
+ expect { Chef::ApiClient.reregister("lost-my-key") }.to raise_error(Net::HTTPServerException)
end
end
@@ -260,7 +300,7 @@ describe Chef::ApiClient do
before do
@api_client_without_key = Chef::ApiClient.new
@api_client_without_key.name("lost-my-key")
- @http_client.should_receive(:get).with("clients/lost-my-key").and_return(@api_client_without_key)
+ expect(@http_client).to receive(:get).with("clients/lost-my-key").and_return(@api_client_without_key)
end
@@ -269,7 +309,7 @@ describe Chef::ApiClient do
@api_client_with_key = Chef::ApiClient.new
@api_client_with_key.name("lost-my-key")
@api_client_with_key.private_key("the new private key")
- @http_client.should_receive(:put).
+ expect(@http_client).to receive(:put).
with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :validator => false, :private_key => true).
and_return(@api_client_with_key)
end
@@ -277,17 +317,17 @@ describe Chef::ApiClient do
it "returns an ApiClient with a private key" do
response = Chef::ApiClient.reregister("lost-my-key")
# no sane == method for ApiClient :'(
- response.should == @api_client_without_key
- response.private_key.should == "the new private key"
- response.name.should == "lost-my-key"
- response.admin.should be_false
+ expect(response).to eq(@api_client_without_key)
+ expect(response.private_key).to eq("the new private key")
+ expect(response.name).to eq("lost-my-key")
+ expect(response.admin).to be_falsey
end
end
context "and the client exists on a Chef 10-like server" do
before do
@api_client_with_key = {"name" => "lost-my-key", "private_key" => "the new private key"}
- @http_client.should_receive(:put).
+ expect(@http_client).to receive(:put).
with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :validator => false, :private_key => true).
and_return(@api_client_with_key)
end
@@ -295,16 +335,14 @@ describe Chef::ApiClient do
it "returns an ApiClient with a private key" do
response = Chef::ApiClient.reregister("lost-my-key")
# no sane == method for ApiClient :'(
- response.should == @api_client_without_key
- response.private_key.should == "the new private key"
- response.name.should == "lost-my-key"
- response.admin.should be_false
- response.validator.should be_false
+ expect(response).to eq(@api_client_without_key)
+ expect(response.private_key).to eq("the new private key")
+ expect(response.name).to eq("lost-my-key")
+ expect(response.admin).to be_falsey
+ expect(response.validator).to be_falsey
end
end
end
end
end
-
-
diff --git a/spec/unit/application/apply_spec.rb b/spec/unit/application/apply_spec.rb
index e29c038340..f6cd0bae03 100644
--- a/spec/unit/application/apply_spec.rb
+++ b/spec/unit/application/apply_spec.rb
@@ -21,7 +21,7 @@ describe Chef::Application::Apply do
before do
@app = Chef::Application::Apply.new
- @app.stub(:configure_logging).and_return(true)
+ allow(@app).to receive(:configure_logging).and_return(true)
@recipe_text = "package 'nyancat'"
Chef::Config[:solo] = true
end
@@ -29,7 +29,7 @@ describe Chef::Application::Apply do
describe "configuring the application" do
it "should set solo mode to true" do
@app.reconfigure
- Chef::Config[:solo].should be_true
+ expect(Chef::Config[:solo]).to be_truthy
end
end
describe "read_recipe_file" do
@@ -37,30 +37,30 @@ describe Chef::Application::Apply do
@recipe_file_name = "foo.rb"
@recipe_path = File.expand_path(@recipe_file_name)
@recipe_file = double("Tempfile (mock)", :read => @recipe_text)
- @app.stub(:open).with(@recipe_path).and_return(@recipe_file)
- File.stub(:exist?).with(@recipe_path).and_return(true)
- Chef::Application.stub(:fatal!).and_return(true)
+ allow(@app).to receive(:open).with(@recipe_path).and_return(@recipe_file)
+ allow(File).to receive(:exist?).with(@recipe_path).and_return(true)
+ allow(Chef::Application).to receive(:fatal!).and_return(true)
end
it "should read text properly" do
- @app.read_recipe_file(@recipe_file_name)[0].should == @recipe_text
+ expect(@app.read_recipe_file(@recipe_file_name)[0]).to eq(@recipe_text)
end
it "should return a file_handle" do
- @app.read_recipe_file(@recipe_file_name)[1].should be_instance_of(RSpec::Mocks::Mock)
+ expect(@app.read_recipe_file(@recipe_file_name)[1]).to be_instance_of(RSpec::Mocks::Double)
end
describe "when recipe is nil" do
it "should raise a fatal with the missing filename message" do
- Chef::Application.should_receive(:fatal!).with("No recipe file was provided", 1)
+ expect(Chef::Application).to receive(:fatal!).with("No recipe file was provided", 1)
@app.read_recipe_file(nil)
end
end
describe "when recipe doesn't exist" do
before do
- File.stub(:exist?).with(@recipe_path).and_return(false)
+ allow(File).to receive(:exist?).with(@recipe_path).and_return(false)
end
it "should raise a fatal with the file doesn't exist message" do
- Chef::Application.should_receive(:fatal!).with(/^No file exists at/, 1)
+ expect(Chef::Application).to receive(:fatal!).with(/^No file exists at/, 1)
@app.read_recipe_file(@recipe_file_name)
end
end
@@ -72,13 +72,13 @@ describe Chef::Application::Apply do
@recipe_fh = @app.instance_variable_get(:@recipe_fh)
end
it "should open a tempfile" do
- @recipe_fh.path.should match(/.*recipe-temporary-file.*/)
+ expect(@recipe_fh.path).to match(/.*recipe-temporary-file.*/)
end
it "should write recipe text to the tempfile" do
- @recipe_fh.read.should == @recipe_text
+ expect(@recipe_fh.read).to eq(@recipe_text)
end
it "should save the filename for later use" do
- @recipe_fh.path.should == @app.instance_variable_get(:@recipe_filename)
+ expect(@recipe_fh.path).to eq(@app.instance_variable_get(:@recipe_filename))
end
end
describe "recipe_file_arg" do
@@ -86,9 +86,25 @@ describe Chef::Application::Apply do
ARGV.clear
end
it "should exit and log message" do
- Chef::Log.should_receive(:debug).with(/^No recipe file provided/)
- lambda { @app.run }.should raise_error(SystemExit) { |e| e.status.should == 1 }
+ expect(Chef::Log).to receive(:debug).with(/^No recipe file provided/)
+ expect { @app.run }.to raise_error(SystemExit) { |e| expect(e.status).to eq(1) }
end
end
+ describe "when the json_attribs configuration option is specified" do
+ let(:json_attribs) { {"a" => "b"} }
+ let(:config_fetcher) { double(Chef::ConfigFetcher, :fetch_json => json_attribs) }
+ let(:json_source) { "https://foo.com/foo.json" }
+
+ before do
+ Chef::Config[:json_attribs] = json_source
+ expect(Chef::ConfigFetcher).to receive(:new).with(json_source).
+ and_return(config_fetcher)
+ end
+
+ it "reads the JSON attributes from the specified source" do
+ @app.reconfigure
+ expect(@app.json_attribs).to eq(json_attribs)
+ end
+ end
end
diff --git a/spec/unit/application/client_spec.rb b/spec/unit/application/client_spec.rb
index 2f6bd1b21e..ea2ad473e5 100644
--- a/spec/unit/application/client_spec.rb
+++ b/spec/unit/application/client_spec.rb
@@ -18,18 +18,21 @@
require 'spec_helper'
describe Chef::Application::Client, "reconfigure" do
+ let(:app) do
+ a = described_class.new
+ a.cli_arguments = []
+ a
+ end
+
before do
- Kernel.stub(:trap).and_return(:ok)
+ allow(Kernel).to receive(:trap).and_return(:ok)
+ allow(::File).to receive(:read).with(Chef::Config.platform_specific_path("/etc/chef/client.rb")).and_return("")
@original_argv = ARGV.dup
ARGV.clear
- @app = Chef::Application::Client.new
- @app.stub(:trap)
- @app.stub(:configure_opt_parser).and_return(true)
- @app.stub(:configure_chef).and_return(true)
- @app.stub(:configure_logging).and_return(true)
- @app.cli_arguments = []
+ allow(app).to receive(:trap)
+ allow(app).to receive(:configure_logging).and_return(true)
Chef::Config[:interval] = 10
Chef::Config[:once] = false
@@ -39,6 +42,13 @@ describe Chef::Application::Client, "reconfigure" do
ARGV.replace(@original_argv)
end
+ describe 'parse cli_arguments' do
+ it 'should call set_specific_recipes' do
+ expect(app).to receive(:set_specific_recipes).and_return(true)
+ app.reconfigure
+ end
+ end
+
describe "when configured to not fork the client process" do
before do
Chef::Config[:client_fork] = false
@@ -54,13 +64,13 @@ describe Chef::Application::Client, "reconfigure" do
end
it "should terminate with message" do
- Chef::Application.should_receive(:fatal!).with(
+ expect(Chef::Application).to receive(:fatal!).with(
"Unforked chef-client interval runs are disabled in Chef 12.
Configuration settings:
interval = 600 seconds
Enable chef-client interval runs by setting `:client_fork = true` in your config file or adding `--fork` to your command line options."
)
- @app.reconfigure
+ app.reconfigure
end
end
@@ -72,7 +82,7 @@ Enable chef-client interval runs by setting `:client_fork = true` in your config
it "should not terminate" do
expect(Chef::Application).not_to receive(:fatal!)
- @app.reconfigure
+ app.reconfigure
end
end
@@ -83,8 +93,8 @@ Enable chef-client interval runs by setting `:client_fork = true` in your config
end
it "should reconfigure chef-client" do
- @app.reconfigure
- Chef::Config[:interval].should be_nil
+ app.reconfigure
+ expect(Chef::Config[:interval]).to be_nil
end
end
end
@@ -96,8 +106,8 @@ Enable chef-client interval runs by setting `:client_fork = true` in your config
end
it "should set the interval to 1800" do
- @app.reconfigure
- Chef::Config.interval.should == 1800
+ app.reconfigure
+ expect(Chef::Config.interval).to eq(1800)
end
end
@@ -110,13 +120,13 @@ Enable chef-client interval runs by setting `:client_fork = true` in your config
end
it "ignores the splay" do
- @app.reconfigure
- Chef::Config.splay.should be_nil
+ app.reconfigure
+ expect(Chef::Config.splay).to be_nil
end
it "forces the interval to nil" do
- @app.reconfigure
- Chef::Config.interval.should be_nil
+ app.reconfigure
+ expect(Chef::Config.interval).to be_nil
end
end
@@ -128,29 +138,117 @@ Enable chef-client interval runs by setting `:client_fork = true` in your config
let(:json_source) { "https://foo.com/foo.json" }
before do
+ allow(app).to receive(:configure_chef).and_return(true)
Chef::Config[:json_attribs] = json_source
- Chef::ConfigFetcher.should_receive(:new).with(json_source).
+ expect(Chef::ConfigFetcher).to receive(:new).with(json_source).
and_return(config_fetcher)
end
it "reads the JSON attributes from the specified source" do
- @app.reconfigure
- @app.chef_client_json.should == json_attribs
+ app.reconfigure
+ expect(app.chef_client_json).to eq(json_attribs)
+ end
+ end
+
+ describe "audit mode" do
+ shared_examples "experimental feature" do
+ before do
+ allow(Chef::Log).to receive(:warn)
+ end
+
+ it "emits a warning that audit mode is an experimental feature" do
+ expect(Chef::Log).to receive(:warn).with(/Audit mode is an experimental feature/)
+ app.reconfigure
+ end
+ end
+
+ shared_examples "unrecognized setting" do
+ it "fatals with a message including the incorrect setting" do
+ expect(Chef::Application).to receive(:fatal!).with(/Unrecognized setting #{mode} for audit mode/)
+ app.reconfigure
+ end
+ end
+
+ shared_context "set via config file" do
+ before do
+ Chef::Config[:audit_mode] = mode
+ end
+ end
+
+ shared_context "set via command line" do
+ before do
+ ARGV.replace(["--audit-mode", mode])
+ end
+ end
+
+ describe "enabled via config file" do
+ include_context "set via config file" do
+ let(:mode) { :enabled }
+ include_examples "experimental feature"
+ end
+ end
+
+ describe "enabled via command line" do
+ include_context "set via command line" do
+ let(:mode) { "enabled" }
+ include_examples "experimental feature"
+ end
+ end
+
+ describe "audit_only via config file" do
+ include_context "set via config file" do
+ let(:mode) { :audit_only }
+ include_examples "experimental feature"
+ end
+ end
+
+ describe "audit-only via command line" do
+ include_context "set via command line" do
+ let(:mode) { "audit-only" }
+ include_examples "experimental feature"
+ end
+ end
+
+ describe "unrecognized setting via config file" do
+ include_context "set via config file" do
+ let(:mode) { :derp }
+ include_examples "unrecognized setting"
+ end
+ end
+
+ describe "unrecognized setting via command line" do
+ include_context "set via command line" do
+ let(:mode) { "derp" }
+ include_examples "unrecognized setting"
+ end
+ end
+ end
+
+ describe "when both the pidfile and lockfile opts are set to the same value" do
+
+ before do
+ Chef::Config[:pid_file] = "/path/to/file"
+ Chef::Config[:lockfile] = "/path/to/file"
+ end
+
+ it "should throw an exception" do
+ expect { @app.reconfigure }.to raise_error
end
end
end
+
describe Chef::Application::Client, "setup_application" do
before do
@app = Chef::Application::Client.new
# this is all stuff the reconfigure method needs
- @app.stub(:configure_opt_parser).and_return(true)
- @app.stub(:configure_chef).and_return(true)
- @app.stub(:configure_logging).and_return(true)
+ allow(@app).to receive(:configure_opt_parser).and_return(true)
+ allow(@app).to receive(:configure_chef).and_return(true)
+ allow(@app).to receive(:configure_logging).and_return(true)
end
it "should change privileges" do
- Chef::Daemon.should_receive(:change_privilege).and_return(true)
+ expect(Chef::Daemon).to receive(:change_privilege).and_return(true)
@app.setup_application
end
after do
@@ -159,11 +257,13 @@ describe Chef::Application::Client, "setup_application" do
end
describe Chef::Application::Client, "configure_chef" do
+ let(:app) { Chef::Application::Client.new }
+
before do
@original_argv = ARGV.dup
ARGV.clear
- @app = Chef::Application::Client.new
- @app.configure_chef
+ allow(::File).to receive(:read).with(Chef::Config.platform_specific_path("/etc/chef/client.rb")).and_return("")
+ app.configure_chef
end
after do
@@ -172,9 +272,9 @@ describe Chef::Application::Client, "configure_chef" do
it "should set the colored output to false by default on windows and true otherwise" do
if windows?
- Chef::Config[:color].should be_false
+ expect(Chef::Config[:color]).to be_falsey
else
- Chef::Config[:color].should be_true
+ expect(Chef::Config[:color]).to be_truthy
end
end
end
@@ -190,8 +290,8 @@ describe Chef::Application::Client, "run_application", :unix_only do
@pipe = IO.pipe
@client = Chef::Client.new
- Chef::Client.stub(:new).and_return(@client)
- @client.stub(:run) do
+ allow(Chef::Client).to receive(:new).and_return(@client)
+ allow(@client).to receive(:run) do
@pipe[1].puts 'started'
sleep 1
@pipe[1].puts 'finished'
@@ -202,7 +302,7 @@ describe Chef::Application::Client, "run_application", :unix_only do
context "when converging in forked process" do
before do
Chef::Config[:daemonize] = true
- Chef::Daemon.stub(:daemonize).and_return(true)
+ allow(Chef::Daemon).to receive(:daemonize).and_return(true)
end
it "should exit hard with exitstatus 3" do
@@ -211,19 +311,19 @@ describe Chef::Application::Client, "run_application", :unix_only do
end
Process.kill("TERM", pid)
_pid, result = Process.waitpid2(pid)
- result.exitstatus.should == 3
+ expect(result.exitstatus).to eq(3)
end
it "should allow child to finish converging" do
pid = fork do
@app.run_application
end
- @pipe[0].gets.should == "started\n"
+ expect(@pipe[0].gets).to eq("started\n")
Process.kill("TERM", pid)
Process.wait
sleep 1 # Make sure we give the converging child process enough time to finish
- IO.select([@pipe[0]], nil, nil, 0).should_not be_nil
- @pipe[0].gets.should == "finished\n"
+ expect(IO.select([@pipe[0]], nil, nil, 0)).not_to be_nil
+ expect(@pipe[0].gets).to eq("finished\n")
end
end
@@ -237,12 +337,12 @@ describe Chef::Application::Client, "run_application", :unix_only do
pid = fork do
@app.run_application
end
- @pipe[0].gets.should == "started\n"
+ expect(@pipe[0].gets).to eq("started\n")
Process.kill("TERM", pid)
_pid, result = Process.waitpid2(pid)
- result.exitstatus.should == 0
- IO.select([@pipe[0]], nil, nil, 0).should_not be_nil
- @pipe[0].gets.should == "finished\n"
+ expect(result.exitstatus).to eq(0)
+ expect(IO.select([@pipe[0]], nil, nil, 0)).not_to be_nil
+ expect(@pipe[0].gets).to eq("finished\n")
end
it "should exit hard when sent before converge" do
@@ -252,7 +352,7 @@ describe Chef::Application::Client, "run_application", :unix_only do
end
Process.kill("TERM", pid)
_pid, result = Process.waitpid2(pid)
- result.exitstatus.should == 3
+ expect(result.exitstatus).to eq(3)
end
end
end
@@ -268,7 +368,7 @@ describe Chef::Application::Client, "run_application", :unix_only do
# Chef::Log.init($stderr)
# Chef::Log.level = :debug
- @app.stub(:run_chef_client) do
+ allow(@app).to receive(:run_chef_client) do
run_count += 1
if run_count > 3
@@ -290,7 +390,7 @@ describe Chef::Application::Client, "run_application", :unix_only do
# We have to do it this way because the main loop of
# Chef::Application::Client swallows most exceptions, and we need to be
# able to expose our expectation failures to the parent process in the test.
- @app.stub(:interval_sleep) do |arg|
+ allow(@app).to receive(:interval_sleep) do |arg|
number_of_sleep_calls += 1
if number_of_sleep_calls > 1
exit 127
@@ -299,12 +399,12 @@ describe Chef::Application::Client, "run_application", :unix_only do
end
it "shouldn't sleep when sent USR1" do
- @app.stub(:interval_sleep).with(0).and_call_original
+ allow(@app).to receive(:interval_sleep).with(0).and_call_original
pid = fork do
@app.run_application
end
_pid, result = Process.waitpid2(pid)
- result.exitstatus.should == 0
+ expect(result.exitstatus).to eq(0)
end
end
end
diff --git a/spec/unit/application/knife_spec.rb b/spec/unit/application/knife_spec.rb
index 09a953ee0e..3c215eac7f 100644
--- a/spec/unit/application/knife_spec.rb
+++ b/spec/unit/application/knife_spec.rb
@@ -40,66 +40,66 @@ describe Chef::Application::Knife do
before(:each) do
# Prevent code from getting loaded on every test invocation.
- Chef::Knife.stub(:load_commands)
+ allow(Chef::Knife).to receive(:load_commands)
@knife = Chef::Application::Knife.new
- @knife.stub(:puts)
- @knife.stub(:trap)
- Chef::Knife.stub(:list_commands)
+ allow(@knife).to receive(:puts)
+ allow(@knife).to receive(:trap)
+ allow(Chef::Knife).to receive(:list_commands)
end
it "should exit 1 and print the options if no arguments are given at all" do
with_argv([]) do
- lambda { @knife.run }.should raise_error(SystemExit) { |e| e.status.should == 1 }
+ expect { @knife.run }.to raise_error(SystemExit) { |e| expect(e.status).to eq(1) }
end
end
it "should exit 2 if run without a sub command" do
with_argv("--user", "adam") do
- Chef::Log.should_receive(:error).with(/you need to pass a sub\-command/i)
- lambda { @knife.run }.should raise_error(SystemExit) { |e| e.status.should == 2 }
+ expect(Chef::Log).to receive(:error).with(/you need to pass a sub\-command/i)
+ expect { @knife.run }.to raise_error(SystemExit) { |e| expect(e.status).to eq(2) }
end
end
it "should run a sub command with the applications command line option prototype" do
with_argv(*%w{noop knife command with some args}) do
knife = double(Chef::Knife)
- Chef::Knife.should_receive(:run).with(ARGV, @knife.options).and_return(knife)
- @knife.should_receive(:exit).with(0)
+ expect(Chef::Knife).to receive(:run).with(ARGV, @knife.options).and_return(knife)
+ expect(@knife).to receive(:exit).with(0)
@knife.run
end
end
it "should set the colored output to false by default on windows and true otherwise" do
with_argv(*%w{noop knife command}) do
- @knife.should_receive(:exit).with(0)
+ expect(@knife).to receive(:exit).with(0)
@knife.run
end
if windows?
- Chef::Config[:color].should be_false
+ expect(Chef::Config[:color]).to be_falsey
else
- Chef::Config[:color].should be_true
+ expect(Chef::Config[:color]).to be_truthy
end
end
describe "when given a path to the client key" do
it "expands a relative path relative to the CWD" do
relative_path = '.chef/client.pem'
- Dir.stub(:pwd).and_return(CHEF_SPEC_DATA)
+ allow(Dir).to receive(:pwd).and_return(CHEF_SPEC_DATA)
with_argv(*%W{noop knife command -k #{relative_path}}) do
- @knife.should_receive(:exit).with(0)
+ expect(@knife).to receive(:exit).with(0)
@knife.run
end
- Chef::Config[:client_key].should == File.join(CHEF_SPEC_DATA, relative_path)
+ expect(Chef::Config[:client_key]).to eq(File.join(CHEF_SPEC_DATA, relative_path))
end
it "expands a ~/home/path to the correct full path" do
home_path = '~/.chef/client.pem'
with_argv(*%W{noop knife command -k #{home_path}}) do
- @knife.should_receive(:exit).with(0)
+ expect(@knife).to receive(:exit).with(0)
@knife.run
end
- Chef::Config[:client_key].should == File.join(ENV['HOME'], '.chef/client.pem').gsub((File::ALT_SEPARATOR || '\\'), File::SEPARATOR)
+ expect(Chef::Config[:client_key]).to eq(File.join(ENV['HOME'], '.chef/client.pem').gsub((File::ALT_SEPARATOR || '\\'), File::SEPARATOR))
end
it "does not expand a full path" do
@@ -109,10 +109,10 @@ describe Chef::Application::Knife do
'/etc/chef/client.pem'
end
with_argv(*%W{noop knife command -k #{full_path}}) do
- @knife.should_receive(:exit).with(0)
+ expect(@knife).to receive(:exit).with(0)
@knife.run
end
- Chef::Config[:client_key].should == full_path
+ expect(Chef::Config[:client_key]).to eq(full_path)
end
end
@@ -123,52 +123,52 @@ describe Chef::Application::Knife do
it "should default to no environment" do
with_argv(*%w{noop knife command}) do
- @knife.should_receive(:exit).with(0)
+ expect(@knife).to receive(:exit).with(0)
@knife.run
end
- Chef::Config[:environment].should == nil
+ expect(Chef::Config[:environment]).to eq(nil)
end
it "should load the environment from the config file" do
config_file = File.join(CHEF_SPEC_DATA,"environment-config.rb")
with_argv(*%W{noop knife command -c #{config_file}}) do
- @knife.should_receive(:exit).with(0)
+ expect(@knife).to receive(:exit).with(0)
@knife.run
end
- Chef::Config[:environment].should == 'production'
+ expect(Chef::Config[:environment]).to eq('production')
end
it "should load the environment from the CLI options" do
with_argv(*%W{noop knife command -E development}) do
- @knife.should_receive(:exit).with(0)
+ expect(@knife).to receive(:exit).with(0)
@knife.run
end
- Chef::Config[:environment].should == 'development'
+ expect(Chef::Config[:environment]).to eq('development')
end
it "should override the config file environment with the CLI environment" do
config_file = File.join(CHEF_SPEC_DATA,"environment-config.rb")
with_argv(*%W{noop knife command -c #{config_file} -E override}) do
- @knife.should_receive(:exit).with(0)
+ expect(@knife).to receive(:exit).with(0)
@knife.run
end
- Chef::Config[:environment].should == 'override'
+ expect(Chef::Config[:environment]).to eq('override')
end
it "should override the config file environment with the CLI environment regardless of order" do
config_file = File.join(CHEF_SPEC_DATA,"environment-config.rb")
with_argv(*%W{noop knife command -E override -c #{config_file}}) do
- @knife.should_receive(:exit).with(0)
+ expect(@knife).to receive(:exit).with(0)
@knife.run
end
- Chef::Config[:environment].should == 'override'
+ expect(Chef::Config[:environment]).to eq('override')
end
it "should run a sub command with the applications command line option prototype" do
with_argv(*%w{noop knife command with some args}) do
knife = double(Chef::Knife)
- Chef::Knife.should_receive(:run).with(ARGV, @knife.options).and_return(knife)
- @knife.should_receive(:exit).with(0)
+ expect(Chef::Knife).to receive(:run).with(ARGV, @knife.options).and_return(knife)
+ expect(@knife).to receive(:exit).with(0)
@knife.run
end
end
diff --git a/spec/unit/application/solo_spec.rb b/spec/unit/application/solo_spec.rb
index e29fcc9367..1785ecfc86 100644
--- a/spec/unit/application/solo_spec.rb
+++ b/spec/unit/application/solo_spec.rb
@@ -18,22 +18,35 @@
require 'spec_helper'
describe Chef::Application::Solo do
+
+ let(:app) { Chef::Application::Solo.new }
+
before do
- Kernel.stub(:trap).and_return(:ok)
- @app = Chef::Application::Solo.new
- @app.stub(:configure_opt_parser).and_return(true)
- @app.stub(:configure_chef).and_return(true)
- @app.stub(:configure_logging).and_return(true)
- @app.stub(:trap)
+ allow(Kernel).to receive(:trap).and_return(:ok)
+ allow(app).to receive(:configure_opt_parser).and_return(true)
+ allow(app).to receive(:configure_chef).and_return(true)
+ allow(app).to receive(:configure_logging).and_return(true)
+ allow(app).to receive(:trap)
+
Chef::Config[:recipe_url] = false
Chef::Config[:json_attribs] = false
Chef::Config[:solo] = true
end
describe "configuring the application" do
+ it 'should call set_specific_recipes' do
+ expect(app).to receive(:set_specific_recipes)
+ app.reconfigure
+ end
+
it "should set solo mode to true" do
- @app.reconfigure
- Chef::Config[:solo].should be_true
+ app.reconfigure
+ expect(Chef::Config[:solo]).to be_truthy
+ end
+
+ it "should set audit-mode to :disabled" do
+ app.reconfigure
+ expect(Chef::Config[:audit_mode]).to be :disabled
end
describe "when configured to not fork the client process" do
@@ -50,13 +63,13 @@ describe Chef::Application::Solo do
end
it "should terminate with message" do
- Chef::Application.should_receive(:fatal!).with(
+ expect(Chef::Application).to receive(:fatal!).with(
"Unforked chef-client interval runs are disabled in Chef 12.
Configuration settings:
interval = 600 seconds
Enable chef-client interval runs by setting `:client_fork = true` in your config file or adding `--fork` to your command line options."
)
- @app.reconfigure
+ app.reconfigure
end
end
end
@@ -68,8 +81,8 @@ Enable chef-client interval runs by setting `:client_fork = true` in your config
it "should set the interval to 1800" do
Chef::Config[:interval] = nil
- @app.reconfigure
- Chef::Config[:interval].should == 1800
+ app.reconfigure
+ expect(Chef::Config[:interval]).to eq(1800)
end
end
@@ -80,48 +93,51 @@ Enable chef-client interval runs by setting `:client_fork = true` in your config
before do
Chef::Config[:json_attribs] = json_source
- Chef::ConfigFetcher.should_receive(:new).with(json_source).
+ expect(Chef::ConfigFetcher).to receive(:new).with(json_source).
and_return(config_fetcher)
end
it "reads the JSON attributes from the specified source" do
- @app.reconfigure
- @app.chef_client_json.should == json_attribs
+ app.reconfigure
+ expect(app.chef_client_json).to eq(json_attribs)
end
end
describe "when the recipe_url configuration option is specified" do
+ let(:tarfile) { StringIO.new("remote_tarball_content") }
+ let(:target_file) { StringIO.new }
+
before do
Chef::Config[:cookbook_path] = "#{Dir.tmpdir}/chef-solo/cookbooks"
Chef::Config[:recipe_url] = "http://junglist.gen.nz/recipes.tgz"
- FileUtils.stub(:mkdir_p).and_return(true)
- @tarfile = StringIO.new("remote_tarball_content")
- @app.stub(:open).with("http://junglist.gen.nz/recipes.tgz").and_yield(@tarfile)
- @target_file = StringIO.new
- File.stub(:open).with("#{Dir.tmpdir}/chef-solo/recipes.tgz", "wb").and_yield(@target_file)
+ allow(FileUtils).to receive(:rm_rf).and_return(true)
+ allow(FileUtils).to receive(:mkdir_p).and_return(true)
+
+ allow(app).to receive(:open).with("http://junglist.gen.nz/recipes.tgz").and_yield(tarfile)
+ allow(File).to receive(:open).with("#{Dir.tmpdir}/chef-solo/recipes.tgz", "wb").and_yield(target_file)
- Chef::Mixin::Command.stub(:run_command).and_return(true)
+ allow(Chef::Mixin::Command).to receive(:run_command).and_return(true)
end
it "should create the recipes path based on the parent of the cookbook path" do
- FileUtils.should_receive(:mkdir_p).with("#{Dir.tmpdir}/chef-solo").and_return(true)
- @app.reconfigure
+ expect(FileUtils).to receive(:mkdir_p).with("#{Dir.tmpdir}/chef-solo").and_return(true)
+ app.reconfigure
end
it "should download the recipes" do
- @app.should_receive(:open).with("http://junglist.gen.nz/recipes.tgz").and_yield(@tarfile)
- @app.reconfigure
+ expect(app).to receive(:open).with("http://junglist.gen.nz/recipes.tgz").and_yield(tarfile)
+ app.reconfigure
end
it "should write the recipes to the target path" do
- @app.reconfigure
- @target_file.string.should == "remote_tarball_content"
+ app.reconfigure
+ expect(target_file.string).to eq("remote_tarball_content")
end
it "should untar the target file to the parent of the cookbook path" do
- Chef::Mixin::Command.should_receive(:run_command).with({:command => "tar zxvf #{Dir.tmpdir}/chef-solo/recipes.tgz -C #{Dir.tmpdir}/chef-solo"}).and_return(true)
- @app.reconfigure
+ expect(Chef::Mixin::Command).to receive(:run_command).with({:command => "tar zxvf #{Dir.tmpdir}/chef-solo/recipes.tgz -C #{Dir.tmpdir}/chef-solo"}).and_return(true)
+ app.reconfigure
end
end
end
@@ -135,14 +151,15 @@ Enable chef-client interval runs by setting `:client_fork = true` in your config
Chef::Config[:json_attribs] = json_source
Chef::Config[:recipe_url] = "http://icanhas.cheezburger.com/lolcats"
Chef::Config[:cookbook_path] = "#{Dir.tmpdir}/chef-solo/cookbooks"
- FileUtils.stub(:mkdir_p).and_return(true)
- Chef::Mixin::Command.stub(:run_command).and_return(true)
+ allow(FileUtils).to receive(:rm_rf).and_return(true)
+ allow(FileUtils).to receive(:mkdir_p).and_return(true)
+ allow(Chef::Mixin::Command).to receive(:run_command).and_return(true)
end
it "should fetch the recipe_url first" do
- @app.should_receive(:fetch_recipe_tarball).ordered
- Chef::ConfigFetcher.should_receive(:new).ordered.and_return(config_fetcher)
- @app.reconfigure
+ expect(app).to receive(:fetch_recipe_tarball).ordered
+ expect(Chef::ConfigFetcher).to receive(:new).ordered.and_return(config_fetcher)
+ app.reconfigure
end
end
@@ -150,19 +167,18 @@ Enable chef-client interval runs by setting `:client_fork = true` in your config
before do
Chef::Config[:solo] = true
- Chef::Daemon.stub(:change_privilege)
- @chef_client = double("Chef::Client")
- Chef::Client.stub(:new).and_return(@chef_client)
- @app = Chef::Application::Solo.new
+ allow(Chef::Daemon).to receive(:change_privilege)
+ chef_client = double("Chef::Client")
+ allow(Chef::Client).to receive(:new).and_return(chef_client)
# this is all stuff the reconfigure method needs
- @app.stub(:configure_opt_parser).and_return(true)
- @app.stub(:configure_chef).and_return(true)
- @app.stub(:configure_logging).and_return(true)
+ allow(app).to receive(:configure_opt_parser).and_return(true)
+ allow(app).to receive(:configure_chef).and_return(true)
+ allow(app).to receive(:configure_logging).and_return(true)
end
it "should change privileges" do
- Chef::Daemon.should_receive(:change_privilege).and_return(true)
- @app.setup_application
+ expect(Chef::Daemon).to receive(:change_privilege).and_return(true)
+ app.setup_application
end
end
diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb
index b7b69c6993..f5a2c72aa0 100644
--- a/spec/unit/application_spec.rb
+++ b/spec/unit/application_spec.rb
@@ -24,9 +24,9 @@ describe Chef::Application do
ARGV.clear
Chef::Log.logger = Logger.new(StringIO.new)
@app = Chef::Application.new
- @app.stub(:trap)
- Dir.stub(:chdir).and_return(0)
- @app.stub(:reconfigure)
+ allow(@app).to receive(:trap)
+ allow(Dir).to receive(:chdir).and_return(0)
+ allow(@app).to receive(:reconfigure)
Chef::Log.init(STDERR)
end
@@ -37,23 +37,28 @@ describe Chef::Application do
describe "reconfigure" do
before do
@app = Chef::Application.new
- @app.stub(:configure_chef).and_return(true)
- @app.stub(:configure_logging).and_return(true)
- @app.stub(:configure_proxy_environment_variables).and_return(true)
+ allow(@app).to receive(:configure_chef).and_return(true)
+ allow(@app).to receive(:configure_logging).and_return(true)
+ allow(@app).to receive(:configure_proxy_environment_variables).and_return(true)
end
it "should configure chef" do
- @app.should_receive(:configure_chef).and_return(true)
+ expect(@app).to receive(:configure_chef).and_return(true)
@app.reconfigure
end
it "should configure logging" do
- @app.should_receive(:configure_logging).and_return(true)
+ expect(@app).to receive(:configure_logging).and_return(true)
@app.reconfigure
end
it "should configure environment variables" do
- @app.should_receive(:configure_proxy_environment_variables).and_return(true)
+ expect(@app).to receive(:configure_proxy_environment_variables).and_return(true)
+ @app.reconfigure
+ end
+
+ it 'should not receive set_specific_recipes' do
+ expect(@app).to_not receive(:set_specific_recipes)
@app.reconfigure
end
end
@@ -65,24 +70,24 @@ describe Chef::Application do
describe "run" do
before do
- @app.stub(:setup_application).and_return(true)
- @app.stub(:run_application).and_return(true)
- @app.stub(:configure_chef).and_return(true)
- @app.stub(:configure_logging).and_return(true)
+ allow(@app).to receive(:setup_application).and_return(true)
+ allow(@app).to receive(:run_application).and_return(true)
+ allow(@app).to receive(:configure_chef).and_return(true)
+ allow(@app).to receive(:configure_logging).and_return(true)
end
it "should reconfigure the application before running" do
- @app.should_receive(:reconfigure).and_return(true)
+ expect(@app).to receive(:reconfigure).and_return(true)
@app.run
end
it "should setup the application before running it" do
- @app.should_receive(:setup_application).and_return(true)
+ expect(@app).to receive(:setup_application).and_return(true)
@app.run
end
it "should run the actual application" do
- @app.should_receive(:run_application).and_return(true)
+ expect(@app).to receive(:run_application).and_return(true)
@app.run
end
end
@@ -91,15 +96,15 @@ describe Chef::Application do
describe "configure_chef" do
before do
# Silence warnings when no config file exists
- Chef::Log.stub(:warn)
+ allow(Chef::Log).to receive(:warn)
@app = Chef::Application.new
#Chef::Config.stub(:merge!).and_return(true)
- @app.stub(:parse_options).and_return(true)
+ allow(@app).to receive(:parse_options).and_return(true)
end
it "should parse the commandline options" do
- @app.should_receive(:parse_options).and_return(true)
+ expect(@app).to receive(:parse_options).and_return(true)
@app.config[:config_file] = "/etc/chef/default.rb" #have a config file set, to prevent triggering error block
@app.configure_chef
end
@@ -110,7 +115,7 @@ describe Chef::Application do
let(:config_location_pathname) do
p = Pathname.new(config_location)
- p.stub(:realpath).and_return(config_location)
+ allow(p).to receive(:realpath).and_return(config_location)
p
end
@@ -119,21 +124,21 @@ describe Chef::Application do
# force let binding to get evaluated or else we stub Pathname.new before we try to use it.
config_location_pathname
- Pathname.stub(:new).with(config_location).and_return(config_location_pathname)
- File.should_receive(:read).
+ allow(Pathname).to receive(:new).with(config_location).and_return(config_location_pathname)
+ expect(File).to receive(:read).
with(config_location).
and_return(config_content)
end
it "should configure chef::config from a file" do
- Chef::Config.should_receive(:from_string).with(config_content, config_location)
+ expect(Chef::Config).to receive(:from_string).with(config_content, config_location)
@app.configure_chef
end
it "should merge the local config hash into chef::config" do
#File.should_receive(:open).with("/etc/chef/default.rb").and_yield(@config_file)
@app.configure_chef
- Chef::Config.rspec_ran.should == "true"
+ expect(Chef::Config.rspec_ran).to eq("true")
end
end
@@ -144,8 +149,8 @@ describe Chef::Application do
end
it "should emit a warning" do
- Chef::Config.should_not_receive(:from_file).with("/etc/chef/default.rb")
- Chef::Log.should_receive(:warn).with("No config file found or specified on command line, using command line options.")
+ expect(Chef::Config).not_to receive(:from_file).with("/etc/chef/default.rb")
+ expect(Chef::Log).to receive(:warn).with("No config file found or specified on command line, using command line options.")
@app.configure_chef
end
end
@@ -155,7 +160,7 @@ describe Chef::Application do
@app.config[:config_file] = "/etc/chef/notfound"
end
it "should use the passed in command line options and defaults" do
- Chef::Config.should_receive(:merge!)
+ expect(Chef::Config).to receive(:merge!)
@app.configure_chef
end
end
@@ -164,33 +169,33 @@ describe Chef::Application do
describe "when configuring the logger" do
before do
@app = Chef::Application.new
- Chef::Log.stub(:init)
+ allow(Chef::Log).to receive(:init)
end
it "should initialise the chef logger" do
- Chef::Log.stub(:level=)
+ allow(Chef::Log).to receive(:level=)
@monologger = double("Monologger")
- MonoLogger.should_receive(:new).with(Chef::Config[:log_location]).and_return(@monologger)
- Chef::Log.should_receive(:init).with(@monologger)
+ expect(MonoLogger).to receive(:new).with(Chef::Config[:log_location]).and_return(@monologger)
+ expect(Chef::Log).to receive(:init).with(@monologger)
@app.configure_logging
end
it "should raise fatals if log location is invalid" do
Chef::Config[:log_location] = "/tmp/non-existing-dir/logfile"
- Chef::Log.should_receive(:fatal).at_least(:once)
- Process.should_receive(:exit)
+ expect(Chef::Log).to receive(:fatal).at_least(:once)
+ expect(Process).to receive(:exit)
@app.configure_logging
end
shared_examples_for "log_level_is_auto" do
context "when STDOUT is to a tty" do
before do
- STDOUT.stub(:tty?).and_return(true)
+ allow(STDOUT).to receive(:tty?).and_return(true)
end
it "configures the log level to :warn" do
@app.configure_logging
- Chef::Log.level.should == :warn
+ expect(Chef::Log.level).to eq(:warn)
end
context "when force_logger is configured" do
@@ -200,19 +205,19 @@ describe Chef::Application do
it "configures the log level to info" do
@app.configure_logging
- Chef::Log.level.should == :info
+ expect(Chef::Log.level).to eq(:info)
end
end
end
context "when STDOUT is not to a tty" do
before do
- STDOUT.stub(:tty?).and_return(false)
+ allow(STDOUT).to receive(:tty?).and_return(false)
end
it "configures the log level to :info" do
@app.configure_logging
- Chef::Log.level.should == :info
+ expect(Chef::Log.level).to eq(:info)
end
context "when force_formatter is configured" do
@@ -221,7 +226,7 @@ describe Chef::Application do
end
it "sets the log level to :warn" do
@app.configure_logging
- Chef::Log.level.should == :warn
+ expect(Chef::Log.level).to eq(:warn)
end
end
end
@@ -242,10 +247,10 @@ describe Chef::Application do
describe "when configuring environment variables" do
def configure_proxy_environment_variables_stubs
- @app.stub(:configure_http_proxy).and_return(true)
- @app.stub(:configure_https_proxy).and_return(true)
- @app.stub(:configure_ftp_proxy).and_return(true)
- @app.stub(:configure_no_proxy).and_return(true)
+ allow(@app).to receive(:configure_http_proxy).and_return(true)
+ allow(@app).to receive(:configure_https_proxy).and_return(true)
+ allow(@app).to receive(:configure_ftp_proxy).and_return(true)
+ allow(@app).to receive(:configure_no_proxy).and_return(true)
end
shared_examples_for "setting ENV['http_proxy']" do
@@ -255,12 +260,12 @@ describe Chef::Application do
it "should set ENV['http_proxy']" do
@app.configure_proxy_environment_variables
- @env['http_proxy'].should == "#{scheme}://#{address}:#{port}"
+ expect(@env['http_proxy']).to eq("#{scheme}://#{address}:#{port}")
end
it "should set ENV['HTTP_PROXY']" do
@app.configure_proxy_environment_variables
- @env['HTTP_PROXY'].should == "#{scheme}://#{address}:#{port}"
+ expect(@env['HTTP_PROXY']).to eq("#{scheme}://#{address}:#{port}")
end
describe "when Chef::Config[:http_proxy_user] is set" do
@@ -270,8 +275,8 @@ describe Chef::Application do
it "should set ENV['http_proxy'] with the username" do
@app.configure_proxy_environment_variables
- @env['http_proxy'].should == "#{scheme}://username@#{address}:#{port}"
- @env['HTTP_PROXY'].should == "#{scheme}://username@#{address}:#{port}"
+ expect(@env['http_proxy']).to eq("#{scheme}://username@#{address}:#{port}")
+ expect(@env['HTTP_PROXY']).to eq("#{scheme}://username@#{address}:#{port}")
end
context "when :http_proxy_user contains '@' and/or ':'" do
@@ -281,8 +286,8 @@ describe Chef::Application do
it "should set ENV['http_proxy'] with the escaped username" do
@app.configure_proxy_environment_variables
- @env['http_proxy'].should == "#{scheme}://my%3Ausern%40me@#{address}:#{port}"
- @env['HTTP_PROXY'].should == "#{scheme}://my%3Ausern%40me@#{address}:#{port}"
+ expect(@env['http_proxy']).to eq("#{scheme}://my%3Ausern%40me@#{address}:#{port}")
+ expect(@env['HTTP_PROXY']).to eq("#{scheme}://my%3Ausern%40me@#{address}:#{port}")
end
end
@@ -293,8 +298,8 @@ describe Chef::Application do
it "should set ENV['http_proxy'] with the password" do
@app.configure_proxy_environment_variables
- @env['http_proxy'].should == "#{scheme}://username:password@#{address}:#{port}"
- @env['HTTP_PROXY'].should == "#{scheme}://username:password@#{address}:#{port}"
+ expect(@env['http_proxy']).to eq("#{scheme}://username:password@#{address}:#{port}")
+ expect(@env['HTTP_PROXY']).to eq("#{scheme}://username:password@#{address}:#{port}")
end
context "when :http_proxy_pass contains '@' and/or ':'" do
@@ -304,8 +309,8 @@ describe Chef::Application do
it "should set ENV['http_proxy'] with the escaped password" do
@app.configure_proxy_environment_variables
- @env['http_proxy'].should == "#{scheme}://username:%3AP%40ssword101@#{address}:#{port}"
- @env['HTTP_PROXY'].should == "#{scheme}://username:%3AP%40ssword101@#{address}:#{port}"
+ expect(@env['http_proxy']).to eq("#{scheme}://username:%3AP%40ssword101@#{address}:#{port}")
+ expect(@env['HTTP_PROXY']).to eq("#{scheme}://username:%3AP%40ssword101@#{address}:#{port}")
end
end
end
@@ -319,8 +324,8 @@ describe Chef::Application do
it "should set ENV['http_proxy']" do
@app.configure_proxy_environment_variables
- @env['http_proxy'].should == "#{scheme}://#{address}:#{port}"
- @env['HTTP_PROXY'].should == "#{scheme}://#{address}:#{port}"
+ expect(@env['http_proxy']).to eq("#{scheme}://#{address}:#{port}")
+ expect(@env['HTTP_PROXY']).to eq("#{scheme}://#{address}:#{port}")
end
end
end
@@ -328,11 +333,11 @@ describe Chef::Application do
describe "when configuring ENV['http_proxy']" do
before do
@env = {}
- @app.stub(:env).and_return(@env)
+ allow(@app).to receive(:env).and_return(@env)
- @app.stub(:configure_https_proxy).and_return(true)
- @app.stub(:configure_ftp_proxy).and_return(true)
- @app.stub(:configure_no_proxy).and_return(true)
+ allow(@app).to receive(:configure_https_proxy).and_return(true)
+ allow(@app).to receive(:configure_ftp_proxy).and_return(true)
+ allow(@app).to receive(:configure_no_proxy).and_return(true)
end
describe "when Chef::Config[:http_proxy] is not set" do
@@ -342,7 +347,7 @@ describe Chef::Application do
it "should not set ENV['http_proxy']" do
@app.configure_proxy_environment_variables
- @env.should == {}
+ expect(@env).to eq({})
end
end
@@ -401,7 +406,7 @@ describe Chef::Application do
it "should set ENV['http_proxy']" do
@app.configure_proxy_environment_variables
- @env['http_proxy'].should == Chef::Config[:http_proxy]
+ expect(@env['http_proxy']).to eq(Chef::Config[:http_proxy])
end
end
@@ -417,26 +422,26 @@ describe Chef::Application do
describe "class method: fatal!" do
before do
- STDERR.stub(:puts).with("FATAL: blah").and_return(true)
- Chef::Log.stub(:fatal).and_return(true)
- Process.stub(:exit).and_return(true)
+ allow(STDERR).to receive(:puts).with("FATAL: blah").and_return(true)
+ allow(Chef::Log).to receive(:fatal).and_return(true)
+ allow(Process).to receive(:exit).and_return(true)
end
it "should log an error message to the logger" do
- Chef::Log.should_receive(:fatal).with("blah").and_return(true)
+ expect(Chef::Log).to receive(:fatal).with("blah").and_return(true)
Chef::Application.fatal! "blah"
end
describe "when an exit code is supplied" do
it "should exit with the given exit code" do
- Process.should_receive(:exit).with(-100).and_return(true)
+ expect(Process).to receive(:exit).with(-100).and_return(true)
Chef::Application.fatal! "blah", -100
end
end
describe "when an exit code is not supplied" do
it "should exit with the default exit code" do
- Process.should_receive(:exit).with(-1).and_return(true)
+ expect(Process).to receive(:exit).with(-1).and_return(true)
Chef::Application.fatal! "blah"
end
end
@@ -449,7 +454,7 @@ describe Chef::Application do
end
it "should raise an error" do
- lambda { @app.setup_application }.should raise_error(Chef::Exceptions::Application)
+ expect { @app.setup_application }.to raise_error(Chef::Exceptions::Application)
end
end
@@ -459,7 +464,7 @@ describe Chef::Application do
end
it "should raise an error" do
- lambda { @app.run_application }.should raise_error(Chef::Exceptions::Application)
+ expect { @app.run_application }.to raise_error(Chef::Exceptions::Application)
end
end
@@ -467,22 +472,52 @@ describe Chef::Application do
it "should warn for bad config file path" do
@app.config[:config_file] = "/tmp/non-existing-dir/file"
config_file_regexp = Regexp.new @app.config[:config_file]
- Chef::Log.should_receive(:warn).at_least(:once).with(config_file_regexp).and_return(true)
- Chef::Log.stub(:warn).and_return(true)
+ expect(Chef::Log).to receive(:warn).at_least(:once).with(config_file_regexp).and_return(true)
+ allow(Chef::Log).to receive(:warn).and_return(true)
@app.configure_chef
end
end
+ describe 'run_chef_client' do
+ context 'with an application' do
+ let(:app) { Chef::Application.new }
+
+ context 'when called with an invalid argument' 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)
+ end
+
+ it 'should raise an argument error detailing the problem' do
+ specific_recipes_regexp = Regexp.new 'received non-Array like specific_recipes argument'
+ expect { app.run_chef_client(nil) }.to raise_error(ArgumentError, specific_recipes_regexp)
+ end
+ end
+
+ 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)
+ end
+
+ it 'should be cool' do
+ expect { app.run_chef_client([]) }.not_to raise_error
+ end
+ end
+ end
+
+ end
+
describe "configuration errors" do
before do
- Process.should_receive(:exit)
+ expect(Process).to receive(:exit)
end
def raises_informative_fatals_on_configure_chef
config_file_regexp = Regexp.new @app.config[:config_file]
- Chef::Log.should_receive(:fatal).
+ expect(Chef::Log).to receive(:fatal).
with(/Configuration error/)
- Chef::Log.should_receive(:fatal).
+ expect(Chef::Log).to receive(:fatal).
with(config_file_regexp).
at_least(1).times
@app.configure_chef
diff --git a/spec/unit/audit/audit_event_proxy_spec.rb b/spec/unit/audit/audit_event_proxy_spec.rb
new file mode 100644
index 0000000000..17a5d3d771
--- /dev/null
+++ b/spec/unit/audit/audit_event_proxy_spec.rb
@@ -0,0 +1,311 @@
+#
+# Author:: Tyler Ball (<tball@chef.io>)
+# Author:: Claire McQuin (<claire@getchef.com>)
+#
+# Copyright:: Copyright (c) 2014 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 'spec_helper'
+require 'chef/audit/audit_event_proxy'
+
+describe Chef::Audit::AuditEventProxy do
+
+ let(:stdout) { StringIO.new }
+ let(:events) { double("Chef::Events") }
+ let(:audit_event_proxy) { Chef::Audit::AuditEventProxy.new(stdout) }
+
+ before do
+ Chef::Audit::AuditEventProxy.events = events
+ end
+
+ describe "#example_group_started" do
+
+ let(:description) { "poots" }
+ let(:group) { double("ExampleGroup", :parent_groups => parents,
+ :description => description) }
+ let(:notification) { double("Notification", :group => group) }
+
+ context "when notified from a top-level example group" do
+
+ let(:parents) { [double("ExampleGroup")] }
+
+ it "notifies control_group_started event" do
+ expect(Chef::Log).to receive(:debug).
+ with("Entered \`control_group\` block named poots")
+ expect(events).to receive(:control_group_started).
+ with(description)
+ audit_event_proxy.example_group_started(notification)
+ end
+ end
+
+ context "when notified from an inner-level example group" do
+
+ let(:parents) { [double("ExampleGroup"), double("OuterExampleGroup")] }
+
+ it "does nothing" do
+ expect(events).to_not receive(:control_group_started)
+ audit_event_proxy.example_group_started(notification)
+ end
+ end
+ end
+
+ describe "#stop" do
+
+ let(:examples) { [] }
+ let(:notification) { double("Notification", :examples => examples) }
+ let(:exception) { nil }
+ let(:example) { double("Example", :exception => exception) }
+ let(:control_group_name) { "audit test" }
+ let(:control_data) { double("ControlData") }
+
+ before do
+ allow(Chef::Log).to receive(:info) # silence messages to output stream
+ end
+
+ it "sends a message that audits completed" do
+ expect(Chef::Log).to receive(:info).with("Successfully executed all \`control_group\` blocks and contained examples")
+ audit_event_proxy.stop(notification)
+ end
+
+ context "when an example succeeded" do
+
+ let(:examples) { [example] }
+ let(:excpetion) { nil }
+
+ before do
+ allow(audit_event_proxy).to receive(:build_control_from).
+ with(example).
+ and_return([control_group_name, control_data])
+ end
+
+ it "notifies events" do
+ expect(events).to receive(:control_example_success).
+ with(control_group_name, control_data)
+ audit_event_proxy.stop(notification)
+ end
+ end
+
+ context "when an example failed" do
+
+ let(:examples) { [example] }
+ let(:exception) { double("ExpectationNotMet") }
+
+ before do
+ allow(audit_event_proxy).to receive(:build_control_from).
+ with(example).
+ and_return([control_group_name, control_data])
+ end
+
+ it "notifies events" do
+ expect(events).to receive(:control_example_failure).
+ with(control_group_name, control_data, exception)
+ audit_event_proxy.stop(notification)
+ end
+ end
+
+ describe "#build_control_from" do
+
+ let(:examples) { [example] }
+
+ let(:example) { double("Example", :metadata => metadata,
+ :description => example_description,
+ :full_description => full_description, :exception => nil) }
+
+ let(:metadata) {
+ {
+ :described_class => described_class,
+ :example_group => example_group,
+ :line_number => line
+ }
+ }
+
+ let(:example_group) {
+ {
+ :description => group_description,
+ :parent_example_group => parent_group
+ }
+ }
+
+ let(:parent_group) {
+ {
+ :description => control_group_name,
+ :parent_example_group => nil
+ }
+ }
+
+ let(:line) { 27 }
+
+ let(:control_data) {
+ {
+ :name => example_description,
+ :desc => full_description,
+ :resource_type => resource_type,
+ :resource_name => resource_name,
+ :context => context,
+ :line_number => line
+ }
+ }
+
+ shared_examples "built control" do
+
+ before do
+ if described_class
+ allow(described_class).to receive(:instance_variable_get).
+ with(:@name).
+ and_return(resource_name)
+ allow(described_class.class).to receive(:name).
+ and_return(described_class.class)
+ end
+ end
+
+ it "returns the controls block name and example metadata for reporting" do
+ expect(events).to receive(:control_example_success).
+ with(control_group_name, control_data)
+ audit_event_proxy.stop(notification)
+ end
+ end
+
+ describe "a top-level example" do
+ # controls "port 111" do
+ # it "has nobody listening" do
+ # expect(port("111")).to_not be_listening
+ # end
+ # end
+
+ # Description parts
+ let(:group_description) { "port 111" }
+ let(:example_description) { "has nobody listening" }
+ let(:full_description) { group_description + " " + example_description }
+
+ # Metadata fields
+ let(:described_class) { nil }
+
+ # Example group (metadata[:example_group]) fields
+ let(:parent_group) { nil }
+
+ # Expected returns
+ let(:control_group_name) { group_description }
+
+ # Control data fields
+ let(:resource_type) { nil }
+ let(:resource_name) { nil }
+ let(:context) { [] }
+
+ include_examples "built control"
+ end
+
+ describe "an example with an implicit subject" do
+ # controls "application ports" do
+ # control port(111) do
+ # it { is_expected.to_not be_listening }
+ # end
+ # end
+
+ # Description parts
+ 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(" ") }
+
+ # Metadata fields
+ let(:described_class) { double("Serverspec::Type::Port",
+ :class => "Serverspec::Type::Port", :name => resource_name) }
+
+ # Control data fields
+ let(:resource_type) { "Port" }
+ let(:resource_name) { "111" }
+ let(:context) { [] }
+
+ include_examples "built control"
+ end
+
+ describe "an example in a nested context" do
+ # controls "application ports" do
+ # control "port 111" do
+ # it "is not listening" do
+ # expect(port(111)).to_not be_listening
+ # end
+ # end
+ # end
+
+ # Description parts
+ 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(" ") }
+
+ # Metadata fields
+ let(:described_class) { nil }
+
+ # Control data fields
+ let(:resource_type) { nil }
+ let(:resource_name) { nil }
+ let(:context) { [group_description] }
+
+ include_examples "built control"
+ end
+
+ describe "an example in a nested context including Serverspec" do
+ # controls "application directory" do
+ # control file("/tmp/audit") do
+ # describe file("/tmp/audit/test_file") do
+ # it "is a file" do
+ # expect(subject).to be_file
+ # end
+ # end
+ # end
+ # end
+
+ # Description parts
+ let(:control_group_name) { "application directory" }
+ 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(" ") }
+
+ # Metadata parts
+ let(:described_class) { double("Serverspec::Type::File",
+ :class => "Serverspec::Type::File", :name => resource_name) }
+
+ # Example group parts
+ let(:parent_group) {
+ {
+ :description => outer_group_description,
+ :parent_example_group => control_group
+ }
+ }
+
+ let(:control_group) {
+ {
+ :description => control_group_name,
+ :parent_example_group => nil
+ }
+ }
+
+ # Control data parts
+ let(:resource_type) { "File" }
+ let(:resource_name) { "/tmp/audit/test_file" }
+ let(:context) { [outer_group_description] }
+
+ include_examples "built control"
+ end
+ end
+ end
+
+end
diff --git a/spec/unit/audit/audit_reporter_spec.rb b/spec/unit/audit/audit_reporter_spec.rb
new file mode 100644
index 0000000000..84d7ea82f0
--- /dev/null
+++ b/spec/unit/audit/audit_reporter_spec.rb
@@ -0,0 +1,393 @@
+#
+# Author:: Tyler Ball (<tball@chef.io>)
+# Author:: Claire McQuin (<claire@getchef.com>)
+#
+# Copyright:: Copyright (c) 2014 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 'spec_helper'
+
+describe Chef::Audit::AuditReporter do
+
+ let(:rest) { double("rest") }
+ let(:reporter) { described_class.new(rest) }
+ let(:node) { double("node", :name => "sofreshsoclean") }
+ 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) }
+
+ describe "#audit_phase_start" do
+
+ it "notifies audit phase start to debug log" do
+ expect(Chef::Log).to receive(:debug).with(/Audit Reporter starting/)
+ reporter.audit_phase_start(run_status)
+ end
+
+ it "initializes an AuditData object" do
+ expect(Chef::Audit::AuditData).to receive(:new).with(run_status.node.name, run_status.run_id)
+ reporter.audit_phase_start(run_status)
+ end
+
+ it "saves the run status" do
+ reporter.audit_phase_start(run_status)
+ expect(reporter.instance_variable_get(:@run_status)).to eq run_status
+ end
+ end
+
+ describe "#run_completed" do
+
+ let(:audit_data) { Chef::Audit::AuditData.new(node.name, run_id) }
+ let(:run_data) { audit_data.to_hash }
+
+ before do
+ allow(reporter).to receive(:auditing_enabled?).and_return(true)
+ allow(reporter).to receive(:run_status).and_return(run_status)
+ allow(rest).to receive(:create_url).and_return(true)
+ allow(rest).to receive(:post).and_return(true)
+ allow(reporter).to receive(:audit_data).and_return(audit_data)
+ allow(reporter).to receive(:run_status).and_return(run_status)
+ allow(audit_data).to receive(:to_hash).and_return(run_data)
+ end
+
+ describe "a successful run with auditing enabled" do
+ it "sets run start and end times" do
+ iso_start_time = "2014-12-03T17:31:05Z"
+ iso_end_time = "2014-12-03T17:36:14Z"
+
+ reporter.run_completed(node)
+ expect(audit_data.start_time).to eq iso_start_time
+ expect(audit_data.end_time).to eq iso_end_time
+ end
+
+ it "posts audit data to server endpoint" do
+ endpoint = "api.opscode.us/orgname/controls"
+ headers = {
+ 'X-Ops-Audit-Report-Protocol-Version' => Chef::Audit::AuditReporter::PROTOCOL_VERSION
+ }
+
+ expect(rest).to receive(:create_url).
+ with("controls").
+ and_return(endpoint)
+ expect(rest).to receive(:post).
+ with(endpoint, run_data, headers)
+ reporter.run_completed(node)
+ end
+
+ context "when unable to post to server" do
+
+ let(:error) do
+ e = StandardError.new
+ e.set_backtrace(caller)
+ e
+ end
+
+ before do
+ expect(rest).to receive(:post).and_raise(error)
+ allow(error).to receive(:respond_to?).and_call_original
+ end
+
+ context "the error is an http error" do
+
+ let(:response) { double("response", :code => code) }
+
+ before do
+ expect(Chef::Log).to receive(:debug).with(/Sending audit report/)
+ expect(Chef::Log).to receive(:debug).with(/Audit Report/)
+ allow(error).to receive(:response).and_return(response)
+ expect(error).to receive(:respond_to?).with(:response).and_return(true)
+ end
+
+ context "when the code is 404" do
+
+ let(:code) { "404" }
+
+ it "logs that the server doesn't support audit reporting" do
+ expect(Chef::Log).to receive(:debug).with(/Server doesn't support audit reporting/)
+ reporter.run_completed(node)
+ end
+ end
+
+ shared_examples "non-404 error code" do
+
+ it "saves the error report" do
+ expect(Chef::FileCache).to receive(:store).
+ with("failed-audit-data.json", an_instance_of(String), 0640).
+ and_return(true)
+ expect(Chef::FileCache).to receive(:load).
+ with("failed-audit-data.json", false).
+ and_return(true)
+ expect(Chef::Log).to receive(:error).with(/Failed to post audit report to server/)
+ reporter.run_completed(node)
+ end
+
+ end
+
+ context "when the code is not 404" do
+ include_examples "non-404 error code" do
+ let(:code) { "505" }
+ end
+ end
+
+ context "when there is no code" do
+ include_examples "non-404 error code" do
+ let(:code) { nil }
+ end
+ end
+
+ end
+
+ context "the error is not an http error" do
+
+ it "logs the error" do
+ expect(error).to receive(:respond_to?).with(:response).and_return(false)
+ expect(Chef::Log).to receive(:error).with(/Failed to post audit report to server/)
+ reporter.run_completed(node)
+ end
+
+ end
+
+ context "when reporting url fatals are enabled" do
+
+ before do
+ allow(Chef::Config).to receive(:[]).
+ with(:enable_reporting_url_fatals).
+ and_return(true)
+ end
+
+ it "raises the error" do
+ expect(error).to receive(:respond_to?).with(:response).and_return(false)
+ allow(Chef::Log).to receive(:error).and_return(true)
+ expect(Chef::Log).to receive(:error).with(/Reporting fatals enabled. Aborting run./)
+ expect{ reporter.run_completed(node) }.to raise_error(error)
+ end
+
+ end
+ end
+ end
+
+ context "when auditing is not enabled" do
+
+ before do
+ allow(Chef::Log).to receive(:debug)
+ end
+
+ it "doesn't send reports" do
+ expect(reporter).to receive(:auditing_enabled?).and_return(false)
+ expect(Chef::Log).to receive(:debug).with("Audit Reports are disabled. Skipping sending reports.")
+ reporter.run_completed(node)
+ end
+
+ end
+
+ context "when the run fails before audits" do
+
+ before do
+ allow(Chef::Log).to receive(:debug)
+ end
+
+ it "doesn't send reports" do
+ expect(reporter).to receive(:auditing_enabled?).and_return(true)
+ expect(reporter).to receive(:run_status).and_return(nil)
+ expect(Chef::Log).to receive(:debug).with("Run failed before audits were initialized, not sending audit report to server")
+ reporter.run_completed(node)
+ end
+
+ end
+ end
+
+ describe "#run_failed" do
+
+ let(:audit_data) { Chef::Audit::AuditData.new(node.name, run_id) }
+ let(:run_data) { audit_data.to_hash }
+
+ let(:error) { double("AuditError", :class => "Chef::Exception::AuditError",
+ :message => "Well that certainly didn't work",
+ :backtrace => ["line 0", "line 1", "line 2"]) }
+
+ before do
+ allow(reporter).to receive(:auditing_enabled?).and_return(true)
+ allow(reporter).to receive(:run_status).and_return(run_status)
+ allow(reporter).to receive(:audit_data).and_return(audit_data)
+ allow(audit_data).to receive(:to_hash).and_return(run_data)
+ end
+
+ it "adds the error information to the reported data" do
+ expect(rest).to receive(:create_url)
+ expect(rest).to receive(:post)
+ reporter.run_failed(error)
+ expect(run_data).to have_key(:error)
+ expect(run_data[:error]).to eq "Chef::Exception::AuditError: Well that certainly didn't work\n" +
+ "line 0\nline 1\nline 2"
+ end
+
+ end
+
+ 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(:ordered_control_groups) {
+ {
+ "foo" => control_group_foo,
+ "bar" => control_group_bar
+ }
+ }
+
+ let(:audit_data) { instance_double(Chef::Audit::AuditData,
+ :add_control_group => true) }
+
+ let(:run_context) { instance_double(Chef::RunContext,
+ :audits => ordered_control_groups) }
+
+ before do
+ allow(reporter).to receive(:ordered_control_groups).and_return(ordered_control_groups)
+ allow(reporter).to receive(:audit_data).and_return(audit_data)
+ allow(reporter).to receive(:run_status).and_return(run_status)
+ allow(run_status).to receive(:run_context).and_return(run_context)
+ end
+ end
+
+ describe "#audit_phase_complete" do
+ include_context "audit data"
+
+ it "notifies audit phase finished to debug log" do
+ expect(Chef::Log).to receive(:debug).with(/Audit Reporter completed/)
+ reporter.audit_phase_complete
+ end
+
+ it "collects audit data" do
+ ordered_control_groups.each do |_name, group|
+ expect(audit_data).to receive(:add_control_group).with(group)
+ end
+ reporter.audit_phase_complete
+ end
+ end
+
+ describe "#audit_phase_failed" do
+ include_context "audit data"
+
+ let(:error) { double("Exception") }
+
+ it "notifies audit phase failed to debug log" do
+ expect(Chef::Log).to receive(:debug).with(/Audit Reporter failed/)
+ reporter.audit_phase_failed(error)
+ end
+
+ it "collects audit data" do
+ ordered_control_groups.each do |_name, group|
+ expect(audit_data).to receive(:add_control_group).with(group)
+ end
+ reporter.audit_phase_failed(error)
+ end
+ end
+
+ describe "#control_group_started" do
+ include_context "audit data"
+
+ let(:name) { "bat" }
+ let(:control_group) { instance_double(Chef::Audit::ControlGroupData,
+ :metadata => double("metadata")) }
+
+ before do
+ allow(Chef::Audit::ControlGroupData).to receive(:new).
+ with(name, control_group.metadata).
+ and_return(control_group)
+ end
+
+ it "stores the control group" do
+ expect(ordered_control_groups).to receive(:has_key?).with(name).and_return(false)
+ allow(run_context.audits).to receive(:[]).with(name).and_return(control_group)
+ expect(ordered_control_groups).to receive(:store).
+ with(name, control_group).
+ and_call_original
+ reporter.control_group_started(name)
+ # stubbed :has_key? above, which is used by the have_key matcher,
+ # so instead we check the response to Hash's #key? because luckily
+ # #key? does not call #has_key?
+ expect(ordered_control_groups.key?(name)).to be true
+ expect(ordered_control_groups[name]).to eq control_group
+ end
+
+ context "when a control group with the same name has been seen" do
+ it "raises an exception" do
+ expect(ordered_control_groups).to receive(:has_key?).with(name).and_return(true)
+ expect{ reporter.control_group_started(name) }.to raise_error(Chef::Exceptions::AuditControlGroupDuplicate)
+ end
+ end
+ end
+
+ describe "#control_example_success" do
+ include_context "audit data"
+
+ let(:name) { "foo" }
+ let(:example_data) { double("example data") }
+
+ it "notifies the control group the example succeeded" do
+ expect(control_group_foo).to receive(:example_success).with(example_data)
+ reporter.control_example_success(name, example_data)
+ end
+ end
+
+ describe "#control_example_failure" do
+ include_context "audit data"
+
+ let(:name) { "bar" }
+ let(:example_data) { double("example data") }
+ let(:error) { double("Exception", :message => "oopsie") }
+
+ it "notifies the control group the example failed" do
+ expect(control_group_bar).to receive(:example_failure).
+ with(example_data, error.message)
+ reporter.control_example_failure(name, example_data, error)
+ end
+ end
+
+ describe "#auditing_enabled?" do
+ shared_examples "enabled?" do |true_or_false|
+
+ it "returns #{true_or_false}" do
+ expect(Chef::Config).to receive(:[]).
+ with(:audit_mode).
+ and_return(audit_setting)
+ expect(reporter.auditing_enabled?).to be true_or_false
+ end
+ end
+
+ context "when auditing is disabled" do
+ include_examples "enabled?", false do
+ let(:audit_setting) { :disabled }
+ end
+ end
+
+ context "when auditing in audit-only mode" do
+ include_examples "enabled?", true do
+ let(:audit_setting) { :audit_only }
+ end
+ end
+
+ context "when auditing is enabled" do
+ include_examples "enabled?", true do
+ let(:audit_setting) { :enabled }
+ end
+ end
+ end
+
+end
diff --git a/spec/unit/audit/control_group_data_spec.rb b/spec/unit/audit/control_group_data_spec.rb
new file mode 100644
index 0000000000..e21ab066fd
--- /dev/null
+++ b/spec/unit/audit/control_group_data_spec.rb
@@ -0,0 +1,478 @@
+#
+# Author:: Tyler Ball (<tball@chef.io>)
+# Author:: Claire McQuin (<claire@getchef.com>)
+#
+# Copyright:: Copyright (c) 2014 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 'spec_helper'
+require 'securerandom'
+
+describe Chef::Audit::AuditData do
+
+ let(:node_name) { "noodles" }
+ let(:run_id) { SecureRandom.uuid }
+ let(:audit_data) { described_class.new(node_name, run_id) }
+
+ let(:control_group_1) { double("control group 1") }
+ let(:control_group_2) { double("control group 2") }
+
+ describe "#add_control_group" do
+ context "when no control groups have been added" do
+ it "stores the control group" do
+ audit_data.add_control_group(control_group_1)
+ expect(audit_data.control_groups).to include(control_group_1)
+ end
+
+ end
+
+ context "when adding additional control groups" do
+
+ before do
+ audit_data.add_control_group(control_group_1)
+ end
+
+ it "stores the control group" do
+ audit_data.add_control_group(control_group_2)
+ expect(audit_data.control_groups).to include(control_group_2)
+ end
+
+ it "stores all control groups" do
+ audit_data.add_control_group(control_group_2)
+ expect(audit_data.control_groups).to include(control_group_1)
+ end
+ end
+ end
+
+ describe "#to_hash" do
+
+ let(:audit_data_hash) { audit_data.to_hash }
+
+ it "returns a hash" do
+ expect(audit_data_hash).to be_a(Hash)
+ end
+
+ it "describes a Chef::Audit::AuditData object" do
+ keys = [:node_name, :run_id, :start_time, :end_time, :control_groups]
+ expect(audit_data_hash.keys).to match_array(keys)
+ end
+
+ describe ":control_groups" do
+
+ let(:control_hash_1) { {:name => "control group 1"} }
+ let(:control_hash_2) { {:name => "control group 2"} }
+
+ let(:control_groups) { audit_data_hash[:control_groups] }
+
+ context "with no control groups added" do
+ it "is an empty list" do
+ expect(control_groups).to eq []
+ end
+ end
+
+ context "with one control group added" do
+
+ before do
+ allow(audit_data).to receive(:control_groups).and_return([control_group_1])
+ end
+
+ it "is a one-element list containing the control group hash" do
+ expect(control_group_1).to receive(:to_hash).once.and_return(control_hash_1)
+ expect(control_groups.size).to eq 1
+ expect(control_groups).to include(control_hash_1)
+ end
+ end
+
+ context "with multiple control groups added" do
+
+ before do
+ allow(audit_data).to receive(:control_groups).and_return([control_group_1, control_group_2])
+ end
+
+ it "is a list of control group hashes" do
+ expect(control_group_1).to receive(:to_hash).and_return(control_hash_1)
+ expect(control_group_2).to receive(:to_hash).and_return(control_hash_2)
+ expect(control_groups.size).to eq 2
+ expect(control_groups).to include(control_hash_1)
+ expect(control_groups).to include(control_hash_2)
+ end
+ end
+ end
+ end
+end
+
+describe Chef::Audit::ControlData do
+
+ let(:name) { "ramen" }
+ let(:resource_type) { double("Service") }
+ let(:resource_name) { "mysql" }
+ 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) }
+
+
+ describe "#to_hash" do
+
+ let(:control_data_hash) { control_data.to_hash }
+
+ it "returns a hash" do
+ expect(control_data_hash).to be_a(Hash)
+ end
+
+ it "describes a Chef::Audit::ControlData object" do
+ keys = [:name, :resource_type, :resource_name, :context, :status, :details]
+ expect(control_data_hash.keys).to match_array(keys)
+ end
+
+ context "when context is nil" do
+
+ it "sets :context to an empty array" do
+ expect(control_data_hash[:context]).to eq []
+ end
+
+ end
+
+ context "when context is non-nil" do
+
+ let(:context) { ["outer"] }
+
+ it "sets :context to its value" do
+ expect(control_data_hash[:context]).to eq context
+ end
+ end
+ end
+end
+
+describe Chef::Audit::ControlGroupData do
+
+ let(:name) { "balloon" }
+ let(:control_group_data) { described_class.new(name) }
+
+ shared_context "control data" do
+
+ let(:name) { "" }
+ let(:resource_type) { nil }
+ let(:resource_name) { nil }
+ let(:context) { nil }
+ let(:line_number) { 0 }
+
+ let(:control_data) {
+ {
+ :name => name,
+ :resource_type => resource_type,
+ :resource_name => resource_name,
+ :context => context,
+ :line_number => line_number
+ }
+ }
+
+ 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) }
+
+ before do
+ allow(Chef::Audit::ControlData).to receive(:new).
+ with(name: name, resource_type: resource_type,
+ resource_name: resource_name, context: context,
+ line_number: line_number).
+ and_return(control)
+ end
+ end
+
+ describe "#new" do
+ it "has status \"success\"" do
+ expect(control_group_data.status).to eq "success"
+ end
+ end
+
+ describe "#example_success" do
+ include_context "control"
+
+ def notify_success
+ control_group_data.example_success(control_data)
+ end
+
+ it "increments the number of successful audits" do
+ num_success = control_group_data.number_succeeded
+ notify_success
+ expect(control_group_data.number_succeeded).to eq (num_success + 1)
+ end
+
+ it "does not increment the number of failed audits" do
+ num_failed = control_group_data.number_failed
+ notify_success
+ expect(control_group_data.number_failed).to eq (num_failed)
+ end
+
+ it "marks the audit's status as success" do
+ notify_success
+ expect(control.status).to eq "success"
+ end
+
+ it "does not modify its own status" do
+ expect(control_group_data).to_not receive(:status=)
+ status = control_group_data.status
+ notify_success
+ expect(control_group_data.status).to eq status
+ end
+
+ it "saves the control" do
+ controls = control_group_data.controls
+ expect(controls).to_not include(control)
+ notify_success
+ expect(controls).to include(control)
+ end
+ end
+
+ describe "#example_failure" do
+ include_context "control"
+
+ let(:details) { "poop" }
+
+ def notify_failure
+ control_group_data.example_failure(control_data, details)
+ end
+
+ it "does not increment the number of successful audits" do
+ num_success = control_group_data.number_succeeded
+ notify_failure
+ expect(control_group_data.number_succeeded).to eq num_success
+ end
+
+ it "increments the number of failed audits" do
+ num_failed = control_group_data.number_failed
+ notify_failure
+ expect(control_group_data.number_failed).to eq (num_failed + 1)
+ end
+
+ it "marks the audit's status as failure" do
+ notify_failure
+ expect(control.status).to eq "failure"
+ end
+
+ it "marks its own status as failure" do
+ notify_failure
+ expect(control_group_data.status).to eq "failure"
+ end
+
+ it "saves the control" do
+ controls = control_group_data.controls
+ expect(controls).to_not include(control)
+ notify_failure
+ expect(controls).to include(control)
+ end
+
+ context "when details are not provided" do
+
+ let(:details) { nil }
+
+ it "does not save details to the control" do
+ default_details = control.details
+ expect(control).to_not receive(:details=)
+ notify_failure
+ expect(control.details).to eq default_details
+ end
+ end
+
+ context "when details are provided" do
+
+ let(:details) { "yep that didn't work" }
+
+ it "saves details to the control" do
+ notify_failure
+ expect(control.details).to eq details
+ end
+ end
+ end
+
+ shared_examples "multiple audits" do |success_or_failure|
+ include_context "control"
+
+ let(:num_success) { 0 }
+ let(:num_failure) { 0 }
+
+ before do
+ if num_failure == 0
+ num_success.times { control_group_data.example_success(control_data) }
+ elsif num_success == 0
+ num_failure.times { control_group_data.example_failure(control_data, nil) }
+ end
+ end
+
+ it "counts the number of successful audits" do
+ expect(control_group_data.number_succeeded).to eq num_success
+ end
+
+ it "counts the number of failed audits" do
+ expect(control_group_data.number_failed).to eq num_failure
+ end
+
+ it "marks its status as \"#{success_or_failure}\"" do
+ expect(control_group_data.status).to eq success_or_failure
+ end
+ end
+
+ context "when all audits pass" do
+ include_examples "multiple audits", "success" do
+ let(:num_success) { 3 }
+ end
+ end
+
+ context "when one audit fails" do
+ shared_examples "mixed audit results" do
+ include_examples "multiple audits", "failure" do
+
+ let(:audit_results) { [] }
+ let(:num_success) { audit_results.count("success") }
+ let(:num_failure) { 1 }
+
+ before do
+ audit_results.each do |result|
+ if result == "success"
+ control_group_data.example_success(control_data)
+ else
+ control_group_data.example_failure(control_data, nil)
+ end
+ end
+ end
+ end
+ end
+
+ context "and it's the first audit" do
+ include_examples "mixed audit results" do
+ let(:audit_results) { ["failure", "success", "success"] }
+ end
+ end
+
+ context "and it's an audit in the middle" do
+ include_examples "mixed audit results" do
+ let(:audit_results) { ["success", "failure", "success"] }
+ end
+ end
+
+ context "and it's the last audit" do
+ include_examples "mixed audit results" do
+ let(:audit_results) { ["success", "success", "failure"] }
+ end
+ end
+ end
+
+ context "when all audits fail" do
+ include_examples "multiple audits", "failure" do
+ let(:num_failure) { 3 }
+ end
+ end
+
+ describe "#to_hash" do
+
+ let(:control_group_data_hash) { control_group_data.to_hash }
+
+ it "returns a hash" do
+ expect(control_group_data_hash).to be_a(Hash)
+ end
+
+ it "describes a Chef::Audit::ControlGroupData object" do
+ keys = [:name, :status, :number_succeeded, :number_failed,
+ :controls, :id]
+ expect(control_group_data_hash.keys).to match_array(keys)
+ end
+
+ describe ":controls" do
+
+ let(:control_group_controls) { control_group_data_hash[:controls] }
+
+ context "with no controls added" do
+ it "is an empty list" do
+ expect(control_group_controls).to eq []
+ end
+ end
+
+ context "with one control added" do
+ include_context "control"
+
+ let(:control_list) { [control_data] }
+ let(:control_hash) { control.to_hash }
+
+ before do
+ expect(control_group_data).to receive(:controls).twice.and_return(control_list)
+ expect(control_data).to receive(:to_hash).and_return(control_hash)
+ end
+
+ it "is a one-element list containing the control hash" do
+ expect(control_group_controls.size).to eq 1
+ expect(control_group_controls).to include(control_hash)
+ end
+
+ it "adds a sequence number to the control" do
+ control_group_data.to_hash
+ expect(control_hash).to have_key(:sequence_number)
+ end
+
+ end
+
+ context "with multiple controls added" do
+
+ let(:control_hash_1) { {:line_number => 27} }
+ let(:control_hash_2) { {:line_number => 13} }
+ let(:control_hash_3) { {:line_number => 35} }
+
+ let(:control_1) { double("control 1",
+ :line_number => control_hash_1[:line_number],
+ :to_hash => control_hash_1) }
+ let(:control_2) { double("control 2",
+ :line_number => control_hash_2[:line_number],
+ :to_hash => control_hash_2) }
+ let(:control_3) { double("control 3",
+ :line_number => control_hash_3[:line_number],
+ :to_hash => control_hash_3) }
+
+ let(:control_list) { [control_1, control_2, control_3] }
+ let(:ordered_control_hashes) { [control_hash_2, control_hash_1, control_hash_3] }
+
+ before do
+ # Another way to do this would be to call #example_success
+ # or #example_failure per control hash, but we'd have to
+ # then stub #create_control and it's a lot of extra stubbing work.
+ # We can't stub the controls reader to return a list of
+ # controls because of the call to sort! and the following
+ # reading of controls.
+ control_group_data.instance_variable_set(:@controls, control_list)
+ end
+
+ it "is a list of control group hashes ordered by line number" do
+ expect(control_group_controls.size).to eq 3
+ expect(control_group_controls).to eq ordered_control_hashes
+ end
+
+ it "assigns sequence numbers in order" do
+ control_group_data.to_hash
+ ordered_control_hashes.each_with_index do |control_hash, idx|
+ expect(control_hash[:sequence_number]).to eq idx + 1
+ end
+ end
+ end
+ end
+ end
+
+end
diff --git a/lib/chef/monkey_patches/file.rb b/spec/unit/audit/rspec_formatter_spec.rb
index acc0ca73fe..471473e387 100644
--- a/lib/chef/monkey_patches/file.rb
+++ b/spec/unit/audit/rspec_formatter_spec.rb
@@ -1,6 +1,8 @@
#
-# Author:: Daniel DeLeo (<dan@opscode.com>)
-# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# Author:: Tyler Ball (<tball@chef.io>)
+# Author:: Claire McQuin (<claire@getchef.com>)
+#
+# Copyright:: Copyright (c) 2014 Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,11 +18,12 @@
# limitations under the License.
#
-if !File.respond_to?(:realpath)
- require 'pathname'
- class File
- def self.realpath(path)
- Pathname.new(path).realpath.to_s
- end
+require 'spec_helper'
+require 'chef/audit/rspec_formatter'
+
+describe Chef::Audit::RspecFormatter do
+ let(:formatter) { Chef::Audit::RspecFormatter.new(nil) }
+ it "should respond to close" do
+ expect(formatter).to respond_to(:close)
end
end
diff --git a/spec/unit/audit/runner_spec.rb b/spec/unit/audit/runner_spec.rb
new file mode 100644
index 0000000000..801147bdb9
--- /dev/null
+++ b/spec/unit/audit/runner_spec.rb
@@ -0,0 +1,135 @@
+#
+# Author:: Tyler Ball (<tball@chef.io>)
+# Copyright:: Copyright (c) 2014 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 'spec_helper'
+require 'rspec/core/sandbox'
+require 'chef/audit/runner'
+require 'chef/audit/audit_event_proxy'
+require 'chef/audit/rspec_formatter'
+require 'rspec/support/spec/in_sub_process'
+require 'rspec/support/spec/stderr_splitter'
+
+
+describe Chef::Audit::Runner do
+ include RSpec::Support::InSubProcess
+
+ let(:events) { double("events") }
+ let(:run_context) { instance_double(Chef::RunContext, :events => events) }
+ let(:runner) { Chef::Audit::Runner.new(run_context) }
+
+ around(:each) do |ex|
+ RSpec::Core::Sandbox.sandboxed { ex.run }
+ end
+
+ describe "#initialize" do
+ it "correctly sets the run_context during initialization" do
+ expect(runner.instance_variable_get(:@run_context)).to eq(run_context)
+ end
+ end
+
+ context "during #run" do
+
+ describe "#setup" do
+ let(:log_location) { File.join(Dir.tmpdir, 'audit_log') }
+ let(:color) { false }
+
+ before do
+ Chef::Config[:log_location] = log_location
+ Chef::Config[:color] = color
+ end
+
+ it "sets all the config values" do
+ # This runs the Serverspec includes - we don't want these hanging around in all subsequent tests so
+ # we run this in a forked process. Keeps Serverspec files from getting loaded into main process.
+ in_sub_process do
+ runner.send(:setup)
+
+ expect(RSpec.configuration.output_stream).to eq(log_location)
+ expect(RSpec.configuration.error_stream).to eq(log_location)
+
+ expect(RSpec.configuration.formatters.size).to eq(2)
+ expect(RSpec.configuration.formatters).to include(instance_of(Chef::Audit::AuditEventProxy))
+ expect(RSpec.configuration.formatters).to include(instance_of(Chef::Audit::RspecFormatter))
+ expect(Chef::Audit::AuditEventProxy.class_variable_get(:@@events)).to eq(run_context.events)
+
+ expect(RSpec.configuration.expectation_frameworks).to eq([RSpec::Matchers])
+ expect(RSpec::Matchers.configuration.syntax).to eq([:expect])
+
+ expect(RSpec.configuration.color).to eq(color)
+ expect(RSpec.configuration.expose_dsl_globally?).to eq(false)
+
+ expect(Specinfra.configuration.backend).to eq(:exec)
+ end
+ end
+ end
+
+ describe "#register_control_groups" do
+ let(:audits) { [] }
+ let(:run_context) { instance_double(Chef::RunContext, :audits => audits) }
+
+ it "adds the control group aliases" do
+ runner.send(:register_control_groups)
+
+ expect(RSpec::Core::DSL.example_group_aliases).to include(:__control_group__)
+ expect(RSpec::Core::DSL.example_group_aliases).to include(:control)
+ end
+
+ context "audits exist" do
+ let(:audits) { {"audit_name" => group} }
+ let(:group) {Struct.new(:args, :block).new(["group_name"], nil)}
+
+ it "sends the audits to the world" do
+ runner.send(:register_control_groups)
+
+ expect(RSpec.world.example_groups.size).to eq(1)
+ # For whatever reason, `kind_of` is not working
+ # expect(RSpec.world.example_groups).to include(kind_of(RSpec::Core::ExampleGroup)) => FAIL
+ g = RSpec.world.example_groups[0]
+ expect(g.ancestors).to include(RSpec::Core::ExampleGroup)
+ expect(g.description).to eq("group_name")
+ end
+ end
+ end
+
+ describe "#do_run" do
+ let(:rspec_runner) { instance_double(RSpec::Core::Runner) }
+
+ it "executes the runner" do
+ expect(RSpec::Core::Runner).to receive(:new).with(nil).and_return(rspec_runner)
+ expect(rspec_runner).to receive(:run_specs).with([])
+
+ runner.send(:do_run)
+ end
+ end
+ end
+
+ describe "counters" do
+ it "correctly calculates failed?" do
+ expect(runner.failed?).to eq(false)
+ end
+
+ it "correctly calculates num_failed" do
+ expect(runner.num_failed).to eq(0)
+ end
+
+ it "correctly calculates num_total" do
+ expect(runner.num_total).to eq(0)
+ end
+ end
+
+end
diff --git a/spec/unit/chef_fs/config_spec.rb b/spec/unit/chef_fs/config_spec.rb
index 031da6c4b5..c7c47ad8ab 100644
--- a/spec/unit/chef_fs/config_spec.rb
+++ b/spec/unit/chef_fs/config_spec.rb
@@ -55,4 +55,56 @@ describe Chef::ChefFS::Config do
Chef::ChefFS::Config.new(base_config, Dir.pwd, {}, ui)
end
end
+
+ describe "local FS configuration" do
+
+ let(:chef_config) do
+ Mash.new({
+ client_path: "/base_path/clients",
+ cookbook_path: "/base_path/cookbooks",
+ data_bag_path: "/base_path/data_bags",
+ environment_path: "/base_path/environments",
+ node_path: "/base_path/nodes",
+ role_path: "/base_path/roles",
+ user_path: "/base_path/users",
+ policy_path: "/base_path/policies"
+ })
+ end
+
+ let(:chef_fs_config) { Chef::ChefFS::Config.new(chef_config, Dir.pwd) }
+
+ subject(:local_fs) { chef_fs_config.local_fs }
+
+ def platform_path(*args)
+ File.expand_path(*args)
+ end
+
+ it "sets the correct nodes path on the local FS object" do
+ expect(local_fs.child_paths["nodes"]).to eq([platform_path("/base_path/nodes")])
+ end
+
+ it "sets the correct cookbook path on the local FS object" do
+ expect(local_fs.child_paths["cookbooks"]).to eq([platform_path("/base_path/cookbooks")])
+ end
+
+ it "sets the correct data bag path on the local FS object" do
+ expect(local_fs.child_paths["data_bags"]).to eq([platform_path("/base_path/data_bags")])
+ end
+
+ it "sets the correct environment path on the local FS object" do
+ expect(local_fs.child_paths["environments"]).to eq([platform_path("/base_path/environments")])
+ end
+
+ it "sets the correct role path on the local FS object" do
+ expect(local_fs.child_paths["roles"]).to eq([platform_path("/base_path/roles")])
+ end
+
+ it "sets the correct user path on the local FS object" do
+ expect(local_fs.child_paths["users"]).to eq([platform_path("/base_path/users")])
+ end
+
+ it "sets the correct policy path on the local FS object" do
+ expect(local_fs.child_paths["policies"]).to eq([platform_path("/base_path/policies")])
+ end
+ end
end
diff --git a/spec/unit/chef_fs/diff_spec.rb b/spec/unit/chef_fs/diff_spec.rb
index 2133d05139..71605393f3 100644
--- a/spec/unit/chef_fs/diff_spec.rb
+++ b/spec/unit/chef_fs/diff_spec.rb
@@ -91,7 +91,7 @@ describe 'diff', :uses_diff => true do
Chef::ChefFS::CommandLine.diff_print(pattern('/'), a, b, nil, nil) do |diff|
results << remove_os_differences(diff)
end
- results.should =~ [
+ expect(results).to match_array([
'diff --knife a/both_dirs/sub_both_files_different b/both_dirs/sub_both_files_different
--- a/both_dirs/sub_both_files_different DATE
+++ b/both_dirs/sub_both_files_different DATE
@@ -160,14 +160,14 @@ new file
+++ b/b_only_file DATE
CONTEXT_LINE_NUMBERS
+b_only_file
-' ]
+' ])
end
it 'Chef::ChefFS::CommandLine.diff_print(/both_dirs)' do
results = []
Chef::ChefFS::CommandLine.diff_print(pattern('/both_dirs'), a, b, nil, nil) do |diff|
results << remove_os_differences(diff)
end
- results.should =~ [
+ expect(results).to match_array([
'diff --knife a/both_dirs/sub_both_files_different b/both_dirs/sub_both_files_different
--- a/both_dirs/sub_both_files_different DATE
+++ b/both_dirs/sub_both_files_different DATE
@@ -202,14 +202,14 @@ new file
+++ b/both_dirs/sub_b_only_file DATE
CONTEXT_LINE_NUMBERS
+sub_b_only_file
-' ]
+' ])
end
it 'Chef::ChefFS::CommandLine.diff_print(/) with depth 1' do
results = []
Chef::ChefFS::CommandLine.diff_print(pattern('/'), a, b, 1, nil) do |diff|
results << remove_os_differences(diff)
end
- results.should =~ [
+ expect(results).to match_array([
'Common subdirectories: b/both_dirs
','diff --knife a/both_files_different b/both_files_different
--- a/both_files_different DATE
@@ -236,14 +236,14 @@ new file
+++ b/b_only_file DATE
CONTEXT_LINE_NUMBERS
+b_only_file
-' ]
+' ])
end
it 'Chef::ChefFS::CommandLine.diff_print(/*_*) with depth 0' do
results = []
Chef::ChefFS::CommandLine.diff_print(pattern('/*_*'), a, b, 0, nil) do |diff|
results << remove_os_differences(diff)
end
- results.should =~ [
+ expect(results).to match_array([
'Common subdirectories: b/both_dirs
','diff --knife a/both_files_different b/both_files_different
--- a/both_files_different DATE
@@ -270,14 +270,14 @@ new file
+++ b/b_only_file DATE
CONTEXT_LINE_NUMBERS
+b_only_file
-' ]
+' ])
end
it 'Chef::ChefFS::CommandLine.diff_print(/) in name-only mode' do
results = []
Chef::ChefFS::CommandLine.diff_print(pattern('/'), a, b, nil, :name_only) do |diff|
results << remove_os_differences(diff)
end
- results.should =~ [
+ expect(results).to match_array([
"b/both_dirs/sub_both_files_different\n",
"b/both_dirs/sub_dirs_empty_in_b_filled_in_a/subsub\n",
"b/both_dirs/sub_dirs_empty_in_a_filled_in_b/subsub\n",
@@ -296,14 +296,14 @@ CONTEXT_LINE_NUMBERS
"b/b_only_file\n",
"b/dir_in_a_file_in_b\n",
"b/file_in_a_dir_in_b\n"
- ]
+ ])
end
it 'Chef::ChefFS::CommandLine.diff_print(/) in name-status mode' do
results = []
Chef::ChefFS::CommandLine.diff_print(pattern('/'), a, b, nil, :name_status) do |diff|
results << remove_os_differences(diff)
end
- results.should =~ [
+ expect(results).to match_array([
"M\tb/both_dirs/sub_both_files_different\n",
"D\tb/both_dirs/sub_dirs_empty_in_b_filled_in_a/subsub\n",
"A\tb/both_dirs/sub_dirs_empty_in_a_filled_in_b/subsub\n",
@@ -322,7 +322,7 @@ CONTEXT_LINE_NUMBERS
"A\tb/b_only_file\n",
"T\tb/dir_in_a_file_in_b\n",
"T\tb/file_in_a_dir_in_b\n"
- ]
+ ])
end
end
end
diff --git a/spec/unit/chef_fs/file_pattern_spec.rb b/spec/unit/chef_fs/file_pattern_spec.rb
index bac393a054..a9f06e8424 100644
--- a/spec/unit/chef_fs/file_pattern_spec.rb
+++ b/spec/unit/chef_fs/file_pattern_spec.rb
@@ -28,466 +28,465 @@ describe Chef::ChefFS::FilePattern do
context 'with empty pattern ""' do
let(:pattern) { Chef::ChefFS::FilePattern.new('') }
it 'match?' do
- pattern.match?('').should be_true
- pattern.match?('/').should be_false
- pattern.match?('a').should be_false
- pattern.match?('a/b').should be_false
+ expect(pattern.match?('')).to be_truthy
+ expect(pattern.match?('/')).to be_falsey
+ expect(pattern.match?('a')).to be_falsey
+ expect(pattern.match?('a/b')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should == ''
+ expect(pattern.exact_path).to eq('')
end
it 'could_match_children?' do
- pattern.could_match_children?('').should be_false
- pattern.could_match_children?('a/b').should be_false
+ expect(pattern.could_match_children?('')).to be_falsey
+ expect(pattern.could_match_children?('a/b')).to be_falsey
end
end
context 'with root pattern "/"' do
let(:pattern) { Chef::ChefFS::FilePattern.new('/') }
it 'match?' do
- pattern.match?('/').should be_true
- pattern.match?('').should be_false
- pattern.match?('a').should be_false
- pattern.match?('/a').should be_false
+ expect(pattern.match?('/')).to be_truthy
+ expect(pattern.match?('')).to be_falsey
+ expect(pattern.match?('a')).to be_falsey
+ expect(pattern.match?('/a')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should == '/'
+ expect(pattern.exact_path).to eq('/')
end
it 'could_match_children?' do
- pattern.could_match_children?('').should be_false
- pattern.could_match_children?('/').should be_false
- pattern.could_match_children?('a').should be_false
- pattern.could_match_children?('a/b').should be_false
- pattern.could_match_children?('/a').should be_false
+ expect(pattern.could_match_children?('')).to be_falsey
+ expect(pattern.could_match_children?('/')).to be_falsey
+ expect(pattern.could_match_children?('a')).to be_falsey
+ expect(pattern.could_match_children?('a/b')).to be_falsey
+ expect(pattern.could_match_children?('/a')).to be_falsey
end
end
context 'with simple pattern "abc"' do
let(:pattern) { Chef::ChefFS::FilePattern.new('abc') }
it 'match?' do
- pattern.match?('abc').should be_true
- pattern.match?('a').should be_false
- pattern.match?('abcd').should be_false
- pattern.match?('/abc').should be_false
- pattern.match?('').should be_false
- pattern.match?('/').should be_false
+ expect(pattern.match?('abc')).to be_truthy
+ expect(pattern.match?('a')).to be_falsey
+ expect(pattern.match?('abcd')).to be_falsey
+ expect(pattern.match?('/abc')).to be_falsey
+ expect(pattern.match?('')).to be_falsey
+ expect(pattern.match?('/')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should == 'abc'
+ expect(pattern.exact_path).to eq('abc')
end
it 'could_match_children?' do
- pattern.could_match_children?('').should be_false
- pattern.could_match_children?('abc').should be_false
- pattern.could_match_children?('/abc').should be_false
+ expect(pattern.could_match_children?('')).to be_falsey
+ expect(pattern.could_match_children?('abc')).to be_falsey
+ expect(pattern.could_match_children?('/abc')).to be_falsey
end
end
context 'with simple pattern "/abc"' do
let(:pattern) { Chef::ChefFS::FilePattern.new('/abc') }
it 'match?' do
- pattern.match?('/abc').should be_true
- pattern.match?('abc').should be_false
- pattern.match?('a').should be_false
- pattern.match?('abcd').should be_false
- pattern.match?('').should be_false
- pattern.match?('/').should be_false
+ expect(pattern.match?('/abc')).to be_truthy
+ expect(pattern.match?('abc')).to be_falsey
+ expect(pattern.match?('a')).to be_falsey
+ expect(pattern.match?('abcd')).to be_falsey
+ expect(pattern.match?('')).to be_falsey
+ expect(pattern.match?('/')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should == '/abc'
+ expect(pattern.exact_path).to eq('/abc')
end
it 'could_match_children?' do
- pattern.could_match_children?('abc').should be_false
- pattern.could_match_children?('/abc').should be_false
- pattern.could_match_children?('/').should be_true
- pattern.could_match_children?('').should be_false
+ expect(pattern.could_match_children?('abc')).to be_falsey
+ expect(pattern.could_match_children?('/abc')).to be_falsey
+ expect(pattern.could_match_children?('/')).to be_truthy
+ expect(pattern.could_match_children?('')).to be_falsey
end
it 'exact_child_name_under' do
- pattern.exact_child_name_under('/').should == 'abc'
+ expect(pattern.exact_child_name_under('/')).to eq('abc')
end
end
context 'with simple pattern "abc/def/ghi"' do
let(:pattern) { Chef::ChefFS::FilePattern.new('abc/def/ghi') }
it 'match?' do
- pattern.match?('abc/def/ghi').should be_true
- pattern.match?('/abc/def/ghi').should be_false
- pattern.match?('abc').should be_false
- pattern.match?('abc/def').should be_false
+ expect(pattern.match?('abc/def/ghi')).to be_truthy
+ expect(pattern.match?('/abc/def/ghi')).to be_falsey
+ expect(pattern.match?('abc')).to be_falsey
+ expect(pattern.match?('abc/def')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should == 'abc/def/ghi'
+ expect(pattern.exact_path).to eq('abc/def/ghi')
end
it 'could_match_children?' do
- pattern.could_match_children?('abc').should be_true
- pattern.could_match_children?('xyz').should be_false
- pattern.could_match_children?('/abc').should be_false
- pattern.could_match_children?('abc/def').should be_true
- pattern.could_match_children?('abc/xyz').should be_false
- pattern.could_match_children?('abc/def/ghi').should be_false
+ expect(pattern.could_match_children?('abc')).to be_truthy
+ expect(pattern.could_match_children?('xyz')).to be_falsey
+ expect(pattern.could_match_children?('/abc')).to be_falsey
+ expect(pattern.could_match_children?('abc/def')).to be_truthy
+ expect(pattern.could_match_children?('abc/xyz')).to be_falsey
+ expect(pattern.could_match_children?('abc/def/ghi')).to be_falsey
end
it 'exact_child_name_under' do
- pattern.exact_child_name_under('abc').should == 'def'
- pattern.exact_child_name_under('abc/def').should == 'ghi'
+ expect(pattern.exact_child_name_under('abc')).to eq('def')
+ expect(pattern.exact_child_name_under('abc/def')).to eq('ghi')
end
end
context 'with simple pattern "/abc/def/ghi"' do
let(:pattern) { Chef::ChefFS::FilePattern.new('/abc/def/ghi') }
it 'match?' do
- pattern.match?('/abc/def/ghi').should be_true
- pattern.match?('abc/def/ghi').should be_false
- pattern.match?('/abc').should be_false
- pattern.match?('/abc/def').should be_false
+ expect(pattern.match?('/abc/def/ghi')).to be_truthy
+ expect(pattern.match?('abc/def/ghi')).to be_falsey
+ expect(pattern.match?('/abc')).to be_falsey
+ expect(pattern.match?('/abc/def')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should == '/abc/def/ghi'
+ expect(pattern.exact_path).to eq('/abc/def/ghi')
end
it 'could_match_children?' do
- pattern.could_match_children?('/abc').should be_true
- pattern.could_match_children?('/xyz').should be_false
- pattern.could_match_children?('abc').should be_false
- pattern.could_match_children?('/abc/def').should be_true
- pattern.could_match_children?('/abc/xyz').should be_false
- pattern.could_match_children?('/abc/def/ghi').should be_false
+ expect(pattern.could_match_children?('/abc')).to be_truthy
+ expect(pattern.could_match_children?('/xyz')).to be_falsey
+ expect(pattern.could_match_children?('abc')).to be_falsey
+ expect(pattern.could_match_children?('/abc/def')).to be_truthy
+ expect(pattern.could_match_children?('/abc/xyz')).to be_falsey
+ expect(pattern.could_match_children?('/abc/def/ghi')).to be_falsey
end
it 'exact_child_name_under' do
- pattern.exact_child_name_under('/').should == 'abc'
- pattern.exact_child_name_under('/abc').should == 'def'
- pattern.exact_child_name_under('/abc/def').should == 'ghi'
+ expect(pattern.exact_child_name_under('/')).to eq('abc')
+ expect(pattern.exact_child_name_under('/abc')).to eq('def')
+ expect(pattern.exact_child_name_under('/abc/def')).to eq('ghi')
end
end
context 'with simple pattern "a\*\b"', :pending => (Chef::Platform.windows?) do
let(:pattern) { Chef::ChefFS::FilePattern.new('a\*\b') }
it 'match?' do
- pattern.match?('a*b').should be_true
- pattern.match?('ab').should be_false
- pattern.match?('acb').should be_false
- pattern.match?('ab').should be_false
+ expect(pattern.match?('a*b')).to be_truthy
+ expect(pattern.match?('ab')).to be_falsey
+ expect(pattern.match?('acb')).to be_falsey
+ expect(pattern.match?('ab')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should == 'a*b'
+ expect(pattern.exact_path).to eq('a*b')
end
it 'could_match_children?' do
- pattern.could_match_children?('a/*b').should be_false
+ expect(pattern.could_match_children?('a/*b')).to be_falsey
end
end
context 'with star pattern "/abc/*/ghi"' do
let(:pattern) { Chef::ChefFS::FilePattern.new('/abc/*/ghi') }
it 'match?' do
- pattern.match?('/abc/def/ghi').should be_true
- pattern.match?('/abc/ghi').should be_false
+ expect(pattern.match?('/abc/def/ghi')).to be_truthy
+ expect(pattern.match?('/abc/ghi')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should be_nil
+ expect(pattern.exact_path).to be_nil
end
it 'could_match_children?' do
- pattern.could_match_children?('/abc').should be_true
- pattern.could_match_children?('/xyz').should be_false
- pattern.could_match_children?('abc').should be_false
- pattern.could_match_children?('/abc/def').should be_true
- pattern.could_match_children?('/abc/xyz').should be_true
- pattern.could_match_children?('/abc/def/ghi').should be_false
+ expect(pattern.could_match_children?('/abc')).to be_truthy
+ expect(pattern.could_match_children?('/xyz')).to be_falsey
+ expect(pattern.could_match_children?('abc')).to be_falsey
+ expect(pattern.could_match_children?('/abc/def')).to be_truthy
+ expect(pattern.could_match_children?('/abc/xyz')).to be_truthy
+ expect(pattern.could_match_children?('/abc/def/ghi')).to be_falsey
end
it 'exact_child_name_under' do
- pattern.exact_child_name_under('/').should == 'abc'
- pattern.exact_child_name_under('/abc').should == nil
- pattern.exact_child_name_under('/abc/def').should == 'ghi'
+ expect(pattern.exact_child_name_under('/')).to eq('abc')
+ expect(pattern.exact_child_name_under('/abc')).to eq(nil)
+ expect(pattern.exact_child_name_under('/abc/def')).to eq('ghi')
end
end
context 'with star pattern "/abc/d*f/ghi"' do
let(:pattern) { Chef::ChefFS::FilePattern.new('/abc/d*f/ghi') }
it 'match?' do
- pattern.match?('/abc/def/ghi').should be_true
- pattern.match?('/abc/dxf/ghi').should be_true
- pattern.match?('/abc/df/ghi').should be_true
- pattern.match?('/abc/dxyzf/ghi').should be_true
- pattern.match?('/abc/d/ghi').should be_false
- pattern.match?('/abc/f/ghi').should be_false
- pattern.match?('/abc/ghi').should be_false
- pattern.match?('/abc/xyz/ghi').should be_false
+ expect(pattern.match?('/abc/def/ghi')).to be_truthy
+ expect(pattern.match?('/abc/dxf/ghi')).to be_truthy
+ expect(pattern.match?('/abc/df/ghi')).to be_truthy
+ expect(pattern.match?('/abc/dxyzf/ghi')).to be_truthy
+ expect(pattern.match?('/abc/d/ghi')).to be_falsey
+ expect(pattern.match?('/abc/f/ghi')).to be_falsey
+ expect(pattern.match?('/abc/ghi')).to be_falsey
+ expect(pattern.match?('/abc/xyz/ghi')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should be_nil
+ expect(pattern.exact_path).to be_nil
end
it 'could_match_children?' do
- pattern.could_match_children?('/abc').should be_true
- pattern.could_match_children?('/xyz').should be_false
- pattern.could_match_children?('abc').should be_false
- pattern.could_match_children?('/abc/def').should be_true
- pattern.could_match_children?('/abc/xyz').should be_false
- pattern.could_match_children?('/abc/dxyzf').should be_true
- pattern.could_match_children?('/abc/df').should be_true
- pattern.could_match_children?('/abc/d').should be_false
- pattern.could_match_children?('/abc/f').should be_false
- pattern.could_match_children?('/abc/def/ghi').should be_false
+ expect(pattern.could_match_children?('/abc')).to be_truthy
+ expect(pattern.could_match_children?('/xyz')).to be_falsey
+ expect(pattern.could_match_children?('abc')).to be_falsey
+ expect(pattern.could_match_children?('/abc/def')).to be_truthy
+ expect(pattern.could_match_children?('/abc/xyz')).to be_falsey
+ expect(pattern.could_match_children?('/abc/dxyzf')).to be_truthy
+ expect(pattern.could_match_children?('/abc/df')).to be_truthy
+ expect(pattern.could_match_children?('/abc/d')).to be_falsey
+ expect(pattern.could_match_children?('/abc/f')).to be_falsey
+ expect(pattern.could_match_children?('/abc/def/ghi')).to be_falsey
end
it 'exact_child_name_under' do
- pattern.exact_child_name_under('/').should == 'abc'
- pattern.exact_child_name_under('/abc').should == nil
- pattern.exact_child_name_under('/abc/def').should == 'ghi'
+ expect(pattern.exact_child_name_under('/')).to eq('abc')
+ expect(pattern.exact_child_name_under('/abc')).to eq(nil)
+ expect(pattern.exact_child_name_under('/abc/def')).to eq('ghi')
end
end
context 'with star pattern "/abc/d??f/ghi"' do
let(:pattern) { Chef::ChefFS::FilePattern.new('/abc/d??f/ghi') }
it 'match?' do
- pattern.match?('/abc/deef/ghi').should be_true
- pattern.match?('/abc/deeef/ghi').should be_false
- pattern.match?('/abc/def/ghi').should be_false
- pattern.match?('/abc/df/ghi').should be_false
- pattern.match?('/abc/d/ghi').should be_false
- pattern.match?('/abc/f/ghi').should be_false
- pattern.match?('/abc/ghi').should be_false
+ expect(pattern.match?('/abc/deef/ghi')).to be_truthy
+ expect(pattern.match?('/abc/deeef/ghi')).to be_falsey
+ expect(pattern.match?('/abc/def/ghi')).to be_falsey
+ expect(pattern.match?('/abc/df/ghi')).to be_falsey
+ expect(pattern.match?('/abc/d/ghi')).to be_falsey
+ expect(pattern.match?('/abc/f/ghi')).to be_falsey
+ expect(pattern.match?('/abc/ghi')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should be_nil
+ expect(pattern.exact_path).to be_nil
end
it 'could_match_children?' do
- pattern.could_match_children?('/abc').should be_true
- pattern.could_match_children?('/xyz').should be_false
- pattern.could_match_children?('abc').should be_false
- pattern.could_match_children?('/abc/deef').should be_true
- pattern.could_match_children?('/abc/deeef').should be_false
- pattern.could_match_children?('/abc/def').should be_false
- pattern.could_match_children?('/abc/df').should be_false
- pattern.could_match_children?('/abc/d').should be_false
- pattern.could_match_children?('/abc/f').should be_false
- pattern.could_match_children?('/abc/deef/ghi').should be_false
+ expect(pattern.could_match_children?('/abc')).to be_truthy
+ expect(pattern.could_match_children?('/xyz')).to be_falsey
+ expect(pattern.could_match_children?('abc')).to be_falsey
+ expect(pattern.could_match_children?('/abc/deef')).to be_truthy
+ expect(pattern.could_match_children?('/abc/deeef')).to be_falsey
+ expect(pattern.could_match_children?('/abc/def')).to be_falsey
+ expect(pattern.could_match_children?('/abc/df')).to be_falsey
+ expect(pattern.could_match_children?('/abc/d')).to be_falsey
+ expect(pattern.could_match_children?('/abc/f')).to be_falsey
+ expect(pattern.could_match_children?('/abc/deef/ghi')).to be_falsey
end
it 'exact_child_name_under' do
- pattern.exact_child_name_under('/').should == 'abc'
- pattern.exact_child_name_under('/abc').should == nil
- pattern.exact_child_name_under('/abc/deef').should == 'ghi'
+ expect(pattern.exact_child_name_under('/')).to eq('abc')
+ expect(pattern.exact_child_name_under('/abc')).to eq(nil)
+ expect(pattern.exact_child_name_under('/abc/deef')).to eq('ghi')
end
end
context 'with star pattern "/abc/d[a-z][0-9]f/ghi"', :pending => (Chef::Platform.windows?) do
let(:pattern) { Chef::ChefFS::FilePattern.new('/abc/d[a-z][0-9]f/ghi') }
it 'match?' do
- pattern.match?('/abc/de1f/ghi').should be_true
- pattern.match?('/abc/deef/ghi').should be_false
- pattern.match?('/abc/d11f/ghi').should be_false
- pattern.match?('/abc/de11f/ghi').should be_false
- pattern.match?('/abc/dee1f/ghi').should be_false
- pattern.match?('/abc/df/ghi').should be_false
- pattern.match?('/abc/d/ghi').should be_false
- pattern.match?('/abc/f/ghi').should be_false
- pattern.match?('/abc/ghi').should be_false
+ expect(pattern.match?('/abc/de1f/ghi')).to be_truthy
+ expect(pattern.match?('/abc/deef/ghi')).to be_falsey
+ expect(pattern.match?('/abc/d11f/ghi')).to be_falsey
+ expect(pattern.match?('/abc/de11f/ghi')).to be_falsey
+ expect(pattern.match?('/abc/dee1f/ghi')).to be_falsey
+ expect(pattern.match?('/abc/df/ghi')).to be_falsey
+ expect(pattern.match?('/abc/d/ghi')).to be_falsey
+ expect(pattern.match?('/abc/f/ghi')).to be_falsey
+ expect(pattern.match?('/abc/ghi')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should be_nil
+ expect(pattern.exact_path).to be_nil
end
it 'could_match_children?' do
- pattern.could_match_children?('/abc').should be_true
- pattern.could_match_children?('/xyz').should be_false
- pattern.could_match_children?('abc').should be_false
- pattern.could_match_children?('/abc/de1f').should be_true
- pattern.could_match_children?('/abc/deef').should be_false
- pattern.could_match_children?('/abc/d11f').should be_false
- pattern.could_match_children?('/abc/de11f').should be_false
- pattern.could_match_children?('/abc/dee1f').should be_false
- pattern.could_match_children?('/abc/def').should be_false
- pattern.could_match_children?('/abc/df').should be_false
- pattern.could_match_children?('/abc/d').should be_false
- pattern.could_match_children?('/abc/f').should be_false
- pattern.could_match_children?('/abc/de1f/ghi').should be_false
+ expect(pattern.could_match_children?('/abc')).to be_truthy
+ expect(pattern.could_match_children?('/xyz')).to be_falsey
+ expect(pattern.could_match_children?('abc')).to be_falsey
+ expect(pattern.could_match_children?('/abc/de1f')).to be_truthy
+ expect(pattern.could_match_children?('/abc/deef')).to be_falsey
+ expect(pattern.could_match_children?('/abc/d11f')).to be_falsey
+ expect(pattern.could_match_children?('/abc/de11f')).to be_falsey
+ expect(pattern.could_match_children?('/abc/dee1f')).to be_falsey
+ expect(pattern.could_match_children?('/abc/def')).to be_falsey
+ expect(pattern.could_match_children?('/abc/df')).to be_falsey
+ expect(pattern.could_match_children?('/abc/d')).to be_falsey
+ expect(pattern.could_match_children?('/abc/f')).to be_falsey
+ expect(pattern.could_match_children?('/abc/de1f/ghi')).to be_falsey
end
it 'exact_child_name_under' do
- pattern.exact_child_name_under('/').should == 'abc'
- pattern.exact_child_name_under('/abc').should == nil
- pattern.exact_child_name_under('/abc/de1f').should == 'ghi'
+ expect(pattern.exact_child_name_under('/')).to eq('abc')
+ expect(pattern.exact_child_name_under('/abc')).to eq(nil)
+ expect(pattern.exact_child_name_under('/abc/de1f')).to eq('ghi')
end
end
context 'with star pattern "/abc/**/ghi"' do
let(:pattern) { Chef::ChefFS::FilePattern.new('/abc/**/ghi') }
it 'match?' do
- pattern.match?('/abc/def/ghi').should be_true
- pattern.match?('/abc/d/e/f/ghi').should be_true
- pattern.match?('/abc/ghi').should be_false
- pattern.match?('/abcdef/d/ghi').should be_false
- pattern.match?('/abc/d/defghi').should be_false
- pattern.match?('/xyz').should be_false
+ expect(pattern.match?('/abc/def/ghi')).to be_truthy
+ expect(pattern.match?('/abc/d/e/f/ghi')).to be_truthy
+ expect(pattern.match?('/abc/ghi')).to be_falsey
+ expect(pattern.match?('/abcdef/d/ghi')).to be_falsey
+ expect(pattern.match?('/abc/d/defghi')).to be_falsey
+ expect(pattern.match?('/xyz')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should be_nil
+ expect(pattern.exact_path).to be_nil
end
it 'could_match_children?' do
- pattern.could_match_children?('/abc').should be_true
- pattern.could_match_children?('/abc/d').should be_true
- pattern.could_match_children?('/abc/d/e').should be_true
- pattern.could_match_children?('/abc/d/e/f').should be_true
- pattern.could_match_children?('/abc/def/ghi').should be_true
- pattern.could_match_children?('abc').should be_false
- pattern.could_match_children?('/xyz').should be_false
+ expect(pattern.could_match_children?('/abc')).to be_truthy
+ expect(pattern.could_match_children?('/abc/d')).to be_truthy
+ expect(pattern.could_match_children?('/abc/d/e')).to be_truthy
+ expect(pattern.could_match_children?('/abc/d/e/f')).to be_truthy
+ expect(pattern.could_match_children?('/abc/def/ghi')).to be_truthy
+ expect(pattern.could_match_children?('abc')).to be_falsey
+ expect(pattern.could_match_children?('/xyz')).to be_falsey
end
it 'exact_child_name_under' do
- pattern.exact_child_name_under('/').should == 'abc'
- pattern.exact_child_name_under('/abc').should == nil
- pattern.exact_child_name_under('/abc/def').should == nil
+ expect(pattern.exact_child_name_under('/')).to eq('abc')
+ expect(pattern.exact_child_name_under('/abc')).to eq(nil)
+ expect(pattern.exact_child_name_under('/abc/def')).to eq(nil)
end
end
context 'with star pattern "/abc**/ghi"' do
let(:pattern) { Chef::ChefFS::FilePattern.new('/abc**/ghi') }
it 'match?' do
- pattern.match?('/abc/def/ghi').should be_true
- pattern.match?('/abc/d/e/f/ghi').should be_true
- pattern.match?('/abc/ghi').should be_true
- pattern.match?('/abcdef/ghi').should be_true
- pattern.match?('/abc/defghi').should be_false
- pattern.match?('/xyz').should be_false
+ expect(pattern.match?('/abc/def/ghi')).to be_truthy
+ expect(pattern.match?('/abc/d/e/f/ghi')).to be_truthy
+ expect(pattern.match?('/abc/ghi')).to be_truthy
+ expect(pattern.match?('/abcdef/ghi')).to be_truthy
+ expect(pattern.match?('/abc/defghi')).to be_falsey
+ expect(pattern.match?('/xyz')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should be_nil
+ expect(pattern.exact_path).to be_nil
end
it 'could_match_children?' do
- pattern.could_match_children?('/abc').should be_true
- pattern.could_match_children?('/abcdef').should be_true
- pattern.could_match_children?('/abc/d/e').should be_true
- pattern.could_match_children?('/abc/d/e/f').should be_true
- pattern.could_match_children?('/abc/def/ghi').should be_true
- pattern.could_match_children?('abc').should be_false
+ expect(pattern.could_match_children?('/abc')).to be_truthy
+ expect(pattern.could_match_children?('/abcdef')).to be_truthy
+ expect(pattern.could_match_children?('/abc/d/e')).to be_truthy
+ expect(pattern.could_match_children?('/abc/d/e/f')).to be_truthy
+ expect(pattern.could_match_children?('/abc/def/ghi')).to be_truthy
+ expect(pattern.could_match_children?('abc')).to be_falsey
end
it 'could_match_children? /abc** returns false for /xyz' do
- pending 'Make could_match_children? more rigorous' do
- # At the moment, we return false for this, but in the end it would be nice to return true:
- pattern.could_match_children?('/xyz').should be_false
- end
+ pending 'Make could_match_children? more rigorous'
+ # At the moment, we return false for this, but in the end it would be nice to return true:
+ expect(pattern.could_match_children?('/xyz')).to be_falsey
end
it 'exact_child_name_under' do
- pattern.exact_child_name_under('/').should == nil
- pattern.exact_child_name_under('/abc').should == nil
- pattern.exact_child_name_under('/abc/def').should == nil
+ expect(pattern.exact_child_name_under('/')).to eq(nil)
+ expect(pattern.exact_child_name_under('/abc')).to eq(nil)
+ expect(pattern.exact_child_name_under('/abc/def')).to eq(nil)
end
end
context 'with star pattern "/abc/**ghi"' do
let(:pattern) { Chef::ChefFS::FilePattern.new('/abc/**ghi') }
it 'match?' do
- pattern.match?('/abc/def/ghi').should be_true
- pattern.match?('/abc/def/ghi/ghi').should be_true
- pattern.match?('/abc/def/ghi/jkl').should be_false
- pattern.match?('/abc/d/e/f/ghi').should be_true
- pattern.match?('/abc/ghi').should be_true
- pattern.match?('/abcdef/ghi').should be_false
- pattern.match?('/abc/defghi').should be_true
- pattern.match?('/xyz').should be_false
+ expect(pattern.match?('/abc/def/ghi')).to be_truthy
+ expect(pattern.match?('/abc/def/ghi/ghi')).to be_truthy
+ expect(pattern.match?('/abc/def/ghi/jkl')).to be_falsey
+ expect(pattern.match?('/abc/d/e/f/ghi')).to be_truthy
+ expect(pattern.match?('/abc/ghi')).to be_truthy
+ expect(pattern.match?('/abcdef/ghi')).to be_falsey
+ expect(pattern.match?('/abc/defghi')).to be_truthy
+ expect(pattern.match?('/xyz')).to be_falsey
end
it 'exact_path' do
- pattern.exact_path.should be_nil
+ expect(pattern.exact_path).to be_nil
end
it 'could_match_children?' do
- pattern.could_match_children?('/abc').should be_true
- pattern.could_match_children?('/abcdef').should be_false
- pattern.could_match_children?('/abc/d/e').should be_true
- pattern.could_match_children?('/abc/d/e/f').should be_true
- pattern.could_match_children?('/abc/def/ghi').should be_true
- pattern.could_match_children?('abc').should be_false
- pattern.could_match_children?('/xyz').should be_false
+ expect(pattern.could_match_children?('/abc')).to be_truthy
+ expect(pattern.could_match_children?('/abcdef')).to be_falsey
+ expect(pattern.could_match_children?('/abc/d/e')).to be_truthy
+ expect(pattern.could_match_children?('/abc/d/e/f')).to be_truthy
+ expect(pattern.could_match_children?('/abc/def/ghi')).to be_truthy
+ expect(pattern.could_match_children?('abc')).to be_falsey
+ expect(pattern.could_match_children?('/xyz')).to be_falsey
end
it 'exact_child_name_under' do
- pattern.exact_child_name_under('/').should == 'abc'
- pattern.exact_child_name_under('/abc').should == nil
- pattern.exact_child_name_under('/abc/def').should == nil
+ expect(pattern.exact_child_name_under('/')).to eq('abc')
+ expect(pattern.exact_child_name_under('/abc')).to eq(nil)
+ expect(pattern.exact_child_name_under('/abc/def')).to eq(nil)
end
end
context 'with star pattern "a**b**c"' do
let(:pattern) { Chef::ChefFS::FilePattern.new('a**b**c') }
it 'match?' do
- pattern.match?('axybzwc').should be_true
- pattern.match?('abc').should be_true
- pattern.match?('axyzwc').should be_false
- pattern.match?('ac').should be_false
- pattern.match?('a/x/y/b/z/w/c').should be_true
+ expect(pattern.match?('axybzwc')).to be_truthy
+ expect(pattern.match?('abc')).to be_truthy
+ expect(pattern.match?('axyzwc')).to be_falsey
+ expect(pattern.match?('ac')).to be_falsey
+ expect(pattern.match?('a/x/y/b/z/w/c')).to be_truthy
end
it 'exact_path' do
- pattern.exact_path.should be_nil
+ expect(pattern.exact_path).to be_nil
end
end
context 'normalization tests' do
it 'handles trailing slashes' do
- p('abc/').normalized_pattern.should == 'abc'
- p('abc/').exact_path.should == 'abc'
- p('abc/').match?('abc').should be_true
- p('//').normalized_pattern.should == '/'
- p('//').exact_path.should == '/'
- p('//').match?('/').should be_true
- p('/./').normalized_pattern.should == '/'
- p('/./').exact_path.should == '/'
- p('/./').match?('/').should be_true
+ expect(p('abc/').normalized_pattern).to eq('abc')
+ expect(p('abc/').exact_path).to eq('abc')
+ expect(p('abc/').match?('abc')).to be_truthy
+ expect(p('//').normalized_pattern).to eq('/')
+ expect(p('//').exact_path).to eq('/')
+ expect(p('//').match?('/')).to be_truthy
+ expect(p('/./').normalized_pattern).to eq('/')
+ expect(p('/./').exact_path).to eq('/')
+ expect(p('/./').match?('/')).to be_truthy
end
it 'handles multiple slashes' do
- p('abc//def').normalized_pattern.should == 'abc/def'
- p('abc//def').exact_path.should == 'abc/def'
- p('abc//def').match?('abc/def').should be_true
- p('abc//').normalized_pattern.should == 'abc'
- p('abc//').exact_path.should == 'abc'
- p('abc//').match?('abc').should be_true
+ expect(p('abc//def').normalized_pattern).to eq('abc/def')
+ expect(p('abc//def').exact_path).to eq('abc/def')
+ expect(p('abc//def').match?('abc/def')).to be_truthy
+ expect(p('abc//').normalized_pattern).to eq('abc')
+ expect(p('abc//').exact_path).to eq('abc')
+ expect(p('abc//').match?('abc')).to be_truthy
end
it 'handles dot' do
- p('abc/./def').normalized_pattern.should == 'abc/def'
- p('abc/./def').exact_path.should == 'abc/def'
- p('abc/./def').match?('abc/def').should be_true
- p('./abc/def').normalized_pattern.should == 'abc/def'
- p('./abc/def').exact_path.should == 'abc/def'
- p('./abc/def').match?('abc/def').should be_true
- p('/.').normalized_pattern.should == '/'
- p('/.').exact_path.should == '/'
- p('/.').match?('/').should be_true
+ expect(p('abc/./def').normalized_pattern).to eq('abc/def')
+ expect(p('abc/./def').exact_path).to eq('abc/def')
+ expect(p('abc/./def').match?('abc/def')).to be_truthy
+ expect(p('./abc/def').normalized_pattern).to eq('abc/def')
+ expect(p('./abc/def').exact_path).to eq('abc/def')
+ expect(p('./abc/def').match?('abc/def')).to be_truthy
+ expect(p('/.').normalized_pattern).to eq('/')
+ expect(p('/.').exact_path).to eq('/')
+ expect(p('/.').match?('/')).to be_truthy
end
it 'handles dot by itself', :pending => "decide what to do with dot by itself" do
- p('.').normalized_pattern.should == '.'
- p('.').exact_path.should == '.'
- p('.').match?('.').should be_true
- p('./').normalized_pattern.should == '.'
- p('./').exact_path.should == '.'
- p('./').match?('.').should be_true
+ expect(p('.').normalized_pattern).to eq('.')
+ expect(p('.').exact_path).to eq('.')
+ expect(p('.').match?('.')).to be_truthy
+ expect(p('./').normalized_pattern).to eq('.')
+ expect(p('./').exact_path).to eq('.')
+ expect(p('./').match?('.')).to be_truthy
end
it 'handles dotdot' do
- p('abc/../def').normalized_pattern.should == 'def'
- p('abc/../def').exact_path.should == 'def'
- p('abc/../def').match?('def').should be_true
- p('abc/def/../..').normalized_pattern.should == ''
- p('abc/def/../..').exact_path.should == ''
- p('abc/def/../..').match?('').should be_true
- p('/*/../def').normalized_pattern.should == '/def'
- p('/*/../def').exact_path.should == '/def'
- p('/*/../def').match?('/def').should be_true
- p('/*/*/../def').normalized_pattern.should == '/*/def'
- p('/*/*/../def').exact_path.should be_nil
- p('/*/*/../def').match?('/abc/def').should be_true
- p('/abc/def/../..').normalized_pattern.should == '/'
- p('/abc/def/../..').exact_path.should == '/'
- p('/abc/def/../..').match?('/').should be_true
- p('abc/../../def').normalized_pattern.should == '../def'
- p('abc/../../def').exact_path.should == '../def'
- p('abc/../../def').match?('../def').should be_true
+ expect(p('abc/../def').normalized_pattern).to eq('def')
+ expect(p('abc/../def').exact_path).to eq('def')
+ expect(p('abc/../def').match?('def')).to be_truthy
+ expect(p('abc/def/../..').normalized_pattern).to eq('')
+ expect(p('abc/def/../..').exact_path).to eq('')
+ expect(p('abc/def/../..').match?('')).to be_truthy
+ expect(p('/*/../def').normalized_pattern).to eq('/def')
+ expect(p('/*/../def').exact_path).to eq('/def')
+ expect(p('/*/../def').match?('/def')).to be_truthy
+ expect(p('/*/*/../def').normalized_pattern).to eq('/*/def')
+ expect(p('/*/*/../def').exact_path).to be_nil
+ expect(p('/*/*/../def').match?('/abc/def')).to be_truthy
+ expect(p('/abc/def/../..').normalized_pattern).to eq('/')
+ expect(p('/abc/def/../..').exact_path).to eq('/')
+ expect(p('/abc/def/../..').match?('/')).to be_truthy
+ expect(p('abc/../../def').normalized_pattern).to eq('../def')
+ expect(p('abc/../../def').exact_path).to eq('../def')
+ expect(p('abc/../../def').match?('../def')).to be_truthy
end
it 'handles dotdot with double star' do
- p('abc**/def/../ghi').exact_path.should be_nil
- p('abc**/def/../ghi').match?('abc/ghi').should be_true
- p('abc**/def/../ghi').match?('abc/x/y/z/ghi').should be_true
- p('abc**/def/../ghi').match?('ghi').should be_false
+ expect(p('abc**/def/../ghi').exact_path).to be_nil
+ expect(p('abc**/def/../ghi').match?('abc/ghi')).to be_truthy
+ expect(p('abc**/def/../ghi').match?('abc/x/y/z/ghi')).to be_truthy
+ expect(p('abc**/def/../ghi').match?('ghi')).to be_falsey
end
it 'raises error on dotdot with overlapping double star' do
- lambda { Chef::ChefFS::FilePattern.new('abc/**/../def').exact_path }.should raise_error(ArgumentError)
- lambda { Chef::ChefFS::FilePattern.new('abc/**/abc/../../def').exact_path }.should raise_error(ArgumentError)
+ expect { Chef::ChefFS::FilePattern.new('abc/**/../def').exact_path }.to raise_error(ArgumentError)
+ expect { Chef::ChefFS::FilePattern.new('abc/**/abc/../../def').exact_path }.to raise_error(ArgumentError)
end
it 'handles leading dotdot' do
- p('../abc/def').exact_path.should == '../abc/def'
- p('../abc/def').match?('../abc/def').should be_true
- p('/../abc/def').exact_path.should == '/abc/def'
- p('/../abc/def').match?('/abc/def').should be_true
- p('..').exact_path.should == '..'
- p('..').match?('..').should be_true
- p('/..').exact_path.should == '/'
- p('/..').match?('/').should be_true
+ expect(p('../abc/def').exact_path).to eq('../abc/def')
+ expect(p('../abc/def').match?('../abc/def')).to be_truthy
+ expect(p('/../abc/def').exact_path).to eq('/abc/def')
+ expect(p('/../abc/def').match?('/abc/def')).to be_truthy
+ expect(p('..').exact_path).to eq('..')
+ expect(p('..').match?('..')).to be_truthy
+ expect(p('/..').exact_path).to eq('/')
+ expect(p('/..').match?('/')).to be_truthy
end
end
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 570246c41f..142755a4f1 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
@@ -27,20 +27,20 @@ describe Chef::ChefFS::FileSystem::OperationFailedError do
it 'include error cause' do
allow_message_expectations_on_nil
response_body = '{"error":["Invalid key test in request body"]}'
- @response.stub(:code).and_return("400")
- @response.stub(:body).and_return(response_body)
+ allow(@response).to receive(:code).and_return("400")
+ allow(@response).to receive(:body).and_return(response_body)
exception = Net::HTTPServerException.new("(exception) unauthorized", @response)
- proc {
+ expect {
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:write, self, exception), error_message
- }.should raise_error(Chef::ChefFS::FileSystem::OperationFailedError, "#{error_message} cause: #{response_body}")
+ }.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
- proc {
+ expect {
raise Chef::ChefFS::FileSystem::OperationFailedError.new(:write, self), error_message
- }.should raise_error(Chef::ChefFS::FileSystem::OperationFailedError, error_message)
+ }.to raise_error(Chef::ChefFS::FileSystem::OperationFailedError, error_message)
end
end
end
diff --git a/spec/unit/chef_fs/file_system_spec.rb b/spec/unit/chef_fs/file_system_spec.rb
index 383a2c81ab..75ca4d4be9 100644
--- a/spec/unit/chef_fs/file_system_spec.rb
+++ b/spec/unit/chef_fs/file_system_spec.rb
@@ -43,13 +43,13 @@ describe Chef::ChefFS::FileSystem do
context 'resolve_path' do
it '/' do
- Chef::ChefFS::FileSystem.resolve_path(fs, '/').path.should == '/'
+ expect(Chef::ChefFS::FileSystem.resolve_path(fs, '/').path).to eq('/')
end
it 'nonexistent /a' do
- Chef::ChefFS::FileSystem.resolve_path(fs, '/a').path.should == '/a'
+ expect(Chef::ChefFS::FileSystem.resolve_path(fs, '/a').path).to eq('/a')
end
it 'nonexistent /a/b' do
- Chef::ChefFS::FileSystem.resolve_path(fs, '/a/b').path.should == '/a/b'
+ expect(Chef::ChefFS::FileSystem.resolve_path(fs, '/a/b').path).to eq('/a/b')
end
end
end
@@ -66,18 +66,19 @@ describe Chef::ChefFS::FileSystem do
:c => '',
}
},
- :x => ''
+ :x => '',
+ :y => {}
})
}
context 'list' do
it '/**' do
- list_should_yield_paths(fs, '/**', '/', '/a', '/x', '/a/aa', '/a/aa/c', '/a/aa/zz', '/a/ab', '/a/ab/c')
+ list_should_yield_paths(fs, '/**', '/', '/a', '/x', '/y', '/a/aa', '/a/aa/c', '/a/aa/zz', '/a/ab', '/a/ab/c')
end
it '/' do
list_should_yield_paths(fs, '/', '/')
end
it '/*' do
- list_should_yield_paths(fs, '/*', '/', '/a', '/x')
+ list_should_yield_paths(fs, '/*', '/', '/a', '/x', '/y')
end
it '/*/*' do
list_should_yield_paths(fs, '/*/*', '/a/aa', '/a/ab')
@@ -113,22 +114,34 @@ describe Chef::ChefFS::FileSystem do
no_blocking_calls_allowed
end
it 'resolves /' do
- Chef::ChefFS::FileSystem.resolve_path(fs, '/').path.should == '/'
+ expect(Chef::ChefFS::FileSystem.resolve_path(fs, '/').path).to eq('/')
end
it 'resolves /x' do
- Chef::ChefFS::FileSystem.resolve_path(fs, '/x').path.should == '/x'
+ expect(Chef::ChefFS::FileSystem.resolve_path(fs, '/x').path).to eq('/x')
end
it 'resolves /a' do
- Chef::ChefFS::FileSystem.resolve_path(fs, '/a').path.should == '/a'
+ expect(Chef::ChefFS::FileSystem.resolve_path(fs, '/a').path).to eq('/a')
end
it 'resolves /a/aa' do
- Chef::ChefFS::FileSystem.resolve_path(fs, '/a/aa').path.should == '/a/aa'
+ expect(Chef::ChefFS::FileSystem.resolve_path(fs, '/a/aa').path).to eq('/a/aa')
end
it 'resolves /a/aa/zz' do
- Chef::ChefFS::FileSystem.resolve_path(fs, '/a/aa/zz').path.should == '/a/aa/zz'
+ expect(Chef::ChefFS::FileSystem.resolve_path(fs, '/a/aa/zz').path).to eq('/a/aa/zz')
end
- it 'resolves nonexistent /y/x/w' do
- Chef::ChefFS::FileSystem.resolve_path(fs, '/y/x/w').path.should == '/y/x/w'
+ it 'resolves nonexistent /q/x/w' do
+ expect(Chef::ChefFS::FileSystem.resolve_path(fs, '/q/x/w').path).to eq('/q/x/w')
+ end
+ end
+
+ context 'empty?' do
+ it 'is not empty /' do
+ expect(Chef::ChefFS::FileSystem.resolve_path(fs, '/').empty?).to be false
+ end
+ it 'is empty /y' do
+ expect(Chef::ChefFS::FileSystem.resolve_path(fs, '/y').empty?).to be true
+ end
+ it 'is not a directory and can\'t be tested /x' do
+ expect { Chef::ChefFS::FileSystem.resolve_path(fs, '/x').empty? }.to raise_error(NoMethodError)
end
end
end
diff --git a/spec/unit/chef_fs/parallelizer.rb b/spec/unit/chef_fs/parallelizer.rb
index a871b60e98..9cb97963ed 100644
--- a/spec/unit/chef_fs/parallelizer.rb
+++ b/spec/unit/chef_fs/parallelizer.rb
@@ -29,8 +29,8 @@ describe Chef::ChefFS::Parallelizer do
sleep val
outputs << val
end
- elapsed_time.should < 0.6
- outputs.should == [ 0.1, 0.3, 0.5 ]
+ expect(elapsed_time).to be < 0.6
+ expect(outputs).to eq([ 0.1, 0.3, 0.5 ])
end
context "With :ordered => false (unordered output)" do
@@ -38,15 +38,15 @@ describe Chef::ChefFS::Parallelizer do
parallelize([], :ordered => false) do
sleep 10
end.to_a == []
- elapsed_time.should < 0.1
+ expect(elapsed_time).to be < 0.1
end
it "10 sleep(0.2)s complete within 0.5 seconds" do
- parallelize(1.upto(10), :ordered => false) do |i|
+ expect(parallelize(1.upto(10), :ordered => false) do |i|
sleep 0.2
'x'
- end.to_a.should == %w(x x x x x x x x x x)
- elapsed_time.should < 0.5
+ end.to_a).to eq(%w(x x x x x x x x x x))
+ expect(elapsed_time).to be < 0.5
end
it "The output comes as soon as it is available" do
@@ -54,10 +54,10 @@ describe Chef::ChefFS::Parallelizer do
sleep val
val
end
- enum.map do |value|
- elapsed_time.should < value+0.1
+ expect(enum.map do |value|
+ expect(elapsed_time).to be < value+0.1
value
- end.should == [ 0.1, 0.3, 0.5 ]
+ end).to eq([ 0.1, 0.3, 0.5 ])
end
it "An exception in input is passed through but does NOT stop processing" do
@@ -67,8 +67,8 @@ describe Chef::ChefFS::Parallelizer do
enum = parallelize(input, :ordered => false) { |x| sleep(x); x }
results = []
expect { enum.each { |value| results << value } }.to raise_error 'hi'
- results.should == [ 0.1, 0.3, 0.5 ]
- elapsed_time.should < 0.6
+ expect(results).to eq([ 0.1, 0.3, 0.5 ])
+ expect(elapsed_time).to be < 0.6
end
it "Exceptions in output are raised after all processing is done" do
@@ -84,9 +84,9 @@ describe Chef::ChefFS::Parallelizer do
end
results = []
expect { enum.each { |value| results << value } }.to raise_error 'hi'
- results.sort.should == [ 1, 2, 3 ]
- elapsed_time.should < 0.3
- processed.should == 3
+ expect(results.sort).to eq([ 1, 2, 3 ])
+ expect(elapsed_time).to be < 0.3
+ expect(processed).to eq(3)
end
it "Exceptions with :stop_on_exception are raised after all processing is done" do
@@ -101,7 +101,7 @@ describe Chef::ChefFS::Parallelizer do
x
end
expect { parallelized.to_a }.to raise_error 'hi'
- processed.should == 4
+ expect(processed).to eq(4)
end
end
@@ -110,15 +110,15 @@ describe Chef::ChefFS::Parallelizer do
parallelize([]) do
sleep 10
end.to_a == []
- elapsed_time.should < 0.1
+ expect(elapsed_time).to be < 0.1
end
it "10 sleep(0.2)s complete within 0.5 seconds" do
- parallelize(1.upto(10), :ordered => true) do |i|
+ expect(parallelize(1.upto(10), :ordered => true) do |i|
sleep 0.2
'x'
- end.to_a.should == %w(x x x x x x x x x x)
- elapsed_time.should < 0.5
+ end.to_a).to eq(%w(x x x x x x x x x x))
+ expect(elapsed_time).to be < 0.5
end
it "Output comes in the order of the input" do
@@ -126,10 +126,10 @@ describe Chef::ChefFS::Parallelizer do
sleep val
val
end.enum_for(:each_with_index)
- enum.next.should == [ 0.5, 0 ]
- enum.next.should == [ 0.3, 1 ]
- enum.next.should == [ 0.1, 2 ]
- elapsed_time.should < 0.6
+ expect(enum.next).to eq([ 0.5, 0 ])
+ expect(enum.next).to eq([ 0.3, 1 ])
+ expect(enum.next).to eq([ 0.1, 2 ])
+ expect(elapsed_time).to be < 0.6
end
it "Exceptions in input are raised in the correct sequence but do NOT stop processing" do
@@ -139,8 +139,8 @@ describe Chef::ChefFS::Parallelizer do
results = []
enum = parallelize(input) { |x| sleep(x); x }
expect { enum.each { |value| results << value } }.to raise_error 'hi'
- elapsed_time.should < 0.6
- results.should == [ 0.5, 0.3, 0.1 ]
+ expect(elapsed_time).to be < 0.6
+ expect(results).to eq([ 0.5, 0.3, 0.1 ])
end
it "Exceptions in output are raised in the correct sequence and running processes do NOT stop processing" do
@@ -156,9 +156,9 @@ describe Chef::ChefFS::Parallelizer do
end
results = []
expect { enum.each { |value| results << value } }.to raise_error 'hi'
- results.should == [ 1, 2 ]
- elapsed_time.should < 0.3
- processed.should == 3
+ expect(results).to eq([ 1, 2 ])
+ expect(elapsed_time).to be < 0.3
+ expect(processed).to eq(3)
end
it "Exceptions with :stop_on_exception are raised after all processing is done" do
@@ -173,7 +173,7 @@ describe Chef::ChefFS::Parallelizer do
x
end
expect { parallelized.to_a }.to raise_error 'hi'
- processed.should == 4
+ expect(processed).to eq(4)
end
end
@@ -187,10 +187,10 @@ describe Chef::ChefFS::Parallelizer do
sleep 0.1
end
enum = parallelize(input) { |x| x }
- enum.map do |value|
- elapsed_time.should < (value+1)*0.1
+ expect(enum.map do |value|
+ expect(elapsed_time).to be < (value+1)*0.1
value
- end.should == [ 1, 2, 3 ]
+ end).to eq([ 1, 2, 3 ])
end
end
@@ -226,44 +226,44 @@ describe Chef::ChefFS::Parallelizer do
end
it "parallelize with :main_thread_processing = true does not block" do
- parallelizer.parallelize([1]) do |x|
+ expect(parallelizer.parallelize([1]) do |x|
sleep(0.1)
x
- end.to_a.should == [ 1 ]
- elapsed_time.should < 0.2
+ end.to_a).to eq([ 1 ])
+ expect(elapsed_time).to be < 0.2
end
it "parallelize with :main_thread_processing = false waits for the job to finish" do
- parallelizer.parallelize([1], :main_thread_processing => false) do |x|
+ expect(parallelizer.parallelize([1], :main_thread_processing => false) do |x|
sleep(0.1)
x+1
- end.to_a.should == [ 2 ]
- elapsed_time.should > 0.3
+ end.to_a).to eq([ 2 ])
+ expect(elapsed_time).to be > 0.3
end
it "resizing the Parallelizer to 0 waits for the job to stop" do
- elapsed_time.should < 0.2
+ expect(elapsed_time).to be < 0.2
parallelizer.resize(0)
- parallelizer.num_threads.should == 0
- elapsed_time.should > 0.25
- @occupying_job_finished.should == [ true ]
+ expect(parallelizer.num_threads).to eq(0)
+ expect(elapsed_time).to be > 0.25
+ expect(@occupying_job_finished).to eq([ true ])
end
it "stopping the Parallelizer waits for the job to finish" do
- elapsed_time.should < 0.2
+ expect(elapsed_time).to be < 0.2
parallelizer.stop
- parallelizer.num_threads.should == 0
- elapsed_time.should > 0.25
- @occupying_job_finished.should == [ true ]
+ expect(parallelizer.num_threads).to eq(0)
+ expect(elapsed_time).to be > 0.25
+ expect(@occupying_job_finished).to eq([ true ])
end
it "resizing the Parallelizer to 2 does not stop the job" do
- elapsed_time.should < 0.2
+ expect(elapsed_time).to be < 0.2
parallelizer.resize(2)
- parallelizer.num_threads.should == 2
- elapsed_time.should < 0.2
+ expect(parallelizer.num_threads).to eq(2)
+ expect(elapsed_time).to be < 0.2
sleep(0.3)
- @occupying_job_finished.should == [ true ]
+ expect(@occupying_job_finished).to eq([ true ])
end
end
@@ -276,9 +276,9 @@ describe Chef::ChefFS::Parallelizer do
sleep(0.05) # Just enough to yield and get other inputs in the queue
x
end
- enum.count.should == 6
- outputs_processed.should == 0
- input_mapper.num_processed.should == 6
+ expect(enum.count).to eq(6)
+ expect(outputs_processed).to eq(0)
+ expect(input_mapper.num_processed).to eq(6)
end
it ".count with arguments works normally" do
@@ -288,10 +288,10 @@ describe Chef::ChefFS::Parallelizer do
outputs_processed += 1
x
end
- enum.count { |x| x > 1 }.should == 6
- enum.count(2).should == 3
- outputs_processed.should == 20
- input_mapper.num_processed.should == 20
+ expect(enum.count { |x| x > 1 }).to eq(6)
+ expect(enum.count(2)).to eq(3)
+ expect(outputs_processed).to eq(20)
+ expect(input_mapper.num_processed).to eq(20)
end
it ".first does not enumerate anything other than the first result(s)" do
@@ -302,10 +302,10 @@ describe Chef::ChefFS::Parallelizer do
sleep(0.05) # Just enough to yield and get other inputs in the queue
x
end
- enum.first.should == 1
- enum.first(2).should == [1,2]
- outputs_processed.should == 3
- input_mapper.num_processed.should == 3
+ expect(enum.first).to eq(1)
+ expect(enum.first(2)).to eq([1,2])
+ expect(outputs_processed).to eq(3)
+ expect(input_mapper.num_processed).to eq(3)
end
it ".take does not enumerate anything other than the first result(s)" do
@@ -316,9 +316,9 @@ describe Chef::ChefFS::Parallelizer do
sleep(0.05) # Just enough to yield and get other inputs in the queue
x
end
- enum.take(2).should == [1,2]
- outputs_processed.should == 2
- input_mapper.num_processed.should == 2
+ expect(enum.take(2)).to eq([1,2])
+ expect(outputs_processed).to eq(2)
+ expect(input_mapper.num_processed).to eq(2)
end
it ".drop does not process anything other than the last result(s)" do
@@ -329,9 +329,9 @@ describe Chef::ChefFS::Parallelizer do
sleep(0.05) # Just enough to yield and get other inputs in the queue
x
end
- enum.drop(2).should == [3,4,5,6]
- outputs_processed.should == 4
- input_mapper.num_processed.should == 6
+ expect(enum.drop(2)).to eq([3,4,5,6])
+ expect(outputs_processed).to eq(4)
+ expect(input_mapper.num_processed).to eq(6)
end
if Enumerable.method_defined?(:lazy)
@@ -343,9 +343,9 @@ describe Chef::ChefFS::Parallelizer do
sleep(0.05) # Just enough to yield and get other inputs in the queue
x
end
- enum.lazy.take(2).to_a.should == [1,2]
- outputs_processed.should == 2
- input_mapper.num_processed.should == 2
+ expect(enum.lazy.take(2).to_a).to eq([1,2])
+ expect(outputs_processed).to eq(2)
+ expect(input_mapper.num_processed).to eq(2)
end
it ".drop does not process anything other than the last result(s)" do
@@ -356,9 +356,9 @@ describe Chef::ChefFS::Parallelizer do
sleep(0.05) # Just enough to yield and get other inputs in the queue
x
end
- enum.lazy.drop(2).to_a.should == [3,4,5,6]
- outputs_processed.should == 4
- input_mapper.num_processed.should == 6
+ expect(enum.lazy.drop(2).to_a).to eq([3,4,5,6])
+ expect(outputs_processed).to eq(4)
+ expect(input_mapper.num_processed).to eq(6)
end
it "lazy enumerable is actually lazy" do
@@ -372,8 +372,8 @@ describe Chef::ChefFS::Parallelizer do
enum.lazy.take(2)
enum.lazy.drop(2)
sleep(0.1)
- outputs_processed.should == 0
- input_mapper.num_processed.should == 0
+ expect(outputs_processed).to eq(0)
+ expect(input_mapper.num_processed).to eq(0)
end
end
end
@@ -386,10 +386,10 @@ describe Chef::ChefFS::Parallelizer do
outputs_processed += 1
x
end
- enum.map { |x| x }.should == [1,2,3]
- enum.map { |x| x }.should == [1,2,3]
- outputs_processed.should == 6
- input_mapper.num_processed.should == 6
+ expect(enum.map { |x| x }).to eq([1,2,3])
+ expect(enum.map { |x| x }).to eq([1,2,3])
+ expect(outputs_processed).to eq(6)
+ expect(input_mapper.num_processed).to eq(6)
end
it ".first and then .map on the same parallel enumerable returns the correct results and re-processes the input" do
@@ -399,10 +399,10 @@ describe Chef::ChefFS::Parallelizer do
outputs_processed += 1
x
end
- enum.first.should == 1
- enum.map { |x| x }.should == [1,2,3]
- outputs_processed.should >= 4
- input_mapper.num_processed.should >= 4
+ expect(enum.first).to eq(1)
+ expect(enum.map { |x| x }).to eq([1,2,3])
+ expect(outputs_processed).to be >= 4
+ expect(input_mapper.num_processed).to be >= 4
end
it "two simultaneous enumerations throws an exception" do
@@ -424,7 +424,7 @@ describe Chef::ChefFS::Parallelizer do
context "And main_thread_processing on" do
it "succeeds in running" do
- parallelizer.parallelize([0.5]) { |x| x*2 }.to_a.should == [1]
+ expect(parallelizer.parallelize([0.5]) { |x| x*2 }.to_a).to eq([1])
end
end
end
@@ -435,11 +435,11 @@ describe Chef::ChefFS::Parallelizer do
end
it "does not have contention issues with large numbers of inputs" do
- parallelizer.parallelize(1.upto(500)) { |x| x+1 }.to_a.should == 2.upto(501).to_a
+ expect(parallelizer.parallelize(1.upto(500)) { |x| x+1 }.to_a).to eq(2.upto(501).to_a)
end
it "does not have contention issues with large numbers of inputs with ordering off" do
- parallelizer.parallelize(1.upto(500), :ordered => false) { |x| x+1 }.to_a.sort.should == 2.upto(501).to_a
+ expect(parallelizer.parallelize(1.upto(500), :ordered => false) { |x| x+1 }.to_a.sort).to eq(2.upto(501).to_a)
end
it "does not have contention issues with large numbers of jobs and inputs with ordering off" do
@@ -451,7 +451,7 @@ describe Chef::ChefFS::Parallelizer do
Thread.new { outputs[i] = parallelizers[i].to_a }
end
threads.each { |thread| thread.join }
- outputs.each { |output| output.sort.should == 2.upto(501).to_a }
+ outputs.each { |output| expect(output.sort).to eq(2.upto(501).to_a) }
end
end
diff --git a/spec/unit/chef_spec.rb b/spec/unit/chef_spec.rb
index b0f0359806..8a8d6c6c68 100644
--- a/spec/unit/chef_spec.rb
+++ b/spec/unit/chef_spec.rb
@@ -20,6 +20,6 @@ require 'spec_helper'
describe Chef do
it "should have a version defined" do
- Chef::VERSION.should match(/(\d+)\.(\d+)\.(\d+)/)
+ expect(Chef::VERSION).to match(/(\d+)\.(\d+)\.(\d+)/)
end
end
diff --git a/spec/unit/client_spec.rb b/spec/unit/client_spec.rb
index e03773ae03..2ec32b32ac 100644
--- a/spec/unit/client_spec.rb
+++ b/spec/unit/client_spec.rb
@@ -44,7 +44,7 @@ describe Chef::Client do
ohai_system = double( "Ohai::System",
:all_plugins => true,
:data => ohai_data)
- ohai_system.stub(:[]) do |key|
+ allow(ohai_system).to receive(:[]) do |key|
ohai_data[key]
end
ohai_system
@@ -72,7 +72,7 @@ describe Chef::Client do
# Node/Ohai data
#Chef::Config[:node_name] = fqdn
- Ohai::System.stub(:new).and_return(ohai_system)
+ allow(Ohai::System).to receive(:new).and_return(ohai_system)
end
describe "authentication protocol selection" do
@@ -85,7 +85,7 @@ describe Chef::Client do
Chef::Config[:node_name] = ("f" * 90)
# ugly that this happens as a side effect of a getter :(
client.node_name
- Chef::Config[:authentication_protocol_version].should == "1.0"
+ expect(Chef::Config[:authentication_protocol_version]).to eq("1.0")
end
end
@@ -94,7 +94,7 @@ describe Chef::Client do
Chef::Config[:node_name] = ("f" * 91)
# ugly that this happens as a side effect of a getter :(
client.node_name
- Chef::Config[:authentication_protocol_version].should == "1.1"
+ expect(Chef::Config[:authentication_protocol_version]).to eq("1.1")
end
end
end
@@ -104,11 +104,11 @@ describe Chef::Client do
context "and STDOUT is a TTY" do
before do
- STDOUT.stub(:tty?).and_return(true)
+ allow(STDOUT).to receive(:tty?).and_return(true)
end
it "configures the :doc formatter" do
- client.formatters_for_run.should == [[:doc]]
+ expect(client.formatters_for_run).to eq([[:doc]])
end
context "and force_logger is set" do
@@ -117,8 +117,8 @@ describe Chef::Client do
end
it "configures the :null formatter" do
- Chef::Config[:force_logger].should be_true
- client.formatters_for_run.should == [[:null]]
+ expect(Chef::Config[:force_logger]).to be_truthy
+ expect(client.formatters_for_run).to eq([[:null]])
end
end
@@ -127,11 +127,11 @@ describe Chef::Client do
context "and STDOUT is not a TTY" do
before do
- STDOUT.stub(:tty?).and_return(false)
+ allow(STDOUT).to receive(:tty?).and_return(false)
end
it "configures the :null formatter" do
- client.formatters_for_run.should == [[:null]]
+ expect(client.formatters_for_run).to eq([[:null]])
end
context "and force_formatter is set" do
@@ -139,7 +139,7 @@ describe Chef::Client do
Chef::Config[:force_formatter] = true
end
it "it configures the :doc formatter" do
- client.formatters_for_run.should == [[:doc]]
+ expect(client.formatters_for_run).to eq([[:doc]])
end
end
end
@@ -153,14 +153,14 @@ describe Chef::Client do
end
it "does not configure a default formatter" do
- client.formatters_for_run.should == [[:min, nil]]
+ expect(client.formatters_for_run).to eq([[:min, nil]])
end
it "configures the formatter for STDOUT/STDERR" do
configured_formatters = client.configure_formatters
min_formatter = configured_formatters[0]
- min_formatter.output.out.should == STDOUT
- min_formatter.output.err.should == STDERR
+ expect(min_formatter.output.out).to eq(STDOUT)
+ expect(min_formatter.output.err).to eq(STDERR)
end
end
@@ -178,8 +178,8 @@ describe Chef::Client do
it "configures the formatter for the file path" do
configured_formatters = client.configure_formatters
min_formatter = configured_formatters[0]
- min_formatter.output.out.path.should == @tmpout.path
- min_formatter.output.err.path.should == @tmpout.path
+ expect(min_formatter.output.out.path).to eq(@tmpout.path)
+ expect(min_formatter.output.err.path).to eq(@tmpout.path)
end
end
@@ -187,11 +187,12 @@ describe Chef::Client do
end
describe "a full client run" do
- shared_examples_for "a successful client run" do
+ shared_context "a client run" do
let(:http_node_load) { double("Chef::REST (node)") }
let(:http_cookbook_sync) { double("Chef::REST (cookbook sync)") }
let(:http_node_save) { double("Chef::REST (node save)") }
let(:runner) { double("Chef::Runner") }
+ let(:audit_runner) { instance_double("Chef::Audit::Runner", :failed? => false) }
let(:api_client_exists?) { false }
@@ -204,11 +205,15 @@ describe Chef::Client do
# --Client.register
# Make sure Client#register thinks the client key doesn't
# exist, so it tries to register and create one.
- File.should_receive(:exists?).with(Chef::Config[:client_key]).exactly(1).times.and_return(api_client_exists?)
+ allow(File).to receive(:exists?).and_call_original
+ expect(File).to receive(:exists?).
+ with(Chef::Config[:client_key]).
+ exactly(:once).
+ and_return(api_client_exists?)
unless api_client_exists?
# Client.register will register with the validation client name.
- Chef::ApiClient::Registration.any_instance.should_receive(:run)
+ expect_any_instance_of(Chef::ApiClient::Registration).to receive(:run)
end
end
@@ -216,64 +221,76 @@ describe Chef::Client do
# Client.register will then turn around create another
# Chef::REST object, this time with the client key it got from the
# previous step.
- Chef::REST.should_receive(:new).
+ expect(Chef::REST).to receive(:new).
with(Chef::Config[:chef_server_url], fqdn, Chef::Config[:client_key]).
- exactly(1).
+ exactly(:once).
and_return(http_node_load)
# --Client#build_node
# looks up the node, which we will return, then later saves it.
- Chef::Node.should_receive(:find_or_create).with(fqdn).and_return(node)
+ expect(Chef::Node).to receive(:find_or_create).with(fqdn).and_return(node)
# --ResourceReporter#node_load_completed
# gets a run id from the server for storing resource history
# (has its own tests, so stubbing it here.)
- Chef::ResourceReporter.any_instance.should_receive(:node_load_completed)
+ expect_any_instance_of(Chef::ResourceReporter).to receive(:node_load_completed)
end
def stub_for_sync_cookbooks
# --Client#setup_run_context
# ---Client#sync_cookbooks -- downloads the list of cookbooks to sync
#
- Chef::CookbookSynchronizer.any_instance.should_receive(:sync_cookbooks)
- Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_cookbook_sync)
- http_cookbook_sync.should_receive(:post).
+ expect_any_instance_of(Chef::CookbookSynchronizer).to receive(:sync_cookbooks)
+ expect(Chef::REST).to receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_cookbook_sync)
+ expect(http_cookbook_sync).to receive(:post).
with("environments/_default/cookbook_versions", {:run_list => []}).
and_return({})
end
def stub_for_converge
# --Client#converge
- Chef::Runner.should_receive(:new).and_return(runner)
- runner.should_receive(:converge).and_return(true)
+ expect(Chef::Runner).to receive(:new).and_return(runner)
+ expect(runner).to receive(:converge).and_return(true)
+ end
- # --ResourceReporter#run_completed
- # updates the server with the resource history
- # (has its own tests, so stubbing it here.)
- Chef::ResourceReporter.any_instance.should_receive(:run_completed)
+ def stub_for_audit
+ # -- Client#run_audits
+ expect(Chef::Audit::Runner).to receive(:new).and_return(audit_runner)
+ expect(audit_runner).to receive(:run).and_return(true)
end
def stub_for_node_save
- node.stub(:data_for_save).and_return(node.for_json)
+ allow(node).to receive(:data_for_save).and_return(node.for_json)
# --Client#save_updated_node
- Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_node_save)
- http_node_save.should_receive(:put_rest).with("nodes/#{fqdn}", node.for_json).and_return(true)
+ expect(Chef::REST).to receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_node_save)
+ expect(http_node_save).to receive(:put_rest).with("nodes/#{fqdn}", node.for_json).and_return(true)
end
def stub_for_run
- Chef::RunLock.any_instance.should_receive(:acquire)
- Chef::RunLock.any_instance.should_receive(:save_pid)
- Chef::RunLock.any_instance.should_receive(:release)
+ expect_any_instance_of(Chef::RunLock).to receive(:acquire)
+ expect_any_instance_of(Chef::RunLock).to receive(:save_pid)
+ expect_any_instance_of(Chef::RunLock).to receive(:release)
# Post conditions: check that node has been filled in correctly
- client.should_receive(:run_started)
- client.should_receive(:run_completed_successfully)
+ expect(client).to receive(:run_started)
+ expect(client).to receive(:run_completed_successfully)
+
+ # --ResourceReporter#run_completed
+ # updates the server with the resource history
+ # (has its own tests, so stubbing it here.)
+ expect_any_instance_of(Chef::ResourceReporter).to receive(:run_completed)
+ # --AuditReporter#run_completed
+ # posts the audit data to server.
+ # (has its own tests, so stubbing it here.)
+ expect_any_instance_of(Chef::Audit::AuditReporter).to receive(:run_completed)
end
before do
Chef::Config[:client_fork] = enable_fork
Chef::Config[:cache_path] = windows? ? 'C:\chef' : '/var/chef'
+ Chef::Config[:why_run] = false
+ Chef::Config[:audit_mode] = :enabled
stub_const("Chef::Client::STDOUT_FD", stdout)
stub_const("Chef::Client::STDERR_FD", stderr)
@@ -282,30 +299,31 @@ describe Chef::Client do
stub_for_node_load
stub_for_sync_cookbooks
stub_for_converge
+ stub_for_audit
stub_for_node_save
stub_for_run
end
+ end
- it "runs ohai, sets up authentication, loads node state, synchronizes policy, and converges" do
+ shared_examples_for "a successful client run" do
+ include_context "a client run"
+
+ it "runs ohai, sets up authentication, loads node state, synchronizes policy, converges, and runs audits" do
# This is what we're testing.
client.run
# fork is stubbed, so we can see the outcome of the run
- node.automatic_attrs[:platform].should == "example-platform"
- node.automatic_attrs[:platform_version].should == "example-platform-1.0"
+ expect(node.automatic_attrs[:platform]).to eq("example-platform")
+ expect(node.automatic_attrs[:platform_version]).to eq("example-platform-1.0")
end
end
-
describe "when running chef-client without fork" do
-
include_examples "a successful client run"
end
describe "when the client key already exists" do
-
let(:api_client_exists?) { true }
-
include_examples "a successful client run"
end
@@ -321,30 +339,29 @@ describe Chef::Client do
before do
# Client will try to compile and run override_recipe
- Chef::RunContext::CookbookCompiler.any_instance.should_receive(:compile)
+ expect_any_instance_of(Chef::RunContext::CookbookCompiler).to receive(:compile)
end
def stub_for_sync_cookbooks
# --Client#setup_run_context
# ---Client#sync_cookbooks -- downloads the list of cookbooks to sync
#
- Chef::CookbookSynchronizer.any_instance.should_receive(:sync_cookbooks)
- Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_cookbook_sync)
- http_cookbook_sync.should_receive(:post).
+ expect_any_instance_of(Chef::CookbookSynchronizer).to receive(:sync_cookbooks)
+ expect(Chef::REST).to receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_cookbook_sync)
+ expect(http_cookbook_sync).to receive(:post).
with("environments/_default/cookbook_versions", {:run_list => ["override_recipe"]}).
and_return({})
end
def stub_for_node_save
# Expect NO node save
- node.should_not_receive(:save)
+ expect(node).not_to receive(:save)
end
end
end
end
describe "when a permanent run list is passed as an option" do
-
include_examples "a successful client run" do
let(:new_runlist) { "recipe[new_run_list_recipe]" }
@@ -354,9 +371,9 @@ describe Chef::Client do
# --Client#setup_run_context
# ---Client#sync_cookbooks -- downloads the list of cookbooks to sync
#
- Chef::CookbookSynchronizer.any_instance.should_receive(:sync_cookbooks)
- Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_cookbook_sync)
- http_cookbook_sync.should_receive(:post).
+ expect_any_instance_of(Chef::CookbookSynchronizer).to receive(:sync_cookbooks)
+ expect(Chef::REST).to receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_cookbook_sync)
+ expect(http_cookbook_sync).to receive(:post).
with("environments/_default/cookbook_versions", {:run_list => ["new_run_list_recipe"]}).
and_return({})
end
@@ -364,12 +381,161 @@ describe Chef::Client do
before do
# Client will try to compile and run the new_run_list_recipe, but we
# do not create a fixture for this.
- Chef::RunContext::CookbookCompiler.any_instance.should_receive(:compile)
+ expect_any_instance_of(Chef::RunContext::CookbookCompiler).to receive(:compile)
end
it "sets the new run list on the node" do
client.run
- node.run_list.should == Chef::RunList.new(new_runlist)
+ expect(node.run_list).to eq(Chef::RunList.new(new_runlist))
+ end
+ end
+ end
+
+ describe "when converge fails" do
+ include_context "a client run" do
+ let(:e) { Exception.new }
+ def stub_for_converge
+ expect(Chef::Runner).to receive(:new).and_return(runner)
+ expect(runner).to receive(:converge).and_raise(e)
+ expect(Chef::Application).to receive(:debug_stacktrace).with an_instance_of(Chef::Exceptions::RunFailedWrappingError)
+ end
+
+ def stub_for_node_save
+ expect(client).to_not receive(:save_updated_node)
+ end
+
+ def stub_for_run
+ expect_any_instance_of(Chef::RunLock).to receive(:acquire)
+ expect_any_instance_of(Chef::RunLock).to receive(:save_pid)
+ expect_any_instance_of(Chef::RunLock).to receive(:release)
+
+ # Post conditions: check that node has been filled in correctly
+ expect(client).to receive(:run_started)
+ expect(client).to receive(:run_failed)
+
+ expect_any_instance_of(Chef::ResourceReporter).to receive(:run_failed)
+ expect_any_instance_of(Chef::Audit::AuditReporter).to receive(:run_failed)
+ end
+ end
+
+ it "runs the audits and raises the error" do
+ expect{ client.run }.to raise_error(Chef::Exceptions::RunFailedWrappingError) do |error|
+ expect(error.wrapped_errors.size).to eq(1)
+ expect(error.wrapped_errors[0]).to eq(e)
+ end
+ end
+ end
+
+ describe "when the audit phase fails" do
+ context "with an exception" do
+ include_context "a client run" do
+ let(:e) { Exception.new }
+ def stub_for_audit
+ expect(Chef::Audit::Runner).to receive(:new).and_return(audit_runner)
+ expect(audit_runner).to receive(:run).and_raise(e)
+ expect(Chef::Application).to receive(:debug_stacktrace).with an_instance_of(Chef::Exceptions::RunFailedWrappingError)
+ end
+
+ def stub_for_run
+ expect_any_instance_of(Chef::RunLock).to receive(:acquire)
+ expect_any_instance_of(Chef::RunLock).to receive(:save_pid)
+ expect_any_instance_of(Chef::RunLock).to receive(:release)
+
+ # Post conditions: check that node has been filled in correctly
+ expect(client).to receive(:run_started)
+ expect(client).to receive(:run_failed)
+
+ expect_any_instance_of(Chef::ResourceReporter).to receive(:run_failed)
+ expect_any_instance_of(Chef::Audit::AuditReporter).to receive(:run_failed)
+ end
+ end
+
+ it "should save the node after converge and raise exception" do
+ expect{ client.run }.to raise_error(Chef::Exceptions::RunFailedWrappingError) do |error|
+ expect(error.wrapped_errors.size).to eq(1)
+ expect(error.wrapped_errors[0]).to eq(e)
+ end
+ end
+ end
+
+ context "with failed audits" do
+ include_context "a client run" do
+ let(:audit_runner) do
+ instance_double("Chef::Audit::Runner", :run => true, :failed? => true, :num_failed => 1, :num_total => 1)
+ end
+
+ def stub_for_audit
+ expect(Chef::Audit::Runner).to receive(:new).and_return(audit_runner)
+ expect(Chef::Application).to receive(:debug_stacktrace).with an_instance_of(Chef::Exceptions::RunFailedWrappingError)
+ end
+
+ def stub_for_run
+ expect_any_instance_of(Chef::RunLock).to receive(:acquire)
+ expect_any_instance_of(Chef::RunLock).to receive(:save_pid)
+ expect_any_instance_of(Chef::RunLock).to receive(:release)
+
+ # Post conditions: check that node has been filled in correctly
+ expect(client).to receive(:run_started)
+ expect(client).to receive(:run_failed)
+
+ expect_any_instance_of(Chef::ResourceReporter).to receive(:run_failed)
+ expect_any_instance_of(Chef::Audit::AuditReporter).to receive(:run_failed)
+ end
+ end
+
+ it "should save the node after converge and raise exception" do
+ expect{ client.run }.to raise_error(Chef::Exceptions::RunFailedWrappingError) do |error|
+ expect(error.wrapped_errors.size).to eq(1)
+ expect(error.wrapped_errors[0]).to be_instance_of(Chef::Exceptions::AuditsFailed)
+ end
+ end
+ end
+ end
+
+ describe "when why_run mode is enabled" do
+ include_context "a client run" do
+
+ before do
+ Chef::Config[:why_run] = true
+ end
+
+ def stub_for_audit
+ expect(Chef::Audit::Runner).to_not receive(:new)
+ end
+
+ def stub_for_node_save
+ # This is how we should be mocking external calls - not letting it fall all the way through to the
+ # REST call
+ expect(node).to receive(:save)
+ end
+
+ it "runs successfully without enabling the audit runner" do
+ client.run
+
+ # fork is stubbed, so we can see the outcome of the run
+ expect(node.automatic_attrs[:platform]).to eq("example-platform")
+ expect(node.automatic_attrs[:platform_version]).to eq("example-platform-1.0")
+ end
+ end
+ end
+
+ describe "when audits are disabled" do
+ include_context "a client run" do
+
+ before do
+ Chef::Config[:audit_mode] = :disabled
+ end
+
+ def stub_for_audit
+ expect(Chef::Audit::Runner).to_not receive(:new)
+ end
+
+ it "runs successfully without enabling the audit runner" do
+ client.run
+
+ # fork is stubbed, so we can see the outcome of the run
+ expect(node.automatic_attrs[:platform]).to eq("example-platform")
+ expect(node.automatic_attrs[:platform_version]).to eq("example-platform-1.0")
end
end
end
@@ -381,23 +547,23 @@ describe Chef::Client do
it "should remove the run_lock on failure of #load_node" do
@run_lock = double("Chef::RunLock", :acquire => true)
- Chef::RunLock.stub(:new).and_return(@run_lock)
+ allow(Chef::RunLock).to receive(:new).and_return(@run_lock)
@events = double("Chef::EventDispatch::Dispatcher").as_null_object
- Chef::EventDispatch::Dispatcher.stub(:new).and_return(@events)
+ allow(Chef::EventDispatch::Dispatcher).to receive(:new).and_return(@events)
# @events is created on Chef::Client.new, so we need to recreate it after mocking
client = Chef::Client.new
- client.stub(:load_node).and_raise(Exception)
- @run_lock.should_receive(:release)
- lambda { client.run }.should raise_error(Exception)
+ allow(client).to receive(:load_node).and_raise(Exception)
+ expect(@run_lock).to receive(:release)
+ expect { client.run }.to raise_error(Exception)
end
end
describe "when notifying other objects of the status of the chef run" do
before do
Chef::Client.clear_notifications
- Chef::Node.stub(:find_or_create).and_return(node)
- node.stub(:save)
+ allow(Chef::Node).to receive(:find_or_create).and_return(node)
+ allow(node).to receive(:save)
client.load_node
client.build_node
end
@@ -405,34 +571,34 @@ describe Chef::Client do
it "notifies observers that the run has started" do
notified = false
Chef::Client.when_run_starts do |run_status|
- run_status.node.should == node
+ expect(run_status.node).to eq(node)
notified = true
end
client.run_started
- notified.should be_true
+ expect(notified).to be_truthy
end
it "notifies observers that the run has completed successfully" do
notified = false
Chef::Client.when_run_completes_successfully do |run_status|
- run_status.node.should == node
+ expect(run_status.node).to eq(node)
notified = true
end
client.run_completed_successfully
- notified.should be_true
+ expect(notified).to be_truthy
end
it "notifies observers that the run failed" do
notified = false
Chef::Client.when_run_fails do |run_status|
- run_status.node.should == node
+ expect(run_status.node).to eq(node)
notified = true
end
client.run_failed
- notified.should be_true
+ expect(notified).to be_truthy
end
end
@@ -446,73 +612,73 @@ describe Chef::Client do
# build_node will call Node#expand! with server, which will
# eventually hit the server to expand the included role.
mock_chef_rest = double("Chef::REST")
- mock_chef_rest.should_receive(:get_rest).with("roles/role_containing_cookbook1").and_return(role_containing_cookbook1)
- Chef::REST.should_receive(:new).and_return(mock_chef_rest)
+ expect(mock_chef_rest).to receive(:get_rest).with("roles/role_containing_cookbook1").and_return(role_containing_cookbook1)
+ expect(Chef::REST).to receive(:new).and_return(mock_chef_rest)
# check pre-conditions.
- node[:roles].should be_nil
- node[:recipes].should be_nil
+ expect(node[:roles]).to be_nil
+ expect(node[:recipes]).to be_nil
- client.policy_builder.stub(:node).and_return(node)
+ allow(client.policy_builder).to receive(:node).and_return(node)
# chefspec and possibly others use the return value of this method
- client.build_node.should == node
+ expect(client.build_node).to eq(node)
# check post-conditions.
- node[:roles].should_not be_nil
- node[:roles].length.should == 1
- node[:roles].should include("role_containing_cookbook1")
- node[:recipes].should_not be_nil
- node[:recipes].length.should == 1
- node[:recipes].should include("cookbook1")
+ expect(node[:roles]).not_to be_nil
+ expect(node[:roles].length).to eq(1)
+ expect(node[:roles]).to include("role_containing_cookbook1")
+ expect(node[:recipes]).not_to be_nil
+ expect(node[:recipes].length).to eq(1)
+ expect(node[:recipes]).to include("cookbook1")
end
it "should set the environment from the specified configuration value" do
- node.chef_environment.should == "_default"
+ expect(node.chef_environment).to eq("_default")
Chef::Config[:environment] = "A"
test_env = Chef::Environment.new
test_env.name("A")
mock_chef_rest = double("Chef::REST")
- mock_chef_rest.should_receive(:get_rest).with("environments/A").and_return(test_env)
- Chef::REST.should_receive(:new).and_return(mock_chef_rest)
- client.policy_builder.stub(:node).and_return(node)
- client.build_node.should == node
+ expect(mock_chef_rest).to receive(:get_rest).with("environments/A").and_return(test_env)
+ expect(Chef::REST).to receive(:new).and_return(mock_chef_rest)
+ allow(client.policy_builder).to receive(:node).and_return(node)
+ expect(client.build_node).to eq(node)
- node.chef_environment.should == "A"
+ expect(node.chef_environment).to eq("A")
end
end
describe "windows_admin_check" do
context "platform is not windows" do
before do
- Chef::Platform.stub(:windows?).and_return(false)
+ allow(Chef::Platform).to receive(:windows?).and_return(false)
end
it "shouldn't be called" do
- client.should_not_receive(:has_admin_privileges?)
+ expect(client).not_to receive(:has_admin_privileges?)
client.do_windows_admin_check
end
end
context "platform is windows" do
before do
- Chef::Platform.stub(:windows?).and_return(true)
+ allow(Chef::Platform).to receive(:windows?).and_return(true)
end
it "should be called" do
- client.should_receive(:has_admin_privileges?)
+ expect(client).to receive(:has_admin_privileges?)
client.do_windows_admin_check
end
context "admin privileges exist" do
before do
- client.should_receive(:has_admin_privileges?).and_return(true)
+ expect(client).to receive(:has_admin_privileges?).and_return(true)
end
it "should not log a warning message" do
- Chef::Log.should_not_receive(:warn)
+ expect(Chef::Log).not_to receive(:warn)
client.do_windows_admin_check
end
@@ -525,11 +691,11 @@ describe Chef::Client do
context "admin privileges doesn't exist" do
before do
- client.should_receive(:has_admin_privileges?).and_return(false)
+ expect(client).to receive(:has_admin_privileges?).and_return(false)
end
it "should log a warning message" do
- Chef::Log.should_receive(:warn)
+ expect(Chef::Log).to receive(:warn)
client.do_windows_admin_check
end
diff --git a/spec/unit/config_fetcher_spec.rb b/spec/unit/config_fetcher_spec.rb
index 31787a0909..1b4a4903a8 100644
--- a/spec/unit/config_fetcher_spec.rb
+++ b/spec/unit/config_fetcher_spec.rb
@@ -16,10 +16,10 @@ describe Chef::ConfigFetcher do
let(:config_content) { "# The client.rb content" }
it "reads the file from disk" do
- ::File.should_receive(:read).
+ expect(::File).to receive(:read).
with(config_location).
and_return(config_content)
- fetcher.read_config.should == config_content
+ expect(fetcher.read_config).to eq(config_content)
end
context "and consuming JSON" do
@@ -28,11 +28,11 @@ describe Chef::ConfigFetcher do
it "returns the parsed JSON" do
- ::File.should_receive(:read).
+ expect(::File).to receive(:read).
with(config_location).
and_return(valid_json)
- fetcher.fetch_json.should == {"a" => "b"}
+ expect(fetcher.fetch_json).to eq({"a" => "b"})
end
context "and the JSON is invalid" do
@@ -40,11 +40,11 @@ describe Chef::ConfigFetcher do
it "reports the JSON error" do
- ::File.should_receive(:read).
+ expect(::File).to receive(:read).
with(config_location).
and_return(invalid_json)
- Chef::Application.should_receive(:fatal!).
+ expect(Chef::Application).to receive(:fatal!).
with(invalid_json_error_regex, 2)
fetcher.fetch_json
end
@@ -59,32 +59,32 @@ describe Chef::ConfigFetcher do
let(:config_content) { "# The client.rb content" }
before do
- Chef::HTTP::Simple.should_receive(:new).
+ expect(Chef::HTTP::Simple).to receive(:new).
with(config_location).
and_return(http)
end
it "reads the file over HTTP" do
- http.should_receive(:get).
+ expect(http).to receive(:get).
with("").and_return(config_content)
- fetcher.read_config.should == config_content
+ expect(fetcher.read_config).to eq(config_content)
end
context "and consuming JSON" do
let(:config_location) { "https://example.com/foo.json" }
it "fetches the file and parses it" do
- http.should_receive(:get).
+ expect(http).to receive(:get).
with("").and_return(valid_json)
- fetcher.fetch_json.should == {"a" => "b"}
+ expect(fetcher.fetch_json).to eq({"a" => "b"})
end
context "and the JSON is invalid" do
it "reports the JSON error" do
- http.should_receive(:get).
+ expect(http).to receive(:get).
with("").and_return(invalid_json)
- Chef::Application.should_receive(:fatal!).
+ expect(Chef::Application).to receive(:fatal!).
with(invalid_json_error_regex, 2)
fetcher.fetch_json
end
diff --git a/spec/unit/config_spec.rb b/spec/unit/config_spec.rb
index a76a2fac8e..06178f7733 100644
--- a/spec/unit/config_spec.rb
+++ b/spec/unit/config_spec.rb
@@ -28,7 +28,7 @@ describe Chef::Config do
end
it "sets the server url" do
- Chef::Config.chef_server_url.should == "https://junglist.gen.nz"
+ expect(Chef::Config.chef_server_url).to eq("https://junglist.gen.nz")
end
context "when the url has a leading space" do
@@ -37,7 +37,7 @@ describe Chef::Config do
end
it "strips the space from the url when setting" do
- Chef::Config.chef_server_url.should == "https://junglist.gen.nz"
+ expect(Chef::Config.chef_server_url).to eq("https://junglist.gen.nz")
end
end
@@ -48,7 +48,7 @@ describe Chef::Config do
end
it "strips the space from the url when setting without raising an error" do
- Chef::Config.chef_server_url.should == "https://junglist.gen.nz"
+ expect(Chef::Config.chef_server_url).to eq("https://junglist.gen.nz")
end
end
@@ -79,39 +79,39 @@ describe Chef::Config do
# end
#
it "has an empty list of formatters by default" do
- Chef::Config.formatters.should == []
+ expect(Chef::Config.formatters).to eq([])
end
it "configures a formatter with a short name" do
Chef::Config.add_formatter(:doc)
- Chef::Config.formatters.should == [[:doc, nil]]
+ expect(Chef::Config.formatters).to eq([[:doc, nil]])
end
it "configures a formatter with a file output" do
Chef::Config.add_formatter(:doc, "/var/log/formatter.log")
- Chef::Config.formatters.should == [[:doc, "/var/log/formatter.log"]]
+ expect(Chef::Config.formatters).to eq([[:doc, "/var/log/formatter.log"]])
end
end
describe "class method: manage_secret_key" do
before do
- Chef::FileCache.stub(:load).and_return(true)
- Chef::FileCache.stub(:has_key?).with("chef_server_cookie_id").and_return(false)
+ allow(Chef::FileCache).to receive(:load).and_return(true)
+ allow(Chef::FileCache).to receive(:has_key?).with("chef_server_cookie_id").and_return(false)
end
it "should generate and store a chef server cookie id" do
- Chef::FileCache.should_receive(:store).with("chef_server_cookie_id", /\w{40}/).and_return(true)
+ expect(Chef::FileCache).to receive(:store).with("chef_server_cookie_id", /\w{40}/).and_return(true)
Chef::Config.manage_secret_key
end
describe "when the filecache has a chef server cookie id key" do
before do
- Chef::FileCache.stub(:has_key?).with("chef_server_cookie_id").and_return(true)
+ allow(Chef::FileCache).to receive(:has_key?).with("chef_server_cookie_id").and_return(true)
end
it "should not generate and store a chef server cookie id" do
- Chef::FileCache.should_not_receive(:store).with("chef_server_cookie_id", /\w{40}/)
+ expect(Chef::FileCache).not_to receive(:store).with("chef_server_cookie_id", /\w{40}/)
Chef::Config.manage_secret_key
end
end
@@ -126,23 +126,23 @@ describe Chef::Config do
end
before :each do
- Chef::Platform.stub(:windows?).and_return(is_windows)
+ allow(Chef::Platform).to receive(:windows?).and_return(is_windows)
end
describe "class method: platform_specific_path" do
if is_windows
it "should return a windows path on windows systems" do
path = "/etc/chef/cookbooks"
- Chef::Config.stub(:env).and_return({ 'SYSTEMDRIVE' => 'C:' })
+ allow(Chef::Config).to receive(:env).and_return({ 'SYSTEMDRIVE' => 'C:' })
# match on a regex that looks for the base path with an optional
# system drive at the beginning (c:)
# system drive is not hardcoded b/c it can change and b/c it is not present on linux systems
- Chef::Config.platform_specific_path(path).should == "C:\\chef\\cookbooks"
+ expect(Chef::Config.platform_specific_path(path)).to eq("C:\\chef\\cookbooks")
end
else
it "should return given path on non-windows systems" do
path = "/etc/chef/cookbooks"
- Chef::Config.platform_specific_path(path).should == "/etc/chef/cookbooks"
+ expect(Chef::Config.platform_specific_path(path)).to eq("/etc/chef/cookbooks")
end
end
end
@@ -166,46 +166,46 @@ describe Chef::Config do
before do
if is_windows
- Chef::Config.stub(:env).and_return({ 'SYSTEMDRIVE' => 'C:' })
+ allow(Chef::Config).to receive(:env).and_return({ 'SYSTEMDRIVE' => 'C:' })
Chef::Config[:user_home] = 'C:\Users\charlie'
else
Chef::Config[:user_home] = '/Users/charlie'
end
- Chef::Config.stub(:path_accessible?).and_return(false)
+ allow(Chef::Config).to receive(:path_accessible?).and_return(false)
end
describe "Chef::Config[:cache_path]" do
context "when /var/chef exists and is accessible" do
it "defaults to /var/chef" do
- Chef::Config.stub(:path_accessible?).with(to_platform("/var/chef")).and_return(true)
- Chef::Config[:cache_path].should == primary_cache_path
+ allow(Chef::Config).to receive(:path_accessible?).with(to_platform("/var/chef")).and_return(true)
+ expect(Chef::Config[:cache_path]).to eq(primary_cache_path)
end
end
context "when /var/chef does not exist and /var is accessible" do
it "defaults to /var/chef" do
- File.stub(:exists?).with(to_platform("/var/chef")).and_return(false)
- Chef::Config.stub(:path_accessible?).with(to_platform("/var")).and_return(true)
- Chef::Config[:cache_path].should == primary_cache_path
+ allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(false)
+ allow(Chef::Config).to receive(:path_accessible?).with(to_platform("/var")).and_return(true)
+ expect(Chef::Config[:cache_path]).to eq(primary_cache_path)
end
end
context "when /var/chef does not exist and /var is not accessible" do
it "defaults to $HOME/.chef" do
- File.stub(:exists?).with(to_platform("/var/chef")).and_return(false)
- Chef::Config.stub(:path_accessible?).with(to_platform("/var")).and_return(false)
- Chef::Config[:cache_path].should == secondary_cache_path
+ allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(false)
+ allow(Chef::Config).to receive(:path_accessible?).with(to_platform("/var")).and_return(false)
+ expect(Chef::Config[:cache_path]).to eq(secondary_cache_path)
end
end
context "when /var/chef exists and is not accessible" do
it "defaults to $HOME/.chef" do
- File.stub(:exists?).with(to_platform("/var/chef")).and_return(true)
- File.stub(:readable?).with(to_platform("/var/chef")).and_return(true)
- File.stub(:writable?).with(to_platform("/var/chef")).and_return(false)
+ allow(File).to receive(:exists?).with(to_platform("/var/chef")).and_return(true)
+ allow(File).to receive(:readable?).with(to_platform("/var/chef")).and_return(true)
+ allow(File).to receive(:writable?).with(to_platform("/var/chef")).and_return(false)
- Chef::Config[:cache_path].should == secondary_cache_path
+ expect(Chef::Config[:cache_path]).to eq(secondary_cache_path)
end
end
@@ -220,7 +220,7 @@ describe Chef::Config do
end
it "cache_path is /a/b/c/local-mode-cache" do
- Chef::Config.cache_path.should == to_platform('/a/b/c/local-mode-cache')
+ expect(Chef::Config.cache_path).to eq(to_platform('/a/b/c/local-mode-cache'))
end
end
@@ -230,43 +230,43 @@ describe Chef::Config do
end
it "cache_path is /a/b/c/local-mode-cache" do
- Chef::Config.cache_path.should == to_platform('/a/b/c/local-mode-cache')
+ expect(Chef::Config.cache_path).to eq(to_platform('/a/b/c/local-mode-cache'))
end
end
end
end
it "Chef::Config[:file_backup_path] defaults to /var/chef/backup" do
- Chef::Config.stub(:cache_path).and_return(primary_cache_path)
+ allow(Chef::Config).to receive(:cache_path).and_return(primary_cache_path)
backup_path = is_windows ? "#{primary_cache_path}\\backup" : "#{primary_cache_path}/backup"
- Chef::Config[:file_backup_path].should == backup_path
+ expect(Chef::Config[:file_backup_path]).to eq(backup_path)
end
it "Chef::Config[:ssl_verify_mode] defaults to :verify_peer" do
- Chef::Config[:ssl_verify_mode].should == :verify_peer
+ expect(Chef::Config[:ssl_verify_mode]).to eq(:verify_peer)
end
it "Chef::Config[:ssl_ca_path] defaults to nil" do
- Chef::Config[:ssl_ca_path].should be_nil
+ expect(Chef::Config[:ssl_ca_path]).to be_nil
end
# TODO can this be removed?
if !is_windows
it "Chef::Config[:ssl_ca_file] defaults to nil" do
- Chef::Config[:ssl_ca_file].should be_nil
+ expect(Chef::Config[:ssl_ca_file]).to be_nil
end
end
it "Chef::Config[:data_bag_path] defaults to /var/chef/data_bags" do
- Chef::Config.stub(:cache_path).and_return(primary_cache_path)
+ allow(Chef::Config).to receive(:cache_path).and_return(primary_cache_path)
data_bag_path = is_windows ? "#{primary_cache_path}\\data_bags" : "#{primary_cache_path}/data_bags"
- Chef::Config[:data_bag_path].should == data_bag_path
+ expect(Chef::Config[:data_bag_path]).to eq(data_bag_path)
end
it "Chef::Config[:environment_path] defaults to /var/chef/environments" do
- Chef::Config.stub(:cache_path).and_return(primary_cache_path)
+ allow(Chef::Config).to receive(:cache_path).and_return(primary_cache_path)
environment_path = is_windows ? "#{primary_cache_path}\\environments" : "#{primary_cache_path}/environments"
- Chef::Config[:environment_path].should == environment_path
+ expect(Chef::Config[:environment_path]).to eq(environment_path)
end
describe "setting the config dir" do
@@ -278,7 +278,7 @@ describe Chef::Config do
end
it "config_dir is /etc/chef" do
- Chef::Config.config_dir.should == to_platform("/etc/chef")
+ expect(Chef::Config.config_dir).to eq(to_platform("/etc/chef"))
end
context "and chef is running in local mode" do
@@ -287,7 +287,7 @@ describe Chef::Config do
end
it "config_dir is /etc/chef" do
- Chef::Config.config_dir.should == to_platform("/etc/chef")
+ expect(Chef::Config.config_dir).to eq(to_platform("/etc/chef"))
end
end
@@ -297,7 +297,7 @@ describe Chef::Config do
end
it "yields the explicit value" do
- Chef::Config.config_dir.should == to_platform("/other/config/dir/")
+ expect(Chef::Config.config_dir).to eq(to_platform("/other/config/dir/"))
end
end
@@ -309,7 +309,7 @@ describe Chef::Config do
end
it "config_dir is /home/charlie/.chef/" do
- Chef::Config.config_dir.should == Chef::Util::PathHelper.join(to_platform("/home/charlie/.chef"), '')
+ expect(Chef::Config.config_dir).to eq(Chef::Util::PathHelper.join(to_platform("/home/charlie/.chef"), ''))
end
context "and chef is running in local mode" do
@@ -318,7 +318,7 @@ describe Chef::Config do
end
it "config_dir is /home/charlie/.chef/" do
- Chef::Config.config_dir.should == Chef::Util::PathHelper.join(to_platform("/home/charlie/.chef"), '')
+ expect(Chef::Config.config_dir).to eq(Chef::Util::PathHelper.join(to_platform("/home/charlie/.chef"), ''))
end
end
end
@@ -334,24 +334,24 @@ describe Chef::Config do
let(:default_ca_file) { "c:/opscode/chef/embedded/ssl/certs/cacert.pem" }
it "finds the embedded dir in the default location" do
- Chef::Config.stub(:_this_file).and_return(default_config_location)
- Chef::Config.embedded_dir.should == "c:/opscode/chef/embedded"
+ allow(Chef::Config).to receive(:_this_file).and_return(default_config_location)
+ expect(Chef::Config.embedded_dir).to eq("c:/opscode/chef/embedded")
end
it "finds the embedded dir in a custom install location" do
- Chef::Config.stub(:_this_file).and_return(alternate_install_location)
- Chef::Config.embedded_dir.should == "c:/my/alternate/install/place/chef/embedded"
+ allow(Chef::Config).to receive(:_this_file).and_return(alternate_install_location)
+ expect(Chef::Config.embedded_dir).to eq("c:/my/alternate/install/place/chef/embedded")
end
it "doesn't error when not in an omnibus install" do
- Chef::Config.stub(:_this_file).and_return(non_omnibus_location)
- Chef::Config.embedded_dir.should be_nil
+ allow(Chef::Config).to receive(:_this_file).and_return(non_omnibus_location)
+ expect(Chef::Config.embedded_dir).to be_nil
end
it "sets the ssl_ca_cert path if the cert file is available" do
- Chef::Config.stub(:_this_file).and_return(default_config_location)
- File.stub(:exist?).with(default_ca_file).and_return(true)
- Chef::Config.ssl_ca_file.should == default_ca_file
+ allow(Chef::Config).to receive(:_this_file).and_return(default_config_location)
+ allow(File).to receive(:exist?).with(default_ca_file).and_return(true)
+ expect(Chef::Config.ssl_ca_file).to eq(default_ca_file)
end
end
end
@@ -360,19 +360,19 @@ describe Chef::Config do
describe "Chef::Config[:user_home]" do
it "should set when HOME is provided" do
expected = to_platform("/home/kitten")
- Chef::Config.stub(:env).and_return({ 'HOME' => expected })
- Chef::Config[:user_home].should == expected
+ allow(Chef::Config).to receive(:env).and_return({ 'HOME' => expected })
+ expect(Chef::Config[:user_home]).to eq(expected)
end
it "should be set when only USERPROFILE is provided" do
expected = to_platform("/users/kitten")
- Chef::Config.stub(:env).and_return({ 'USERPROFILE' => expected })
- Chef::Config[:user_home].should == expected
+ allow(Chef::Config).to receive(:env).and_return({ 'USERPROFILE' => expected })
+ expect(Chef::Config[:user_home]).to eq(expected)
end
it "falls back to the current working directory when HOME and USERPROFILE is not set" do
- Chef::Config.stub(:env).and_return({})
- Chef::Config[:user_home].should == Dir.pwd
+ allow(Chef::Config).to receive(:env).and_return({})
+ expect(Chef::Config[:user_home]).to eq(Dir.pwd)
end
end
@@ -380,32 +380,32 @@ describe Chef::Config do
let(:db_secret_default_path){ to_platform("/etc/chef/encrypted_data_bag_secret") }
before do
- File.stub(:exist?).with(db_secret_default_path).and_return(secret_exists)
+ allow(File).to receive(:exist?).with(db_secret_default_path).and_return(secret_exists)
end
context "/etc/chef/encrypted_data_bag_secret exists" do
let(:secret_exists) { true }
it "sets the value to /etc/chef/encrypted_data_bag_secret" do
- Chef::Config[:encrypted_data_bag_secret].should eq db_secret_default_path
+ expect(Chef::Config[:encrypted_data_bag_secret]).to eq db_secret_default_path
end
end
context "/etc/chef/encrypted_data_bag_secret does not exist" do
let(:secret_exists) { false }
it "sets the value to nil" do
- Chef::Config[:encrypted_data_bag_secret].should be_nil
+ expect(Chef::Config[:encrypted_data_bag_secret]).to be_nil
end
end
end
describe "Chef::Config[:event_handlers]" do
it "sets a event_handlers to an empty array by default" do
- Chef::Config[:event_handlers].should eq([])
+ expect(Chef::Config[:event_handlers]).to eq([])
end
it "should be able to add custom handlers" do
o = Object.new
Chef::Config[:event_handlers] << o
- Chef::Config[:event_handlers].should be_include(o)
+ expect(Chef::Config[:event_handlers]).to be_include(o)
end
end
@@ -413,7 +413,7 @@ describe Chef::Config do
context "on a platform that is not Windows" do
it "allows one letter usernames" do
any_match = Chef::Config[:user_valid_regex].any? { |regex| regex.match('a') }
- expect(any_match).to be_true
+ expect(any_match).to be_truthy
end
end
end
@@ -508,4 +508,43 @@ describe Chef::Config do
end
end
end
+
+ describe "Treating deprecation warnings as errors" do
+
+ context "when using our default RSpec configuration" do
+
+ it "defaults to treating deprecation warnings as errors" do
+ expect(Chef::Config[:treat_deprecation_warnings_as_errors]).to be(true)
+ end
+
+ it "sets CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS environment variable" do
+ expect(ENV['CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS']).to eq("1")
+ end
+
+ it "treats deprecation warnings as errors in child processes when testing" do
+ # Doing a full integration test where we launch a child process is slow
+ # and liable to break for weird reasons (bundler env stuff, etc.), so
+ # we're just checking that the presence of the environment variable
+ # causes treat_deprecation_warnings_as_errors to be set to true after a
+ # config reset.
+ Chef::Config.reset
+ expect(Chef::Config[:treat_deprecation_warnings_as_errors]).to be(true)
+ end
+
+ end
+
+ context "outside of our test environment" do
+
+ before do
+ ENV.delete('CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS')
+ Chef::Config.reset
+ end
+
+ it "defaults to NOT treating deprecation warnings as errors" do
+ expect(Chef::Config[:treat_deprecation_warnings_as_errors]).to be(false)
+ end
+ end
+
+
+ end
end
diff --git a/spec/unit/cookbook/chefignore_spec.rb b/spec/unit/cookbook/chefignore_spec.rb
index e529a6d05a..9f5546de28 100644
--- a/spec/unit/cookbook/chefignore_spec.rb
+++ b/spec/unit/cookbook/chefignore_spec.rb
@@ -23,18 +23,18 @@ describe Chef::Cookbook::Chefignore do
end
it "loads the globs in the chefignore file" do
- @chefignore.ignores.should =~ %w[recipes/ignoreme.rb ignored]
+ expect(@chefignore.ignores).to match_array(%w[recipes/ignoreme.rb ignored])
end
it "removes items from an array that match the ignores" do
file_list = %w[ recipes/ignoreme.rb recipes/dontignoreme.rb ]
- @chefignore.remove_ignores_from(file_list).should == %w[recipes/dontignoreme.rb]
+ expect(@chefignore.remove_ignores_from(file_list)).to eq(%w[recipes/dontignoreme.rb])
end
it "determines if a file is ignored" do
- @chefignore.ignored?('ignored').should be_true
- @chefignore.ignored?('recipes/ignoreme.rb').should be_true
- @chefignore.ignored?('recipes/dontignoreme.rb').should be_false
+ expect(@chefignore.ignored?('ignored')).to be_truthy
+ expect(@chefignore.ignored?('recipes/ignoreme.rb')).to be_truthy
+ expect(@chefignore.ignored?('recipes/dontignoreme.rb')).to be_falsey
end
context "when using the single cookbook pattern" do
@@ -43,7 +43,7 @@ describe Chef::Cookbook::Chefignore do
end
it "loads the globs in the chefignore file" do
- @chefignore.ignores.should =~ %w[recipes/ignoreme.rb ignored vendor/bundle/*]
+ expect(@chefignore.ignores).to match_array(%w[recipes/ignoreme.rb ignored vendor/bundle/*])
end
end
end
diff --git a/spec/unit/cookbook/cookbook_version_loader_spec.rb b/spec/unit/cookbook/cookbook_version_loader_spec.rb
index 4ba4e1de57..2c4ad11787 100644
--- a/spec/unit/cookbook/cookbook_version_loader_spec.rb
+++ b/spec/unit/cookbook/cookbook_version_loader_spec.rb
@@ -20,7 +20,7 @@ require 'spec_helper'
describe Chef::Cookbook::CookbookVersionLoader do
before do
- Chef::Platform.stub(:windows?) { false }
+ allow(Chef::Platform).to receive(:windows?) { false }
end
describe "loading a cookbook" do
@@ -74,8 +74,8 @@ describe Chef::Cookbook::CookbookVersionLoader do
end
it "should load the metadata for the cookbook" do
- loaded_cookbook.metadata.name.to_s.should == "openldap"
- loaded_cookbook.metadata.should be_a_kind_of(Chef::Cookbook::Metadata)
+ expect(loaded_cookbook.metadata.name.to_s).to eq("openldap")
+ expect(loaded_cookbook.metadata).to be_a_kind_of(Chef::Cookbook::Metadata)
end
context "when a cookbook has ignored files" do
diff --git a/spec/unit/cookbook/metadata_spec.rb b/spec/unit/cookbook/metadata_spec.rb
index 51814320d4..760ae5dd2a 100644
--- a/spec/unit/cookbook/metadata_spec.rb
+++ b/spec/unit/cookbook/metadata_spec.rb
@@ -34,7 +34,7 @@ describe Chef::Cookbook::Metadata do
end
it "does not depend on object identity for equality" do
- metadata.should == metadata.dup
+ expect(metadata).to eq(metadata.dup)
end
it "is not equal to another object if it isn't have all of the metadata fields" do
@@ -46,7 +46,7 @@ describe Chef::Cookbook::Metadata do
setter = "#{field}="
metadata_value = metadata.send(field)
almost_duck_type.send(setter, metadata_value) if almost_duck_type.respond_to?(setter)
- @mets.should_not == almost_duck_type
+ expect(@mets).not_to eq(almost_duck_type)
end
end
end
@@ -58,7 +58,7 @@ describe Chef::Cookbook::Metadata do
metadata_value = metadata.send(field)
duck_type.send(setter, metadata_value)
end
- metadata.should == duck_type
+ expect(metadata).to eq(duck_type)
end
it "is not equal if any values are different" do
@@ -73,7 +73,7 @@ describe Chef::Cookbook::Metadata do
end
duck_type.send("#{field_to_change}=".to_sym, :epic_fail)
- metadata.should_not == duck_type
+ expect(metadata).not_to eq(duck_type)
end
end
@@ -82,71 +82,71 @@ describe Chef::Cookbook::Metadata do
describe "when first created" do
it "has no name" do
- metadata.name.should eq(nil)
+ expect(metadata.name).to eq(nil)
end
it "has an empty description" do
- metadata.description.should eq("")
+ expect(metadata.description).to eq("")
end
it "has an empty long description" do
- metadata.long_description.should eq("")
+ expect(metadata.long_description).to eq("")
end
it "defaults to 'all rights reserved' license" do
- metadata.license.should eq("All rights reserved")
+ expect(metadata.license).to eq("All rights reserved")
end
it "has an empty maintainer field" do
- metadata.maintainer.should eq(nil)
+ expect(metadata.maintainer).to eq(nil)
end
it "has an empty maintainer_email field" do
- metadata.maintainer.should eq(nil)
+ expect(metadata.maintainer).to eq(nil)
end
it "has an empty platforms list" do
- metadata.platforms.should eq(Mash.new)
+ expect(metadata.platforms).to eq(Mash.new)
end
it "has an empty dependencies list" do
- metadata.dependencies.should eq(Mash.new)
+ expect(metadata.dependencies).to eq(Mash.new)
end
it "has an empty recommends list" do
- metadata.recommendations.should eq(Mash.new)
+ expect(metadata.recommendations).to eq(Mash.new)
end
it "has an empty suggestions list" do
- metadata.suggestions.should eq(Mash.new)
+ expect(metadata.suggestions).to eq(Mash.new)
end
it "has an empty conflicts list" do
- metadata.conflicting.should eq(Mash.new)
+ expect(metadata.conflicting).to eq(Mash.new)
end
it "has an empty replaces list" do
- metadata.replacing.should eq(Mash.new)
+ expect(metadata.replacing).to eq(Mash.new)
end
it "has an empty attributes list" do
- metadata.attributes.should eq(Mash.new)
+ expect(metadata.attributes).to eq(Mash.new)
end
it "has an empty groupings list" do
- metadata.groupings.should eq(Mash.new)
+ expect(metadata.groupings).to eq(Mash.new)
end
it "has an empty recipes list" do
- metadata.recipes.should eq(Mash.new)
+ expect(metadata.recipes).to eq(Mash.new)
end
it "has an empty source_url string" do
- metadata.source_url.should eq('')
+ expect(metadata.source_url).to eq('')
end
it "has an empty issues_url string" do
- metadata.issues_url.should eq('')
+ expect(metadata.issues_url).to eq('')
end
end
@@ -155,12 +155,12 @@ describe Chef::Cookbook::Metadata do
context "when no required fields are set" do
it "is not valid" do
- metadata.should_not be_valid
+ expect(metadata).not_to be_valid
end
it "has a list of validation errors" do
expected_errors = ["The `name' attribute is required in cookbook metadata"]
- metadata.errors.should eq(expected_errors)
+ expect(metadata.errors).to eq(expected_errors)
end
end
@@ -171,11 +171,11 @@ describe Chef::Cookbook::Metadata do
end
it "is valid" do
- metadata.should be_valid
+ expect(metadata).to be_valid
end
it "has no validation errors" do
- metadata.errors.should be_empty
+ expect(metadata.errors).to be_empty
end
end
@@ -185,7 +185,7 @@ describe Chef::Cookbook::Metadata do
describe "adding a supported platform" do
it "should support adding a supported platform with a single expression" do
metadata.supports("ubuntu", ">= 8.04")
- metadata.platforms["ubuntu"].should == '>= 8.04'
+ expect(metadata.platforms["ubuntu"]).to eq('>= 8.04')
end
end
@@ -203,23 +203,23 @@ describe Chef::Cookbook::Metadata do
params.sort { |a,b| a.to_s <=> b.to_s }.each do |field, field_value|
describe field do
it "should be set-able via #{field}" do
- metadata.send(field, field_value).should eql(field_value)
+ expect(metadata.send(field, field_value)).to eql(field_value)
end
it "should be get-able via #{field}" do
metadata.send(field, field_value)
- metadata.send(field).should eql(field_value)
+ expect(metadata.send(field)).to eql(field_value)
end
end
end
describe "version transformation" do
it "should transform an '0.6' version to '0.6.0'" do
- metadata.send(:version, "0.6").should eql("0.6.0")
+ expect(metadata.send(:version, "0.6")).to eql("0.6.0")
end
it "should spit out '0.6.0' after transforming '0.6'" do
metadata.send(:version, "0.6")
- metadata.send(:version).should eql("0.6.0")
+ expect(metadata.send(:version)).to eql("0.6.0")
end
end
end
@@ -238,11 +238,11 @@ describe Chef::Cookbook::Metadata do
check_with = dep_args.shift
describe dep do
it "should be set-able via #{dep}" do
- metadata.send(dep, *dep_args).should == dep_args[1]
+ expect(metadata.send(dep, *dep_args)).to eq(dep_args[1])
end
it "should be get-able via #{check_with}" do
metadata.send(dep, *dep_args)
- metadata.send(check_with).should == { dep_args[0] => dep_args[1] }
+ expect(metadata.send(check_with)).to eq({ dep_args[0] => dep_args[1] })
end
end
end
@@ -260,11 +260,11 @@ describe Chef::Cookbook::Metadata do
normalized_version = dep_args.pop
describe dep do
it "should be set-able and normalized via #{dep}" do
- metadata.send(dep, *dep_args).should == normalized_version
+ expect(metadata.send(dep, *dep_args)).to eq(normalized_version)
end
it "should be get-able and normalized via #{check_with}" do
metadata.send(dep, *dep_args)
- metadata.send(check_with).should == { dep_args[0] => normalized_version }
+ expect(metadata.send(check_with)).to eq({ dep_args[0] => normalized_version })
end
end
end
@@ -282,7 +282,7 @@ describe Chef::Cookbook::Metadata do
dep_types.each do |dep, dep_args|
it "for #{dep} raises an informative error instead of vomiting on your shoes" do
- lambda {metadata.send(dep, *dep_args)}.should raise_error(Chef::Exceptions::ObsoleteDependencySyntax)
+ expect {metadata.send(dep, *dep_args)}.to raise_error(Chef::Exceptions::ObsoleteDependencySyntax)
end
end
end
@@ -300,7 +300,7 @@ describe Chef::Cookbook::Metadata do
dep_types.each do |dep, dep_args|
it "for #{dep} raises an informative error instead of vomiting on your shoes" do
- lambda {metadata.send(dep, *dep_args)}.should raise_error(Chef::Exceptions::InvalidVersionConstraint)
+ expect {metadata.send(dep, *dep_args)}.to raise_error(Chef::Exceptions::InvalidVersionConstraint)
end
end
end
@@ -312,24 +312,24 @@ describe Chef::Cookbook::Metadata do
"title" => "MySQL Tuning",
"description" => "Setting from the my.cnf file that allow you to tune your mysql server"
}
- metadata.grouping("/db/mysql/databases/tuning", group).should == group
+ expect(metadata.grouping("/db/mysql/databases/tuning", group)).to eq(group)
end
it "should not accept anything but a string for display_name" do
- lambda {
+ expect {
metadata.grouping("db/mysql/databases", :title => "foo")
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.grouping("db/mysql/databases", :title => Hash.new)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should not accept anything but a string for the description" do
- lambda {
+ expect {
metadata.grouping("db/mysql/databases", :description => "foo")
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.grouping("db/mysql/databases", :description => Hash.new)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
end
@@ -347,170 +347,170 @@ describe Chef::Cookbook::Metadata do
"source_url" => "http://example.com",
"issues_url" => "http://example.com/issues"
}
- metadata.attribute("/db/mysql/databases", attrs).should == attrs
+ expect(metadata.attribute("/db/mysql/databases", attrs)).to eq(attrs)
end
it "should not accept anything but a string for display_name" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :display_name => "foo")
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :display_name => Hash.new)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should not accept anything but a string for the description" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :description => "foo")
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :description => Hash.new)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should not accept anything but a string for the source_url" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :source_url => "foo")
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :source_url => Hash.new)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should not accept anything but a string for the issues_url" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :issues_url => "foo")
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :issues_url => Hash.new)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should not accept anything but an array of strings for choice" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :choice => ['dedicated', 'shared'])
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :choice => [10, 'shared'])
- }.should raise_error(ArgumentError)
- lambda {
+ }.to raise_error(ArgumentError)
+ expect {
metadata.attribute("db/mysql/databases", :choice => Hash.new)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should set choice to empty array by default" do
metadata.attribute("db/mysql/databases", {})
- metadata.attributes["db/mysql/databases"][:choice].should == []
+ expect(metadata.attributes["db/mysql/databases"][:choice]).to eq([])
end
it "should let calculated be true or false" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :calculated => true)
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :calculated => false)
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :calculated => Hash.new)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should set calculated to false by default" do
metadata.attribute("db/mysql/databases", {})
- metadata.attributes["db/mysql/databases"][:calculated].should == false
+ expect(metadata.attributes["db/mysql/databases"][:calculated]).to eq(false)
end
it "accepts String for the attribute type" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :type => "string")
- }.should_not raise_error
+ }.not_to raise_error
end
it "accepts Array for the attribute type" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :type => "array")
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :type => Array.new)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "accepts symbol for the attribute type" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :type => "symbol")
- }.should_not raise_error
+ }.not_to raise_error
end
- it "should let type be hash (backwards compatability only)" do
- lambda {
+ it "should let type be hash (backwards compatibility only)" do
+ expect {
metadata.attribute("db/mysql/databases", :type => "hash")
- }.should_not raise_error
+ }.not_to raise_error
end
it "should let required be required, recommended or optional" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :required => 'required')
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :required => 'recommended')
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :required => 'optional')
- }.should_not raise_error
+ }.not_to raise_error
end
it "should convert required true to required" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :required => true)
- }.should_not raise_error
+ }.not_to raise_error
#attrib = metadata.attributes["db/mysql/databases"][:required].should == "required"
end
it "should convert required false to optional" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :required => false)
- }.should_not raise_error
+ }.not_to raise_error
#attrib = metadata.attributes["db/mysql/databases"][:required].should == "optional"
end
it "should set required to 'optional' by default" do
metadata.attribute("db/mysql/databases", {})
- metadata.attributes["db/mysql/databases"][:required].should == 'optional'
+ expect(metadata.attributes["db/mysql/databases"][:required]).to eq('optional')
end
it "should make sure recipes is an array" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :recipes => [])
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :required => Hash.new)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should set recipes to an empty array by default" do
metadata.attribute("db/mysql/databases", {})
- metadata.attributes["db/mysql/databases"][:recipes].should == []
+ expect(metadata.attributes["db/mysql/databases"][:recipes]).to eq([])
end
it "should allow the default value to be a string, array, hash, boolean or numeric" do
- lambda {
+ expect {
metadata.attribute("db/mysql/databases", :default => [])
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :default => {})
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :default => "alice in chains")
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :default => 1337)
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :default => true)
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
metadata.attribute("db/mysql/databases", :required => :not_gonna_do_it)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should limit the types allowed in the choice array" do
@@ -519,87 +519,87 @@ describe Chef::Cookbook::Metadata do
:choice => [ "test1", "test2" ],
:default => "test1"
}
- lambda {
+ expect {
metadata.attribute("test_cookbook/test", options)
- }.should_not raise_error
+ }.not_to raise_error
options = {
:type => "boolean",
:choice => [ true, false ],
:default => true
}
- lambda {
+ expect {
metadata.attribute("test_cookbook/test", options)
- }.should_not raise_error
+ }.not_to raise_error
options = {
:type => "numeric",
:choice => [ 1337, 420 ],
:default => 1337
}
- lambda {
+ expect {
metadata.attribute("test_cookbook/test", options)
- }.should_not raise_error
+ }.not_to raise_error
options = {
:type => "numeric",
:choice => [ true, "false" ],
:default => false
}
- lambda {
+ expect {
metadata.attribute("test_cookbook/test", options)
- }.should raise_error
+ }.to raise_error
end
it "should error if default used with calculated" do
- lambda {
+ expect {
attrs = {
:calculated => true,
:default => [ "I thought you said calculated" ]
}
metadata.attribute("db/mysql/databases", attrs)
- }.should raise_error(ArgumentError)
- lambda {
+ }.to raise_error(ArgumentError)
+ expect {
attrs = {
:calculated => true,
:default => "I thought you said calculated"
}
metadata.attribute("db/mysql/databases", attrs)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should allow a default that is a choice" do
- lambda {
+ expect {
attrs = {
:choice => [ "a", "b", "c"],
:default => "b"
}
metadata.attribute("db/mysql/databases", attrs)
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
attrs = {
:choice => [ "a", "b", "c", "d", "e"],
:default => ["b", "d"]
}
metadata.attribute("db/mysql/databases", attrs)
- }.should_not raise_error
+ }.not_to raise_error
end
it "should error if default is not a choice" do
- lambda {
+ expect {
attrs = {
:choice => [ "a", "b", "c"],
:default => "d"
}
metadata.attribute("db/mysql/databases", attrs)
- }.should raise_error(ArgumentError)
- lambda {
+ }.to raise_error(ArgumentError)
+ expect {
attrs = {
:choice => [ "a", "b", "c", "d", "e"],
:default => ["b", "z"]
}
metadata.attribute("db/mysql/databases", attrs)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
end
@@ -616,18 +616,18 @@ describe Chef::Cookbook::Metadata do
end
it "should have the names of the recipes" do
- metadata.recipes["test_cookbook"].should == ""
- metadata.recipes["test_cookbook::enlighten"].should == ""
+ expect(metadata.recipes["test_cookbook"]).to eq("")
+ expect(metadata.recipes["test_cookbook::enlighten"]).to eq("")
end
it "should let you set the description for a recipe" do
metadata.recipe "test_cookbook", "It, um... tests stuff?"
- metadata.recipes["test_cookbook"].should == "It, um... tests stuff?"
+ expect(metadata.recipes["test_cookbook"]).to eq("It, um... tests stuff?")
end
it "should automatically provide each recipe" do
- metadata.providing.has_key?("test_cookbook").should == true
- metadata.providing.has_key?("test_cookbook::enlighten").should == true
+ expect(metadata.providing.has_key?("test_cookbook")).to eq(true)
+ expect(metadata.providing.has_key?("test_cookbook::enlighten")).to eq(true)
end
end
@@ -662,7 +662,7 @@ describe Chef::Cookbook::Metadata do
let(:deserialized_metadata) { Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(metadata)) }
it "should serialize to a json hash" do
- deserialized_metadata.should be_a_kind_of(Hash)
+ expect(deserialized_metadata).to be_a_kind_of(Hash)
end
%w{
@@ -686,7 +686,7 @@ describe Chef::Cookbook::Metadata do
issues_url
}.each do |t|
it "should include '#{t}'" do
- deserialized_metadata[t].should == metadata.send(t.to_sym)
+ expect(deserialized_metadata[t]).to eq(metadata.send(t.to_sym))
end
end
end
@@ -697,7 +697,7 @@ describe Chef::Cookbook::Metadata do
it "should deserialize to a Chef::Cookbook::Metadata object" do
- deserialized_metadata.should be_a_kind_of(Chef::Cookbook::Metadata)
+ expect(deserialized_metadata).to be_a_kind_of(Chef::Cookbook::Metadata)
end
%w{
@@ -721,7 +721,7 @@ describe Chef::Cookbook::Metadata do
issues_url
}.each do |t|
it "should match '#{t}'" do
- deserialized_metadata.send(t.to_sym).should == metadata.send(t.to_sym)
+ expect(deserialized_metadata.send(t.to_sym)).to eq(metadata.send(t.to_sym))
end
end
end
@@ -739,31 +739,31 @@ describe Chef::Cookbook::Metadata do
it "should transform deprecated greater than syntax for :#{to_check.to_s}" do
@hash[to_check.to_s]["foo::bar"] = ">> 0.2"
deserial = Chef::Cookbook::Metadata.from_hash(@hash)
- deserial.send(to_check)["foo::bar"].should == '> 0.2'
+ expect(deserial.send(to_check)["foo::bar"]).to eq('> 0.2')
end
it "should transform deprecated less than syntax for :#{to_check.to_s}" do
@hash[to_check.to_s]["foo::bar"] = "<< 0.2"
deserial = Chef::Cookbook::Metadata.from_hash(@hash)
- deserial.send(to_check)["foo::bar"].should == '< 0.2'
+ expect(deserial.send(to_check)["foo::bar"]).to eq('< 0.2')
end
it "should ignore multiple dependency constraints for :#{to_check.to_s}" do
@hash[to_check.to_s]["foo::bar"] = [ ">= 1.0", "<= 5.2" ]
deserial = Chef::Cookbook::Metadata.from_hash(@hash)
- deserial.send(to_check)["foo::bar"].should == []
+ expect(deserial.send(to_check)["foo::bar"]).to eq([])
end
it "should accept an empty array of dependency constraints for :#{to_check.to_s}" do
@hash[to_check.to_s]["foo::bar"] = []
deserial = Chef::Cookbook::Metadata.from_hash(@hash)
- deserial.send(to_check)["foo::bar"].should == []
+ expect(deserial.send(to_check)["foo::bar"]).to eq([])
end
it "should accept single-element arrays of dependency constraints for :#{to_check.to_s}" do
@hash[to_check.to_s]["foo::bar"] = [ ">= 2.0" ]
deserial = Chef::Cookbook::Metadata.from_hash(@hash)
- deserial.send(to_check)["foo::bar"].should == ">= 2.0"
+ expect(deserial.send(to_check)["foo::bar"]).to eq(">= 2.0")
end
end
end
diff --git a/spec/unit/cookbook/syntax_check_spec.rb b/spec/unit/cookbook/syntax_check_spec.rb
index 4d22e0e920..471fc01831 100644
--- a/spec/unit/cookbook/syntax_check_spec.rb
+++ b/spec/unit/cookbook/syntax_check_spec.rb
@@ -21,7 +21,7 @@ require "chef/cookbook/syntax_check"
describe Chef::Cookbook::SyntaxCheck do
before do
- Chef::Platform.stub(:windows?) { false }
+ allow(Chef::Platform).to receive(:windows?) { false }
end
let(:cookbook_path) { File.join(CHEF_SPEC_DATA, 'cookbooks', 'openldap') }
@@ -43,6 +43,7 @@ describe Chef::Cookbook::SyntaxCheck do
before do
Chef::Log.logger = Logger.new(StringIO.new)
+ @original_log_level = Chef::Log.level
Chef::Log.level = :warn # suppress "Syntax OK" messages
@attr_files = %w{default.rb smokey.rb}.map { |f| File.join(cookbook_path, 'attributes', f) }
@@ -61,17 +62,21 @@ describe Chef::Cookbook::SyntaxCheck do
@template_files = basenames.map { |f| File.join(cookbook_path, 'templates', 'default', f)}
end
+ after do
+ Chef::Log.level = @original_log_level
+ end
+
it "creates a syntax checker given the cookbook name when Chef::Config.cookbook_path is set" do
Chef::Config[:cookbook_path] = File.dirname(cookbook_path)
syntax_check = Chef::Cookbook::SyntaxCheck.for_cookbook(:openldap)
- syntax_check.cookbook_path.should == cookbook_path
- syntax_check.ruby_files.sort.should == open_ldap_cookbook_files.sort
+ expect(syntax_check.cookbook_path).to eq(cookbook_path)
+ expect(syntax_check.ruby_files.sort).to eq(open_ldap_cookbook_files.sort)
end
it "creates a syntax checker given the cookbook name and cookbook_path" do
syntax_check = Chef::Cookbook::SyntaxCheck.for_cookbook(:openldap, File.join(CHEF_SPEC_DATA, 'cookbooks'))
- syntax_check.cookbook_path.should == cookbook_path
- syntax_check.ruby_files.sort.should == open_ldap_cookbook_files.sort
+ expect(syntax_check.cookbook_path).to eq(cookbook_path)
+ expect(syntax_check.ruby_files.sort).to eq(open_ldap_cookbook_files.sort)
end
context "when using a standalone cookbook" do
@@ -79,22 +84,22 @@ describe Chef::Cookbook::SyntaxCheck do
it "creates a syntax checker given the cookbook name and cookbook_path for a standalone cookbook" do
syntax_check = Chef::Cookbook::SyntaxCheck.for_cookbook(:standalone_cookbook, CHEF_SPEC_DATA)
- syntax_check.cookbook_path.should == cookbook_path
- syntax_check.ruby_files.should == [File.join(cookbook_path, 'recipes/default.rb')]
+ expect(syntax_check.cookbook_path).to eq(cookbook_path)
+ expect(syntax_check.ruby_files).to eq([File.join(cookbook_path, 'recipes/default.rb')])
end
end
describe "when first created" do
it "has the path to the cookbook to syntax check" do
- syntax_check.cookbook_path.should == cookbook_path
+ expect(syntax_check.cookbook_path).to eq(cookbook_path)
end
it "lists the ruby files in the cookbook" do
- syntax_check.ruby_files.sort.should == @ruby_files.sort
+ expect(syntax_check.ruby_files.sort).to eq(@ruby_files.sort)
end
it "lists the erb templates in the cookbook" do
- syntax_check.template_files.sort.should == @template_files.sort
+ expect(syntax_check.template_files.sort).to eq(@template_files.sort)
end
end
@@ -112,33 +117,33 @@ describe Chef::Cookbook::SyntaxCheck do
describe "and the files have not been syntax checked previously" do
it "shows that all ruby files require a syntax check" do
- syntax_check.untested_ruby_files.sort.should == @ruby_files.sort
+ expect(syntax_check.untested_ruby_files.sort).to eq(@ruby_files.sort)
end
it "shows that all template files require a syntax check" do
- syntax_check.untested_template_files.sort.should == @template_files.sort
+ expect(syntax_check.untested_template_files.sort).to eq(@template_files.sort)
end
it "removes a ruby file from the list of untested files after it is marked as validated" do
recipe = File.join(cookbook_path, 'recipes', 'default.rb')
syntax_check.validated(recipe)
- syntax_check.untested_ruby_files.should_not include(recipe)
+ expect(syntax_check.untested_ruby_files).not_to include(recipe)
end
it "removes a template file from the list of untested files after it is marked as validated" do
template = File.join(cookbook_path, 'templates', 'default', 'test.erb')
syntax_check.validated(template)
- syntax_check.untested_template_files.should_not include(template)
+ expect(syntax_check.untested_template_files).not_to include(template)
end
it "validates all ruby files" do
- syntax_check.validate_ruby_files.should be_true
- syntax_check.untested_ruby_files.should be_empty
+ expect(syntax_check.validate_ruby_files).to be_truthy
+ expect(syntax_check.untested_ruby_files).to be_empty
end
it "validates all templates" do
- syntax_check.validate_templates.should be_true
- syntax_check.untested_template_files.should be_empty
+ expect(syntax_check.validate_templates).to be_truthy
+ expect(syntax_check.untested_template_files).to be_empty
end
describe "and a file has a syntax error" do
@@ -148,22 +153,22 @@ describe Chef::Cookbook::SyntaxCheck do
end
it "it indicates that a ruby file has a syntax error" do
- syntax_check.validate_ruby_files.should be_false
+ expect(syntax_check.validate_ruby_files).to be_falsey
end
it "does not remove the invalid file from the list of untested files" do
- syntax_check.untested_ruby_files.should include(File.join(cookbook_path, 'recipes', 'default.rb'))
+ expect(syntax_check.untested_ruby_files).to include(File.join(cookbook_path, 'recipes', 'default.rb'))
syntax_check.validate_ruby_files
- syntax_check.untested_ruby_files.should include(File.join(cookbook_path, 'recipes', 'default.rb'))
+ expect(syntax_check.untested_ruby_files).to include(File.join(cookbook_path, 'recipes', 'default.rb'))
end
it "indicates that a template file has a syntax error" do
- syntax_check.validate_templates.should be_false
+ expect(syntax_check.validate_templates).to be_falsey
end
it "does not remove the invalid template from the list of untested templates" do
- syntax_check.untested_template_files.should include(File.join(cookbook_path, 'templates', 'default', 'borken.erb'))
- lambda {syntax_check.validate_templates}.should_not change(syntax_check, :untested_template_files)
+ expect(syntax_check.untested_template_files).to include(File.join(cookbook_path, 'templates', 'default', 'borken.erb'))
+ expect {syntax_check.validate_templates}.not_to change(syntax_check, :untested_template_files)
end
end
@@ -177,12 +182,12 @@ describe Chef::Cookbook::SyntaxCheck do
end
it "shows that ignored ruby files do not require a syntax check" do
- syntax_check.untested_ruby_files.sort.should == @ruby_files.sort
+ expect(syntax_check.untested_ruby_files.sort).to eq(@ruby_files.sort)
end
it "does not indicate that a ruby file has a syntax error" do
- syntax_check.validate_ruby_files.should be_true
- syntax_check.untested_ruby_files.should be_empty
+ expect(syntax_check.validate_ruby_files).to be_truthy
+ expect(syntax_check.untested_ruby_files).to be_empty
end
end
@@ -196,13 +201,13 @@ describe Chef::Cookbook::SyntaxCheck do
end
it "does not syntax check ruby files" do
- syntax_check.should_not_receive(:shell_out)
- syntax_check.validate_ruby_files.should be_true
+ expect(syntax_check).not_to receive(:shell_out)
+ expect(syntax_check.validate_ruby_files).to be_truthy
end
it "does not syntax check templates" do
- syntax_check.should_not_receive(:shell_out)
- syntax_check.validate_templates.should be_true
+ expect(syntax_check).not_to receive(:shell_out)
+ expect(syntax_check.validate_templates).to be_truthy
end
end
end
diff --git a/spec/unit/cookbook_loader_spec.rb b/spec/unit/cookbook_loader_spec.rb
index deaf393d7a..45a985bafd 100644
--- a/spec/unit/cookbook_loader_spec.rb
+++ b/spec/unit/cookbook_loader_spec.rb
@@ -20,7 +20,7 @@ require 'spec_helper'
describe Chef::CookbookLoader do
before do
- Chef::Platform.stub(:windows?) {false}
+ allow(Chef::Platform).to receive(:windows?) {false}
end
let(:repo_paths) do
[
@@ -40,7 +40,7 @@ describe Chef::CookbookLoader do
cookbook_paths.delete_if { |path| File.basename(path) == "chefignore" }
cookbook_paths.each do |cookbook_path|
- Chef::Cookbook::CookbookVersionLoader.should_receive(:new).
+ expect(Chef::Cookbook::CookbookVersionLoader).to receive(:new).
with(cookbook_path, anything).
once.
and_call_original
@@ -56,19 +56,19 @@ describe Chef::CookbookLoader do
describe "[]" do
it "should return cookbook objects with []" do
- cookbook_loader[:openldap].should be_a_kind_of(Chef::CookbookVersion)
+ expect(cookbook_loader[:openldap]).to be_a_kind_of(Chef::CookbookVersion)
end
it "should raise an exception if it cannot find a cookbook with []" do
- lambda { cookbook_loader[:monkeypoop] }.should raise_error(Chef::Exceptions::CookbookNotFoundInRepo)
+ expect { cookbook_loader[:monkeypoop] }.to raise_error(Chef::Exceptions::CookbookNotFoundInRepo)
end
it "should allow you to look up available cookbooks with [] and a symbol" do
- cookbook_loader[:openldap].name.should eql(:openldap)
+ expect(cookbook_loader[:openldap].name).to eql(:openldap)
end
it "should allow you to look up available cookbooks with [] and a string" do
- cookbook_loader["openldap"].name.should eql(:openldap)
+ expect(cookbook_loader["openldap"].name).to eql(:openldap)
end
end
@@ -78,8 +78,8 @@ describe Chef::CookbookLoader do
cookbook_loader.each do |cookbook_name, cookbook|
seen[cookbook_name] = true
end
- seen.should have_key("openldap")
- seen.should have_key("apache2")
+ expect(seen).to have_key("openldap")
+ expect(seen).to have_key("apache2")
end
it "should iterate in alphabetical order" do
@@ -87,86 +87,86 @@ describe Chef::CookbookLoader do
cookbook_loader.each do |cookbook_name, cookbook|
seen << cookbook_name
end
- seen[0].should == "angrybash"
- seen[1].should == "apache2"
- seen[2].should == "borken"
- seen[3].should == "ignorken"
- seen[4].should == "java"
- seen[5].should == "name-mismatch"
- seen[6].should == "openldap"
+ expect(seen[0]).to eq("angrybash")
+ expect(seen[1]).to eq("apache2")
+ expect(seen[2]).to eq("borken")
+ expect(seen[3]).to eq("ignorken")
+ expect(seen[4]).to eq("java")
+ expect(seen[5]).to eq("name-mismatch")
+ expect(seen[6]).to eq("openldap")
end
end
describe "referencing cookbook files" do
it "should find all the cookbooks in the cookbook path" do
cookbook_loader.load_cookbooks
- cookbook_loader.should have_key(:openldap)
- cookbook_loader.should have_key(:apache2)
+ expect(cookbook_loader).to have_key(:openldap)
+ expect(cookbook_loader).to have_key(:apache2)
end
it "should allow you to override an attribute file via cookbook_path" do
- cookbook_loader[:openldap].attribute_filenames.detect { |f|
+ expect(cookbook_loader[:openldap].attribute_filenames.detect { |f|
f =~ /cookbooks\/openldap\/attributes\/default.rb/
- }.should_not eql(nil)
- cookbook_loader[:openldap].attribute_filenames.detect { |f|
+ }).not_to eql(nil)
+ expect(cookbook_loader[:openldap].attribute_filenames.detect { |f|
f =~ /kitchen\/openldap\/attributes\/default.rb/
- }.should eql(nil)
+ }).to eql(nil)
end
it "should load different attribute files from deeper paths" do
- cookbook_loader[:openldap].attribute_filenames.detect { |f|
+ expect(cookbook_loader[:openldap].attribute_filenames.detect { |f|
f =~ /kitchen\/openldap\/attributes\/robinson.rb/
- }.should_not eql(nil)
+ }).not_to eql(nil)
end
it "should allow you to override a definition file via cookbook_path" do
- cookbook_loader[:openldap].definition_filenames.detect { |f|
+ expect(cookbook_loader[:openldap].definition_filenames.detect { |f|
f =~ /cookbooks\/openldap\/definitions\/client.rb/
- }.should_not eql(nil)
- cookbook_loader[:openldap].definition_filenames.detect { |f|
+ }).not_to eql(nil)
+ expect(cookbook_loader[:openldap].definition_filenames.detect { |f|
f =~ /kitchen\/openldap\/definitions\/client.rb/
- }.should eql(nil)
+ }).to eql(nil)
end
it "should load definition files from deeper paths" do
- cookbook_loader[:openldap].definition_filenames.detect { |f|
+ expect(cookbook_loader[:openldap].definition_filenames.detect { |f|
f =~ /kitchen\/openldap\/definitions\/drewbarrymore.rb/
- }.should_not eql(nil)
+ }).not_to eql(nil)
end
it "should allow you to override a recipe file via cookbook_path" do
- cookbook_loader[:openldap].recipe_filenames.detect { |f|
+ expect(cookbook_loader[:openldap].recipe_filenames.detect { |f|
f =~ /cookbooks\/openldap\/recipes\/gigantor.rb/
- }.should_not eql(nil)
- cookbook_loader[:openldap].recipe_filenames.detect { |f|
+ }).not_to eql(nil)
+ expect(cookbook_loader[:openldap].recipe_filenames.detect { |f|
f =~ /kitchen\/openldap\/recipes\/gigantor.rb/
- }.should eql(nil)
+ }).to eql(nil)
end
it "should load recipe files from deeper paths" do
- cookbook_loader[:openldap].recipe_filenames.detect { |f|
+ expect(cookbook_loader[:openldap].recipe_filenames.detect { |f|
f =~ /kitchen\/openldap\/recipes\/woot.rb/
- }.should_not eql(nil)
+ }).not_to eql(nil)
end
it "should allow you to have an 'ignore' file, which skips loading files in later cookbooks" do
- cookbook_loader[:openldap].recipe_filenames.detect { |f|
+ expect(cookbook_loader[:openldap].recipe_filenames.detect { |f|
f =~ /kitchen\/openldap\/recipes\/ignoreme.rb/
- }.should eql(nil)
+ }).to eql(nil)
end
it "should find files that start with a ." do
- cookbook_loader[:openldap].file_filenames.detect { |f|
+ expect(cookbook_loader[:openldap].file_filenames.detect { |f|
f =~ /\.dotfile$/
- }.should =~ /\.dotfile$/
- cookbook_loader[:openldap].file_filenames.detect { |f|
+ }).to match(/\.dotfile$/)
+ expect(cookbook_loader[:openldap].file_filenames.detect { |f|
f =~ /\.ssh\/id_rsa$/
- }.should =~ /\.ssh\/id_rsa$/
+ }).to match(/\.ssh\/id_rsa$/)
end
it "should load the metadata for the cookbook" do
- cookbook_loader.metadata[:openldap].name.to_s.should == "openldap"
- cookbook_loader.metadata[:openldap].should be_a_kind_of(Chef::Cookbook::Metadata)
+ expect(cookbook_loader.metadata[:openldap].name.to_s).to eq("openldap")
+ expect(cookbook_loader.metadata[:openldap]).to be_a_kind_of(Chef::Cookbook::Metadata)
end
end # referencing cookbook files
@@ -190,6 +190,11 @@ describe Chef::CookbookLoader do
end
describe "loading only one cookbook" do
+
+ let(:openldap_cookbook) { cookbook_loader["openldap"] }
+
+ let(:cookbook_as_hash) { Chef::CookbookManifest.new(openldap_cookbook).to_hash }
+
before(:each) do
cookbook_loader.load_cookbook("openldap")
end
@@ -199,27 +204,26 @@ describe Chef::CookbookLoader do
cookbook_loader.each do |cookbook_name, cookbook|
seen[cookbook_name] = true
end
- seen.should have_key("openldap")
+ expect(seen).to have_key("openldap")
end
it "should not duplicate keys when serialized to JSON" do
# Chef JSON serialization will generate duplicate keys if given
# a Hash containing matching string and symbol keys. See CHEF-4571.
- aa = cookbook_loader["openldap"]
- aa.to_hash["metadata"].recipes.keys.should_not include(:openldap)
- aa.to_hash["metadata"].recipes.keys.should include("openldap")
+ expect(cookbook_as_hash["metadata"].recipes.keys).not_to include(:openldap)
+ expect(cookbook_as_hash["metadata"].recipes.keys).to include("openldap")
expected_desc = "Main Open LDAP configuration"
- aa.to_hash["metadata"].recipes["openldap"].should == expected_desc
- raw = Chef::JSONCompat.to_json(aa.to_hash["metadata"].recipes)
+ expect(cookbook_as_hash["metadata"].recipes["openldap"]).to eq(expected_desc)
+ raw = Chef::JSONCompat.to_json(cookbook_as_hash["metadata"].recipes)
search_str = "\"openldap\":\""
key_idx = raw.index(search_str)
- key_idx.should be > 0
+ expect(key_idx).to be > 0
dup_idx = raw[(key_idx + 1)..-1].index(search_str)
- dup_idx.should be_nil
+ expect(dup_idx).to be_nil
end
it "should not load the cookbook again when accessed" do
- cookbook_loader.should_not_receive('load_cookbook')
+ expect(cookbook_loader).not_to receive('load_cookbook')
cookbook_loader["openldap"]
end
@@ -228,11 +232,11 @@ describe Chef::CookbookLoader do
cookbook_loader.each do |cookbook_name, cookbook|
seen[cookbook_name] = true
end
- seen.should_not have_key("apache2")
+ expect(seen).not_to have_key("apache2")
end
it "should load another cookbook lazily with []" do
- cookbook_loader["apache2"].should be_a_kind_of(Chef::CookbookVersion)
+ expect(cookbook_loader["apache2"]).to be_a_kind_of(Chef::CookbookVersion)
end
context "when an unrelated cookbook has invalid metadata" do
@@ -265,8 +269,8 @@ describe Chef::CookbookLoader do
cookbook_loader.each do |cookbook_name, cookbook|
seen[cookbook_name] = true
end
- seen.should have_key("openldap")
- seen.should have_key("apache2")
+ expect(seen).to have_key("openldap")
+ expect(seen).to have_key("apache2")
end
end
end # loading only one cookbook
@@ -279,8 +283,8 @@ describe Chef::CookbookLoader do
it "loads the correct cookbook" do
cookbook_version = cookbook_loader["name-mismatch"]
- cookbook_version.should be_a_kind_of(Chef::CookbookVersion)
- cookbook_version.name.should == :"name-mismatch"
+ expect(cookbook_version).to be_a_kind_of(Chef::CookbookVersion)
+ expect(cookbook_version.name).to eq(:"name-mismatch")
end
end
diff --git a/spec/unit/cookbook_manifest_spec.rb b/spec/unit/cookbook_manifest_spec.rb
index e87b8e1e9a..938f72c743 100644
--- a/spec/unit/cookbook_manifest_spec.rb
+++ b/spec/unit/cookbook_manifest_spec.rb
@@ -1,7 +1,6 @@
#
-# Author:: Tim Hinderliter (<tim@opscode.com>)
-# Author:: Christopher Walters (<cw@opscode.com>)
-# Copyright:: Copyright (c) 2010 Opscode, Inc.
+# Author:: Daniel DeLeo (<dan@chef.io>)
+# Copyright:: Copyright (c) 2015 Opscode, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,540 +14,214 @@
# 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 'spec_helper'
+require 'chef/cookbook_manifest'
+require 'chef/digester'
+require 'pathname'
-describe "Chef::CookbookVersion manifest" do
- before(:each) do
- @cookbook = Chef::CookbookVersion.new "test-cookbook"
- @cookbook.manifest = {
- "files" =>
- [
- # afile.rb
- {
- :name => "afile.rb",
- :path => "files/host-examplehost.example.org/afile.rb",
- :checksum => "csum-host",
- :specificity => "host-examplehost.example.org"
- },
- {
- :name => "afile.rb",
- :path => "files/ubuntu-9.10/afile.rb",
- :checksum => "csum-platver-full",
- :specificity => "ubuntu-9.10"
- },
- {
- :name => "afile.rb",
- :path => "files/newubuntu-9/afile.rb",
- :checksum => "csum-platver-partial",
- :specificity => "newubuntu-9"
- },
- {
- :name => "afile.rb",
- :path => "files/ubuntu/afile.rb",
- :checksum => "csum-plat",
- :specificity => "ubuntu"
- },
- {
- :name => "afile.rb",
- :path => "files/default/afile.rb",
- :checksum => "csum-default",
- :specificity => "default"
- },
-
- # for different/odd platform_versions
- {
- :name => "bfile.rb",
- :path => "files/fakeos-2.0.rc.1/bfile.rb",
- :checksum => "csum2-platver-full",
- :specificity => "fakeos-2.0.rc.1"
- },
- {
- :name => "bfile.rb",
- :path => "files/newfakeos-2.0.rc/bfile.rb",
- :checksum => "csum2-platver-partial",
- :specificity => "newfakeos-2.0.rc"
- },
- {
- :name => "bfile.rb",
- :path => "files/fakeos-maple tree/bfile.rb",
- :checksum => "csum3-platver-full",
- :specificity => "maple tree"
- },
- {
- :name => "bfile.rb",
- :path => "files/fakeos-1/bfile.rb",
- :checksum => "csum4-platver-full",
- :specificity => "fakeos-1"
- },
-
- # directory adirectory
- {
- :name => "anotherfile1.rb",
- :path => "files/host-examplehost.example.org/adirectory/anotherfile1.rb.host",
- :checksum => "csum-host-1",
- :specificity => "host-examplehost.example.org"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/host-examplehost.example.org/adirectory/anotherfile2.rb.host",
- :checksum => "csum-host-2",
- :specificity => "host-examplehost.example.org"
- },
-
- {
- :name => "anotherfile1.rb",
- :path => "files/ubuntu-9.10/adirectory/anotherfile1.rb.platform-full-version",
- :checksum => "csum-platver-full-1",
- :specificity => "ubuntu-9.10"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/ubuntu-9.10/adirectory/anotherfile2.rb.platform-full-version",
- :checksum => "csum-platver-full-2",
- :specificity => "ubuntu-9.10"
- },
-
- {
- :name => "anotherfile1.rb",
- :path => "files/newubuntu-9/adirectory/anotherfile1.rb.platform-partial-version",
- :checksum => "csum-platver-partial-1",
- :specificity => "newubuntu-9"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/newubuntu-9/adirectory/anotherfile2.rb.platform-partial-version",
- :checksum => "csum-platver-partial-2",
- :specificity => "nweubuntu-9"
- },
-
- {
- :name => "anotherfile1.rb",
- :path => "files/ubuntu/adirectory/anotherfile1.rb.platform",
- :checksum => "csum-plat-1",
- :specificity => "ubuntu"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/ubuntu/adirectory/anotherfile2.rb.platform",
- :checksum => "csum-plat-2",
- :specificity => "ubuntu"
- },
-
- {
- :name => "anotherfile1.rb",
- :path => "files/default/adirectory/anotherfile1.rb.default",
- :checksum => "csum-default-1",
- :specificity => "default"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/default/adirectory/anotherfile2.rb.default",
- :checksum => "csum-default-2",
- :specificity => "default"
- },
- # for different/odd platform_versions
- {
- :name => "anotherfile1.rb",
- :path => "files/fakeos-2.0.rc.1/adirectory/anotherfile1.rb.platform-full-version",
- :checksum => "csum2-platver-full-1",
- :specificity => "fakeos-2.0.rc.1"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/fakeos-2.0.rc.1/adirectory/anotherfile2.rb.platform-full-version",
- :checksum => "csum2-platver-full-2",
- :specificity => "fakeos-2.0.rc.1"
- },
- {
- :name => "anotherfile1.rb",
- :path => "files/newfakeos-2.0.rc.1/adirectory/anotherfile1.rb.platform-partial-version",
- :checksum => "csum2-platver-partial-1",
- :specificity => "newfakeos-2.0.rc"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/newfakeos-2.0.rc.1/adirectory/anotherfile2.rb.platform-partial-version",
- :checksum => "csum2-platver-partial-2",
- :specificity => "newfakeos-2.0.rc"
- },
- {
- :name => "anotherfile1.rb",
- :path => "files/fakeos-maple tree/adirectory/anotherfile1.rb.platform-full-version",
- :checksum => "csum3-platver-full-1",
- :specificity => "fakeos-maple tree"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/fakeos-maple tree/adirectory/anotherfile2.rb.platform-full-version",
- :checksum => "csum3-platver-full-2",
- :specificity => "fakeos-maple tree"
- },
- {
- :name => "anotherfile1.rb",
- :path => "files/fakeos-1/adirectory/anotherfile1.rb.platform-full-version",
- :checksum => "csum4-platver-full-1",
- :specificity => "fakeos-1"
- },
- {
- :name => "anotherfile2.rb",
- :path => "files/fakeos-1/adirectory/anotherfile2.rb.platform-full-version",
- :checksum => "csum4-platver-full-2",
- :specificity => "fakeos-1"
- },
- ]
- }
-
- end
-
-
- it "should return a manifest record based on priority preference: host" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "examplehost.example.org"
-
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
- manifest_record.should_not be_nil
- manifest_record[:checksum].should == "csum-host"
- end
-
- it "should return a manifest record based on priority preference: platform & full version" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
- manifest_record.should_not be_nil
- manifest_record[:checksum].should == "csum-platver-full"
- end
-
- it "should return a manifest record based on priority preference: platform & partial version" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "newubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
- manifest_record.should_not be_nil
- manifest_record[:checksum].should == "csum-platver-partial"
- end
+describe Chef::CookbookManifest do
- it "should return a manifest record based on priority preference: platform only" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "1.0"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ let(:version) { "1.2.3" }
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
- manifest_record.should_not be_nil
- manifest_record[:checksum].should == "csum-plat"
- end
-
- it "should return a manifest record based on priority preference: default" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "notubuntu"
- node.automatic_attrs[:platform_version] = "1.0"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
- manifest_record.should_not be_nil
- manifest_record[:checksum].should == "csum-default"
+ let(:metadata) do
+ Chef::Cookbook::Metadata.new.tap do |m|
+ m.version(version)
+ end
end
- it "should return a manifest record based on priority preference: platform & full version - platform_version variant 1" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "2.0.rc.1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ let(:cookbook_root) { '/tmp/blah' }
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
- manifest_record.should_not be_nil
- manifest_record[:checksum].should == "csum2-platver-full"
+ let(:cookbook_version) do
+ Chef::CookbookVersion.new("tatft", cookbook_root).tap do |c|
+ c.metadata = metadata
+ end
end
- it "should return a manifest record based on priority preference: platform & partial version - platform_version variant 1" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "newfakeos"
- node.automatic_attrs[:platform_version] = "2.0.rc.1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ let(:policy_mode) { false }
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
- manifest_record.should_not be_nil
- manifest_record[:checksum].should == "csum2-platver-partial"
- end
+ subject(:cookbook_manifest) { Chef::CookbookManifest.new(cookbook_version, policy_mode: policy_mode) }
- it "should return a manifest record based on priority preference: platform & full version - platform_version variant 2" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "maple tree"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ context "when policy mode is not specified" do
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
- manifest_record.should_not be_nil
- manifest_record[:checksum].should == "csum3-platver-full"
- end
+ subject(:cookbook_manifest) { Chef::CookbookManifest.new(cookbook_version) }
- it "should return a manifest record based on priority preference: platform & full version - platform_version variant 3" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ it "defaults to policies disabled" do
+ expect(cookbook_manifest.policy_mode?).to be(false)
+ end
- manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
- manifest_record.should_not be_nil
- manifest_record[:checksum].should == "csum4-platver-full"
end
- describe "when fetching the contents of a directory by file specificity" do
-
- it "should return a directory of manifest records based on priority preference: host" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "examplehost.example.org"
+ describe "collecting cookbook data from the cookbook version object" do
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- manifest_records.should_not be_nil
- manifest_records.size.should == 2
-
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- checksums.sort.should == ["csum-host-1", "csum-host-2"]
+ it "delegates `name' to cookbook_version" do
+ expect(cookbook_manifest.name).to eq("tatft")
end
- it "should return a directory of manifest records based on priority preference: platform & full version" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- manifest_records.should_not be_nil
- manifest_records.size.should == 2
-
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- checksums.sort.should == ["csum-platver-full-1", "csum-platver-full-2"]
+ it "delegates `root_paths' to cookbook_version" do
+ expect(cookbook_manifest.root_paths).to eq(['/tmp/blah'])
end
- it "should return a directory of manifest records based on priority preference: platform & partial version" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "newubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- manifest_records.should_not be_nil
- manifest_records.size.should == 2
-
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- checksums.sort.should == ["csum-platver-partial-1", "csum-platver-partial-2"]
+ it "delegates `metadata' to cookbook_version" do
+ expect(cookbook_manifest.metadata).to eq(metadata)
end
- it "should return a directory of manifest records based on priority preference: platform only" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "1.0"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- manifest_records.should_not be_nil
- manifest_records.size.should == 2
-
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- checksums.sort.should == ["csum-plat-1", "csum-plat-2"]
+ it "delegates `full_name' to cookbook_version" do
+ expect(cookbook_manifest.full_name).to eq("tatft-1.2.3")
end
- it "should return a directory of manifest records based on priority preference: default" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "notubuntu"
- node.automatic_attrs[:platform_version] = "1.0"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- manifest_records.should_not be_nil
- manifest_records.size.should == 2
-
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- checksums.sort.should == ["csum-default-1", "csum-default-2"]
+ it "delegates `version' to cookbook_version" do
+ expect(cookbook_manifest.version).to eq(version)
end
- it "should return a manifest record based on priority preference: platform & full version - platform_version variant 1" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "2.0.rc.1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- manifest_records.should_not be_nil
- manifest_records.size.should == 2
+ it "delegates `frozen_version?' to cookbook_version" do
+ expect(cookbook_manifest.frozen_version?).to be(false)
+ end
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- checksums.sort.should == ["csum2-platver-full-1", "csum2-platver-full-2"]
+ it "delegates `segment_filenames' to cookbook_version" do
+ expect(cookbook_version).to receive(:segment_filenames).with(:recipes).and_return([])
+ expect(cookbook_manifest.segment_filenames(:recipes)).to eq([])
end
- it "should return a manifest record based on priority preference: platform & partial version - platform_version variant 1" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "newfakeos"
- node.automatic_attrs[:platform_version] = "2.0.rc.1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ end
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- manifest_records.should_not be_nil
- manifest_records.size.should == 2
+ context "when given an empty cookbook" do
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- checksums.sort.should == ["csum2-platver-partial-1", "csum2-platver-partial-2"]
- end
+ let(:expected_hash) do
+ {
+ "chef_type" => "cookbook_version",
- it "should return a manifest record based on priority preference: platform & full version - platform_version variant 2" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "maple tree"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ "name" => "tatft-1.2.3",
+ "version" => "1.2.3",
+ "cookbook_name" => "tatft",
+ "metadata" => metadata,
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- manifest_records.should_not be_nil
- manifest_records.size.should == 2
+ "frozen?" => false,
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- checksums.sort.should == ["csum3-platver-full-1", "csum3-platver-full-2"]
+ "recipes" =>[],
+ "definitions" =>[],
+ "libraries" =>[],
+ "attributes" =>[],
+ "files" =>[],
+ "templates" =>[],
+ "resources" =>[],
+ "providers" =>[],
+ "root_files" =>[],
+ }
end
- it "should return a manifest record based on priority preference: platform & full version - platform_version variant 3" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
- manifest_records.should_not be_nil
- manifest_records.size.should == 2
-
- checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
- checksums.sort.should == ["csum4-platver-full-1", "csum4-platver-full-2"]
+ it "converts the CookbookVersion to a ruby Hash representation" do
+ expect(cookbook_manifest.to_hash).to eq(expected_hash)
end
+
end
- ## Globbing the relative paths out of the manifest records ##
+ context "when given a cookbook with files" do
- describe "when globbing for relative file paths based on filespecificity" do
- it "should return a list of relative paths based on priority preference: host" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "examplehost.example.org"
+ let(:cookbook_root) { File.join(CHEF_SPEC_DATA, 'cb_version_cookbooks', 'tatft') }
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- filenames.should_not be_nil
- filenames.size.should == 2
+ let(:attribute_filenames) { Dir[File.join(cookbook_root, 'attributes', '**', '*.rb')] }
+ let(:definition_filenames) { Dir[File.join(cookbook_root, 'definitions', '**', '*.rb')] }
+ let(:file_filenames) { Dir[File.join(cookbook_root, 'files', '**', '*.tgz')] }
+ let(:recipe_filenames) { Dir[File.join(cookbook_root, 'recipes', '**', '*.rb')] }
+ let(:template_filenames) { Dir[File.join(cookbook_root, 'templates', '**', '*.erb')] }
+ let(:library_filenames) { Dir[File.join(cookbook_root, 'libraries', '**', '*.rb')] }
+ let(:resource_filenames) { Dir[File.join(cookbook_root, 'resources', '**', '*.rb')] }
+ let(:provider_filenames) { Dir[File.join(cookbook_root, 'providers', '**', '*.rb')] }
+ let(:root_filenames) { Array(File.join(cookbook_root, 'README.rdoc')) }
+ let(:metadata_filenames) { Array(File.join(cookbook_root, 'metadata.json')) }
- filenames.sort.should == ['anotherfile1.rb.host', 'anotherfile2.rb.host']
- end
+ let(:match_md5) { /[0-9a-f]{32}/ }
- it "should return a list of relative paths based on priority preference: platform & full version" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ def map_to_file_specs(paths)
+ paths.map do |path|
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- filenames.should_not be_nil
- filenames.size.should == 2
+ relative_path = Pathname.new(path).relative_path_from(Pathname.new(cookbook_root)).to_s
- filenames.sort.should == ['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version']
+ {
+ "name" => File.basename(path),
+ "path" => relative_path,
+ "checksum" => Chef::Digester.generate_md5_checksum_for_file(path),
+ "specificity" => "default",
+ }
+ end
end
- it "should return a list of relative paths based on priority preference: platform & partial version" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "newubuntu"
- node.automatic_attrs[:platform_version] = "9.10"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- filenames.should_not be_nil
- filenames.size.should == 2
+ let(:expected_hash) do
+ {
+ "chef_type" => "cookbook_version",
- filenames.sort.should == ['anotherfile1.rb.platform-partial-version', 'anotherfile2.rb.platform-partial-version']
- end
-
- it "should return a list of relative paths based on priority preference: platform only" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "ubuntu"
- node.automatic_attrs[:platform_version] = "1.0"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ "name" => "tatft-1.2.3",
+ "version" => "1.2.3",
+ "cookbook_name" => "tatft",
+ "metadata" => metadata,
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- filenames.should_not be_nil
- filenames.size.should == 2
+ "frozen?" => false,
- filenames.sort.should == ['anotherfile1.rb.platform', 'anotherfile2.rb.platform']
+ "recipes" => map_to_file_specs(recipe_filenames),
+ "definitions" => map_to_file_specs(definition_filenames),
+ "libraries" => map_to_file_specs(library_filenames),
+ "attributes" => map_to_file_specs(attribute_filenames),
+ "files" => map_to_file_specs(file_filenames),
+ "templates" => map_to_file_specs(template_filenames),
+ "resources" => map_to_file_specs(resource_filenames),
+ "providers" => map_to_file_specs(provider_filenames),
+ "root_files" => map_to_file_specs(root_filenames),
+ }
end
- it "should return a list of relative paths based on priority preference: default" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "notubuntu"
- node.automatic_attrs[:platform_version] = "1.0"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ before do
+ cookbook_version.attribute_filenames = attribute_filenames
+ cookbook_version.definition_filenames = definition_filenames
+ cookbook_version.file_filenames = file_filenames
+ cookbook_version.recipe_filenames = recipe_filenames
+ cookbook_version.template_filenames = template_filenames
+ cookbook_version.library_filenames = library_filenames
+ cookbook_version.resource_filenames = resource_filenames
+ cookbook_version.provider_filenames = provider_filenames
+ cookbook_version.root_filenames = root_filenames
+ cookbook_version.metadata_filenames = metadata_filenames
+ end
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- filenames.should_not be_nil
- filenames.size.should == 2
+ it "converts the CookbookVersion to a ruby Hash representation" do
+ cookbook_manifest_hash = cookbook_manifest.to_hash
- filenames.sort.should == ['anotherfile1.rb.default', 'anotherfile2.rb.default']
+ expect(cookbook_manifest_hash.keys).to match_array(expected_hash.keys)
+ cookbook_manifest_hash.each do |key, value|
+ expect(cookbook_manifest_hash[key]).to eq(expected_hash[key])
+ end
end
- it "should return a list of relative paths based on priority preference: platform & full version - platform_version variant 1" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "2.0.rc.1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ end
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- filenames.should_not be_nil
- filenames.size.should == 2
+ describe "providing upstream URLs for save" do
- filenames.sort.should == ['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version']
- end
+ context "and policy mode is disabled" do
- it "should return a list of relative paths based on priority preference: platform & partial version - platform_version variant 1" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "newfakeos"
- node.automatic_attrs[:platform_version] = "2.0.rc.1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ it "gives the save URL" do
+ expect(cookbook_manifest.save_url).to eq("cookbooks/tatft/1.2.3")
+ end
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- filenames.should_not be_nil
- filenames.size.should == 2
+ it "gives the force save URL" do
+ expect(cookbook_manifest.force_save_url).to eq("cookbooks/tatft/1.2.3?force=true")
+ end
- filenames.sort.should == ['anotherfile1.rb.platform-partial-version', 'anotherfile2.rb.platform-partial-version']
end
- it "should return a list of relative paths based on priority preference: platform & full version - platform_version variant 2" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "maple tree"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
-
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- filenames.should_not be_nil
- filenames.size.should == 2
+ context "and policy mode is enabled" do
- filenames.sort.should == ['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version']
- end
+ let(:policy_mode) { true }
- it "should return a list of relative paths based on priority preference: platform & full version - platform_version variant 3" do
- node = Chef::Node.new
- node.automatic_attrs[:platform] = "fakeos"
- node.automatic_attrs[:platform_version] = "1"
- node.automatic_attrs[:fqdn] = "differenthost.example.org"
+ it "gives the save URL" do
+ expect(cookbook_manifest.save_url).to eq("cookbook_artifacts/tatft/1.2.3")
+ end
- filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
- filenames.should_not be_nil
- filenames.size.should == 2
+ it "gives the force save URL" do
+ expect(cookbook_manifest.force_save_url).to eq("cookbook_artifacts/tatft/1.2.3?force=true")
+ end
- filenames.sort.should == ['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version']
end
end
+
end
+
diff --git a/spec/unit/cookbook_site_streaming_uploader_spec.rb b/spec/unit/cookbook_site_streaming_uploader_spec.rb
index 1d7009e31c..ef0f649163 100644
--- a/spec/unit/cookbook_site_streaming_uploader_spec.rb
+++ b/spec/unit/cookbook_site_streaming_uploader_spec.rb
@@ -42,16 +42,16 @@ describe Chef::CookbookSiteStreamingUploader do
@cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, 'cookbooks'))
@loader = Chef::CookbookLoader.new(@cookbook_repo)
@loader.load_cookbooks
- File.stub(:unlink).and_return()
+ allow(File).to receive(:unlink)
end
it "should create the cookbook tmp dir" do
cookbook = @loader[:openldap]
files_count = Dir.glob(File.join(@cookbook_repo, cookbook.name.to_s, '**', '*'), File::FNM_DOTMATCH).count { |file| File.file?(file) }
- Tempfile.should_receive(:new).with("chef-#{cookbook.name}-build").and_return(FakeTempfile.new("chef-#{cookbook.name}-build"))
- FileUtils.should_receive(:mkdir_p).exactly(files_count + 1).times
- FileUtils.should_receive(:cp).exactly(files_count).times
+ expect(Tempfile).to receive(:new).with("chef-#{cookbook.name}-build").and_return(FakeTempfile.new("chef-#{cookbook.name}-build"))
+ expect(FileUtils).to receive(:mkdir_p).exactly(files_count + 1).times
+ expect(FileUtils).to receive(:cp).exactly(files_count).times
Chef::CookbookSiteStreamingUploader.create_build_dir(cookbook)
end
@@ -64,39 +64,39 @@ describe Chef::CookbookSiteStreamingUploader do
@secret_filename = File.join(CHEF_SPEC_DATA, 'ssl/private_key.pem')
@rsa_key = File.read(@secret_filename)
response = Net::HTTPResponse.new('1.0', '200', 'OK')
- Net::HTTP.any_instance.stub(:request).and_return(response)
+ allow_any_instance_of(Net::HTTP).to receive(:request).and_return(response)
end
it "should send an http request" do
- Net::HTTP.any_instance.should_receive(:request)
+ expect_any_instance_of(Net::HTTP).to receive(:request)
Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, 'bill', @secret_filename)
end
it "should read the private key file" do
- File.should_receive(:read).with(@secret_filename).and_return(@rsa_key)
+ expect(File).to receive(:read).with(@secret_filename).and_return(@rsa_key)
Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, 'bill', @secret_filename)
end
it "should add the authentication signed header" do
- Mixlib::Authentication::SigningObject.any_instance.should_receive(:sign).and_return({})
+ expect_any_instance_of(Mixlib::Authentication::SigningObject).to receive(:sign).and_return({})
Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, 'bill', @secret_filename)
end
it "should be able to send post requests" do
post = Net::HTTP::Post.new(@uri, {})
- Net::HTTP::Post.should_receive(:new).once.and_return(post)
- Net::HTTP::Put.should_not_receive(:new)
- Net::HTTP::Get.should_not_receive(:new)
+ expect(Net::HTTP::Post).to receive(:new).once.and_return(post)
+ expect(Net::HTTP::Put).not_to receive(:new)
+ expect(Net::HTTP::Get).not_to receive(:new)
Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, 'bill', @secret_filename)
end
it "should be able to send put requests" do
put = Net::HTTP::Put.new(@uri, {})
- Net::HTTP::Post.should_not_receive(:new)
- Net::HTTP::Put.should_receive(:new).once.and_return(put)
- Net::HTTP::Get.should_not_receive(:new)
+ expect(Net::HTTP::Post).not_to receive(:new)
+ expect(Net::HTTP::Put).to receive(:new).once.and_return(put)
+ expect(Net::HTTP::Get).not_to receive(:new)
Chef::CookbookSiteStreamingUploader.make_request(:put, @uri, 'bill', @secret_filename)
end
@@ -126,19 +126,19 @@ describe Chef::CookbookSiteStreamingUploader do
@uri = "https://cookbooks.dummy.com/api/v1/cookbooks"
uri_info = URI.parse(@uri)
@http = Net::HTTP.new(uri_info.host, uri_info.port)
- Net::HTTP.should_receive(:new).with(uri_info.host, uri_info.port).and_return(@http)
+ expect(Net::HTTP).to receive(:new).with(uri_info.host, uri_info.port).and_return(@http)
end
it "should be VERIFY_NONE when ssl_verify_mode is :verify_none" do
Chef::Config[:ssl_verify_mode] = :verify_none
Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, 'bill', @secret_filename)
- @http.verify_mode.should == OpenSSL::SSL::VERIFY_NONE
+ expect(@http.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE)
end
it "should be VERIFY_PEER when ssl_verify_mode is :verify_peer" do
Chef::Config[:ssl_verify_mode] = :verify_peer
Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, 'bill', @secret_filename)
- @http.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
+ expect(@http.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER)
end
end
@@ -151,17 +151,17 @@ describe Chef::CookbookSiteStreamingUploader do
end
it "should create a StreamPart" do
- @stream_part.should be_instance_of(Chef::CookbookSiteStreamingUploader::StreamPart)
+ expect(@stream_part).to be_instance_of(Chef::CookbookSiteStreamingUploader::StreamPart)
end
it "should expose its size" do
- @stream_part.size.should eql(File.size(@file))
+ expect(@stream_part.size).to eql(File.size(@file))
end
it "should read with offset and how_much" do
content = @file.read(4)
@file.rewind
- @stream_part.read(0, 4).should eql(content)
+ expect(@stream_part.read(0, 4)).to eql(content)
end
end # StreamPart
@@ -173,15 +173,15 @@ describe Chef::CookbookSiteStreamingUploader do
end
it "should create a StringPart" do
- @string_part.should be_instance_of(Chef::CookbookSiteStreamingUploader::StringPart)
+ expect(@string_part).to be_instance_of(Chef::CookbookSiteStreamingUploader::StringPart)
end
it "should expose its size" do
- @string_part.size.should eql(@str.size)
+ expect(@string_part.size).to eql(@str.size)
end
it "should read with offset and how_much" do
- @string_part.read(2, 4).should eql(@str[2, 4])
+ expect(@string_part.read(2, 4)).to eql(@str[2, 4])
end
end # StringPart
@@ -198,21 +198,21 @@ describe Chef::CookbookSiteStreamingUploader do
end
it "should create a MultipartStream" do
- @multipart_stream.should be_instance_of(Chef::CookbookSiteStreamingUploader::MultipartStream)
+ expect(@multipart_stream).to be_instance_of(Chef::CookbookSiteStreamingUploader::MultipartStream)
end
it "should expose its size" do
- @multipart_stream.size.should eql(@stream1.size + @stream2.size)
+ expect(@multipart_stream.size).to eql(@stream1.size + @stream2.size)
end
it "should read with how_much" do
- @multipart_stream.read(10).should eql("#{@string1}#{@string2}"[0, 10])
+ expect(@multipart_stream.read(10)).to eql("#{@string1}#{@string2}"[0, 10])
end
it "should read receiving destination buffer as second argument (CHEF-4456: Ruby 2 compat)" do
dst_buf = ''
@multipart_stream.read(10, dst_buf)
- dst_buf.should eql("#{@string1}#{@string2}"[0, 10])
+ expect(dst_buf).to eql("#{@string1}#{@string2}"[0, 10])
end
end # MultipartStream
diff --git a/spec/unit/cookbook_spec.rb b/spec/unit/cookbook_spec.rb
index 9bcea97d98..7b3cda2af1 100644
--- a/spec/unit/cookbook_spec.rb
+++ b/spec/unit/cookbook_spec.rb
@@ -33,43 +33,43 @@ describe Chef::CookbookVersion do
end
it "should have a name" do
- @cookbook.name.should == :openldap
+ expect(@cookbook.name).to eq(:openldap)
end
it "should allow you to set the list of attribute files and create the mapping from short names to paths" do
@cookbook.attribute_filenames = [ "attributes/one.rb", "attributes/two.rb" ]
- @cookbook.attribute_filenames.should == [ "attributes/one.rb", "attributes/two.rb" ]
- @cookbook.attribute_filenames_by_short_filename.keys.sort.should eql(["one", "two"])
- @cookbook.attribute_filenames_by_short_filename["one"].should == "attributes/one.rb"
- @cookbook.attribute_filenames_by_short_filename["two"].should == "attributes/two.rb"
+ expect(@cookbook.attribute_filenames).to eq([ "attributes/one.rb", "attributes/two.rb" ])
+ expect(@cookbook.attribute_filenames_by_short_filename.keys.sort).to eql(["one", "two"])
+ expect(@cookbook.attribute_filenames_by_short_filename["one"]).to eq("attributes/one.rb")
+ expect(@cookbook.attribute_filenames_by_short_filename["two"]).to eq("attributes/two.rb")
end
it "should allow you to set the list of recipe files and create the mapping of recipe short name to filename" do
@cookbook.recipe_filenames = [ "recipes/one.rb", "recipes/two.rb" ]
- @cookbook.recipe_filenames.should == [ "recipes/one.rb", "recipes/two.rb" ]
- @cookbook.recipe_filenames_by_name.keys.sort.should eql(["one", "two"])
- @cookbook.recipe_filenames_by_name["one"].should == "recipes/one.rb"
- @cookbook.recipe_filenames_by_name["two"].should == "recipes/two.rb"
+ expect(@cookbook.recipe_filenames).to eq([ "recipes/one.rb", "recipes/two.rb" ])
+ expect(@cookbook.recipe_filenames_by_name.keys.sort).to eql(["one", "two"])
+ expect(@cookbook.recipe_filenames_by_name["one"]).to eq("recipes/one.rb")
+ expect(@cookbook.recipe_filenames_by_name["two"]).to eq("recipes/two.rb")
end
it "should generate a list of recipes by fully-qualified name" do
@cookbook.recipe_filenames = [ "recipes/one.rb", "/recipes/two.rb", "three.rb" ]
- @cookbook.fully_qualified_recipe_names.include?("openldap::one").should == true
- @cookbook.fully_qualified_recipe_names.include?("openldap::two").should == true
- @cookbook.fully_qualified_recipe_names.include?("openldap::three").should == true
+ expect(@cookbook.fully_qualified_recipe_names.include?("openldap::one")).to eq(true)
+ expect(@cookbook.fully_qualified_recipe_names.include?("openldap::two")).to eq(true)
+ expect(@cookbook.fully_qualified_recipe_names.include?("openldap::three")).to eq(true)
end
it "should find a preferred file" do
- pending
+ skip
end
it "should not return an unchanged preferred file" do
pending
- @cookbook.preferred_filename(@node, :files, 'a-filename', 'the-checksum').should be_nil
+ expect(@cookbook.preferred_filename(@node, :files, 'a-filename', 'the-checksum')).to be_nil
end
it "should raise an ArgumentException if you try to load a bad recipe name" do
- lambda { @cookbook.load_recipe("doesnt_exist", @node) }.should raise_error(ArgumentError)
+ expect { @cookbook.load_recipe("doesnt_exist", @node) }.to raise_error(ArgumentError)
end
end
diff --git a/spec/unit/cookbook_uploader_spec.rb b/spec/unit/cookbook_uploader_spec.rb
index af25baff13..152e5373f0 100644
--- a/spec/unit/cookbook_uploader_spec.rb
+++ b/spec/unit/cookbook_uploader_spec.rb
@@ -45,7 +45,13 @@ describe Chef::CookbookUploader do
let(:sandbox_commit_uri) { "https://chef.example.org/sandboxes/abc123" }
- let(:uploader) { described_class.new(cookbooks_to_upload, :rest => http_client) }
+ let(:policy_mode) { false }
+
+ let(:uploader) { described_class.new(cookbooks_to_upload, rest: http_client, policy_mode: policy_mode) }
+
+ it "defaults to not enabling policy mode" do
+ expect(described_class.new(cookbooks_to_upload, rest: http_client).policy_mode?).to be(false)
+ end
it "has a list of cookbooks to upload" do
expect(uploader.cookbooks).to eq(cookbooks_to_upload)
@@ -61,7 +67,7 @@ describe Chef::CookbookUploader do
describe "uploading cookbooks" do
def url_for(cksum)
- "https://storage.example.com/#{cksum}"
+ "https://storage.example.com/#{cksum}"
end
let(:sandbox_response) do
@@ -94,6 +100,10 @@ describe Chef::CookbookUploader do
end
end
+ def expected_save_url(cookbook)
+ "cookbooks/#{cookbook.name}/#{cookbook.version}"
+ end
+
def expect_sandbox_commit
expect(http_client).to receive(:put).with(sandbox_commit_uri, {:is_completed => true})
end
@@ -102,7 +112,7 @@ describe Chef::CookbookUploader do
cookbooks_to_upload.each do |cookbook|
expect(http_client).to receive(:put).
- with(cookbook.save_url, cookbook)
+ with(expected_save_url(cookbook), cookbook)
end
end
@@ -155,6 +165,30 @@ describe Chef::CookbookUploader do
end
end
+
+ context "when policy_mode is specified" do
+
+ let(:cksums_not_on_remote) do
+ checksums_of_cookbook_files.keys
+ end
+
+ let(:policy_mode) { true }
+
+ def expected_save_url(cookbook)
+ "cookbook_artifacts/#{cookbook.name}/#{cookbook.version}"
+ end
+
+ it "uploads all files in a sandbox transaction, then creates cookbooks on the server using cookbook_artifacts API" do
+ expect_sandbox_create
+ expect_checksum_upload
+ expect_sandbox_commit
+ expect_cookbook_create
+
+ uploader.upload_cookbooks
+ end
+
+
+ end
end
end
diff --git a/spec/unit/cookbook_version_file_specificity_spec.rb b/spec/unit/cookbook_version_file_specificity_spec.rb
new file mode 100644
index 0000000000..73b10899d4
--- /dev/null
+++ b/spec/unit/cookbook_version_file_specificity_spec.rb
@@ -0,0 +1,554 @@
+#
+# Author:: Tim Hinderliter (<tim@opscode.com>)
+# Author:: Christopher Walters (<cw@opscode.com>)
+# Copyright:: Copyright (c) 2010 Opscode, 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 'spec_helper'
+
+describe Chef::CookbookVersion, "file specificity" do
+ before(:each) do
+ @cookbook = Chef::CookbookVersion.new "test-cookbook"
+ @cookbook.manifest = {
+ "files" =>
+ [
+ # afile.rb
+ {
+ :name => "afile.rb",
+ :path => "files/host-examplehost.example.org/afile.rb",
+ :checksum => "csum-host",
+ :specificity => "host-examplehost.example.org"
+ },
+ {
+ :name => "afile.rb",
+ :path => "files/ubuntu-9.10/afile.rb",
+ :checksum => "csum-platver-full",
+ :specificity => "ubuntu-9.10"
+ },
+ {
+ :name => "afile.rb",
+ :path => "files/newubuntu-9/afile.rb",
+ :checksum => "csum-platver-partial",
+ :specificity => "newubuntu-9"
+ },
+ {
+ :name => "afile.rb",
+ :path => "files/ubuntu/afile.rb",
+ :checksum => "csum-plat",
+ :specificity => "ubuntu"
+ },
+ {
+ :name => "afile.rb",
+ :path => "files/default/afile.rb",
+ :checksum => "csum-default",
+ :specificity => "default"
+ },
+
+ # for different/odd platform_versions
+ {
+ :name => "bfile.rb",
+ :path => "files/fakeos-2.0.rc.1/bfile.rb",
+ :checksum => "csum2-platver-full",
+ :specificity => "fakeos-2.0.rc.1"
+ },
+ {
+ :name => "bfile.rb",
+ :path => "files/newfakeos-2.0.rc/bfile.rb",
+ :checksum => "csum2-platver-partial",
+ :specificity => "newfakeos-2.0.rc"
+ },
+ {
+ :name => "bfile.rb",
+ :path => "files/fakeos-maple tree/bfile.rb",
+ :checksum => "csum3-platver-full",
+ :specificity => "maple tree"
+ },
+ {
+ :name => "bfile.rb",
+ :path => "files/fakeos-1/bfile.rb",
+ :checksum => "csum4-platver-full",
+ :specificity => "fakeos-1"
+ },
+
+ # directory adirectory
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/host-examplehost.example.org/adirectory/anotherfile1.rb.host",
+ :checksum => "csum-host-1",
+ :specificity => "host-examplehost.example.org"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/host-examplehost.example.org/adirectory/anotherfile2.rb.host",
+ :checksum => "csum-host-2",
+ :specificity => "host-examplehost.example.org"
+ },
+
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/ubuntu-9.10/adirectory/anotherfile1.rb.platform-full-version",
+ :checksum => "csum-platver-full-1",
+ :specificity => "ubuntu-9.10"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/ubuntu-9.10/adirectory/anotherfile2.rb.platform-full-version",
+ :checksum => "csum-platver-full-2",
+ :specificity => "ubuntu-9.10"
+ },
+
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/newubuntu-9/adirectory/anotherfile1.rb.platform-partial-version",
+ :checksum => "csum-platver-partial-1",
+ :specificity => "newubuntu-9"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/newubuntu-9/adirectory/anotherfile2.rb.platform-partial-version",
+ :checksum => "csum-platver-partial-2",
+ :specificity => "nweubuntu-9"
+ },
+
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/ubuntu/adirectory/anotherfile1.rb.platform",
+ :checksum => "csum-plat-1",
+ :specificity => "ubuntu"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/ubuntu/adirectory/anotherfile2.rb.platform",
+ :checksum => "csum-plat-2",
+ :specificity => "ubuntu"
+ },
+
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/default/adirectory/anotherfile1.rb.default",
+ :checksum => "csum-default-1",
+ :specificity => "default"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/default/adirectory/anotherfile2.rb.default",
+ :checksum => "csum-default-2",
+ :specificity => "default"
+ },
+ # for different/odd platform_versions
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/fakeos-2.0.rc.1/adirectory/anotherfile1.rb.platform-full-version",
+ :checksum => "csum2-platver-full-1",
+ :specificity => "fakeos-2.0.rc.1"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/fakeos-2.0.rc.1/adirectory/anotherfile2.rb.platform-full-version",
+ :checksum => "csum2-platver-full-2",
+ :specificity => "fakeos-2.0.rc.1"
+ },
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/newfakeos-2.0.rc.1/adirectory/anotherfile1.rb.platform-partial-version",
+ :checksum => "csum2-platver-partial-1",
+ :specificity => "newfakeos-2.0.rc"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/newfakeos-2.0.rc.1/adirectory/anotherfile2.rb.platform-partial-version",
+ :checksum => "csum2-platver-partial-2",
+ :specificity => "newfakeos-2.0.rc"
+ },
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/fakeos-maple tree/adirectory/anotherfile1.rb.platform-full-version",
+ :checksum => "csum3-platver-full-1",
+ :specificity => "fakeos-maple tree"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/fakeos-maple tree/adirectory/anotherfile2.rb.platform-full-version",
+ :checksum => "csum3-platver-full-2",
+ :specificity => "fakeos-maple tree"
+ },
+ {
+ :name => "anotherfile1.rb",
+ :path => "files/fakeos-1/adirectory/anotherfile1.rb.platform-full-version",
+ :checksum => "csum4-platver-full-1",
+ :specificity => "fakeos-1"
+ },
+ {
+ :name => "anotherfile2.rb",
+ :path => "files/fakeos-1/adirectory/anotherfile2.rb.platform-full-version",
+ :checksum => "csum4-platver-full-2",
+ :specificity => "fakeos-1"
+ },
+ ]
+ }
+
+ end
+
+
+ it "should return a manifest record based on priority preference: host" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "examplehost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum-host")
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum-platver-full")
+ end
+
+ it "should return a manifest record based on priority preference: platform & partial version" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "newubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum-platver-partial")
+ end
+
+ it "should return a manifest record based on priority preference: platform only" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "1.0"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum-plat")
+ end
+
+ it "should return a manifest record based on priority preference: default" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "notubuntu"
+ node.automatic_attrs[:platform_version] = "1.0"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "afile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum-default")
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version - platform_version variant 1" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "2.0.rc.1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum2-platver-full")
+ end
+
+ it "should return a manifest record based on priority preference: platform & partial version - platform_version variant 1" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "newfakeos"
+ node.automatic_attrs[:platform_version] = "2.0.rc.1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum2-platver-partial")
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version - platform_version variant 2" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "maple tree"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum3-platver-full")
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version - platform_version variant 3" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_record = @cookbook.preferred_manifest_record(node, :files, "bfile.rb")
+ expect(manifest_record).not_to be_nil
+ expect(manifest_record[:checksum]).to eq("csum4-platver-full")
+ end
+
+ describe "when fetching the contents of a directory by file specificity" do
+
+ it "should return a directory of manifest records based on priority preference: host" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "examplehost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum-host-1", "csum-host-2"])
+ end
+
+ it "should return a directory of manifest records based on priority preference: platform & full version" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum-platver-full-1", "csum-platver-full-2"])
+ end
+
+ it "should return a directory of manifest records based on priority preference: platform & partial version" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "newubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum-platver-partial-1", "csum-platver-partial-2"])
+ end
+
+ it "should return a directory of manifest records based on priority preference: platform only" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "1.0"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum-plat-1", "csum-plat-2"])
+ end
+
+ it "should return a directory of manifest records based on priority preference: default" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "notubuntu"
+ node.automatic_attrs[:platform_version] = "1.0"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum-default-1", "csum-default-2"])
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version - platform_version variant 1" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "2.0.rc.1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum2-platver-full-1", "csum2-platver-full-2"])
+ end
+
+ it "should return a manifest record based on priority preference: platform & partial version - platform_version variant 1" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "newfakeos"
+ node.automatic_attrs[:platform_version] = "2.0.rc.1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum2-platver-partial-1", "csum2-platver-partial-2"])
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version - platform_version variant 2" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "maple tree"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum3-platver-full-1", "csum3-platver-full-2"])
+ end
+
+ it "should return a manifest record based on priority preference: platform & full version - platform_version variant 3" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ manifest_records = @cookbook.preferred_manifest_records_for_directory(node, :files, "adirectory")
+ expect(manifest_records).not_to be_nil
+ expect(manifest_records.size).to eq(2)
+
+ checksums = manifest_records.map{ |manifest_record| manifest_record[:checksum] }
+ expect(checksums.sort).to eq(["csum4-platver-full-1", "csum4-platver-full-2"])
+ end
+ end
+
+ ## Globbing the relative paths out of the manifest records ##
+
+ describe "when globbing for relative file paths based on filespecificity" do
+ it "should return a list of relative paths based on priority preference: host" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "examplehost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.host', 'anotherfile2.rb.host'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform & full version" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform & partial version" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "newubuntu"
+ node.automatic_attrs[:platform_version] = "9.10"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform-partial-version', 'anotherfile2.rb.platform-partial-version'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform only" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "ubuntu"
+ node.automatic_attrs[:platform_version] = "1.0"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform', 'anotherfile2.rb.platform'])
+ end
+
+ it "should return a list of relative paths based on priority preference: default" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "notubuntu"
+ node.automatic_attrs[:platform_version] = "1.0"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.default', 'anotherfile2.rb.default'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform & full version - platform_version variant 1" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "2.0.rc.1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform & partial version - platform_version variant 1" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "newfakeos"
+ node.automatic_attrs[:platform_version] = "2.0.rc.1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform-partial-version', 'anotherfile2.rb.platform-partial-version'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform & full version - platform_version variant 2" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "maple tree"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version'])
+ end
+
+ it "should return a list of relative paths based on priority preference: platform & full version - platform_version variant 3" do
+ node = Chef::Node.new
+ node.automatic_attrs[:platform] = "fakeos"
+ node.automatic_attrs[:platform_version] = "1"
+ node.automatic_attrs[:fqdn] = "differenthost.example.org"
+
+ filenames = @cookbook.relative_filenames_in_preferred_directory(node, :files, "adirectory")
+ expect(filenames).not_to be_nil
+ expect(filenames.size).to eq(2)
+
+ expect(filenames.sort).to eq(['anotherfile1.rb.platform-full-version', 'anotherfile2.rb.platform-full-version'])
+ end
+ end
+end
diff --git a/spec/unit/cookbook_version_spec.rb b/spec/unit/cookbook_version_spec.rb
index 8436e5c480..440dd9da6c 100644
--- a/spec/unit/cookbook_version_spec.rb
+++ b/spec/unit/cookbook_version_spec.rb
@@ -24,76 +24,54 @@ describe Chef::CookbookVersion do
end
it "has a name" do
- @cookbook_version.name.should == 'tatft'
+ expect(@cookbook_version.name).to eq('tatft')
end
it "has no attribute files" do
- @cookbook_version.attribute_filenames.should be_empty
+ expect(@cookbook_version.attribute_filenames).to be_empty
end
it "has no resource definition files" do
- @cookbook_version.definition_filenames.should be_empty
+ expect(@cookbook_version.definition_filenames).to be_empty
end
it "has no cookbook files" do
- @cookbook_version.file_filenames.should be_empty
+ expect(@cookbook_version.file_filenames).to be_empty
end
it "has no recipe files" do
- @cookbook_version.recipe_filenames.should be_empty
+ expect(@cookbook_version.recipe_filenames).to be_empty
end
it "has no library files" do
- @cookbook_version.library_filenames.should be_empty
+ expect(@cookbook_version.library_filenames).to be_empty
end
it "has no LWRP resource files" do
- @cookbook_version.resource_filenames.should be_empty
+ expect(@cookbook_version.resource_filenames).to be_empty
end
it "has no LWRP provider files" do
- @cookbook_version.provider_filenames.should be_empty
+ expect(@cookbook_version.provider_filenames).to be_empty
end
it "has no metadata files" do
- @cookbook_version.metadata_filenames.should be_empty
+ expect(@cookbook_version.metadata_filenames).to be_empty
end
it "is not frozen" do
- @cookbook_version.should_not be_frozen_version
+ expect(@cookbook_version).not_to be_frozen_version
end
it "can be frozen" do
@cookbook_version.freeze_version
- @cookbook_version.should be_frozen_version
- end
-
- it "is \"ready\"" do
- # WTF is this? what are the valid states? and why aren't they set with encapsulating methods?
- # [Dan 15-Jul-2010]
- @cookbook_version.status.should == :ready
+ expect(@cookbook_version).to be_frozen_version
end
it "has empty metadata" do
- @cookbook_version.metadata.should == Chef::Cookbook::Metadata.new
- end
-
- it "creates a manifest hash of its contents" do
- expected = {"recipes"=>[],
- "definitions"=>[],
- "libraries"=>[],
- "attributes"=>[],
- "files"=>[],
- "templates"=>[],
- "resources"=>[],
- "providers"=>[],
- "root_files"=>[],
- "cookbook_name"=>"tatft",
- "metadata"=>Chef::Cookbook::Metadata.new,
- "version"=>"0.0.0",
- "name"=>"tatft-0.0.0"}
- @cookbook_version.manifest.should == expected
+ expect(@cookbook_version.metadata).to eq(Chef::Cookbook::Metadata.new)
end
+
end
describe "with a cookbook directory named tatft" do
@@ -141,93 +119,14 @@ describe Chef::CookbookVersion do
@node.name("testing")
end
- it "generates a manifest containing the cookbook's files" do
- manifest = @cookbook_version.manifest
-
- manifest["metadata"].should == Chef::Cookbook::Metadata.new
- manifest["cookbook_name"].should == "tatft"
-
- manifest["recipes"].should have(1).recipe_file
-
- recipe = manifest["recipes"].first
- recipe["name"].should == "default.rb"
- recipe["path"].should == "recipes/default.rb"
- recipe["checksum"].should match(MD5)
- recipe["specificity"].should == "default"
-
- manifest["definitions"].should have(1).definition_file
-
- definition = manifest["definitions"].first
- definition["name"].should == "runit_service.rb"
- definition["path"].should == "definitions/runit_service.rb"
- definition["checksum"].should match(MD5)
- definition["specificity"].should == "default"
-
- manifest["libraries"].should have(1).library_file
-
- library = manifest["libraries"].first
- library["name"].should == "ownage.rb"
- library["path"].should == "libraries/ownage.rb"
- library["checksum"].should match(MD5)
- library["specificity"].should == "default"
-
- manifest["attributes"].should have(1).attribute_file
-
- attribute_file = manifest["attributes"].first
- attribute_file["name"].should == "default.rb"
- attribute_file["path"].should == "attributes/default.rb"
- attribute_file["checksum"].should match(MD5)
- attribute_file["specificity"].should == "default"
-
- manifest["files"].should have(1).cookbook_file
-
- cookbook_file = manifest["files"].first
- cookbook_file["name"].should == "giant_blob.tgz"
- cookbook_file["path"].should == "files/default/giant_blob.tgz"
- cookbook_file["checksum"].should match(MD5)
- cookbook_file["specificity"].should == "default"
-
- manifest["templates"].should have(1).template
-
- template = manifest["templates"].first
- template["name"].should == "configuration.erb"
- template["path"].should == "templates/default/configuration.erb"
- template["checksum"].should match(MD5)
- template["specificity"].should == "default"
-
- manifest["resources"].should have(1).lwr
-
- lwr = manifest["resources"].first
- lwr["name"].should == "lwr.rb"
- lwr["path"].should == "resources/lwr.rb"
- lwr["checksum"].should match(MD5)
- lwr["specificity"].should == "default"
-
- manifest["providers"].should have(1).lwp
-
- lwp = manifest["providers"].first
- lwp["name"].should == "lwp.rb"
- lwp["path"].should == "providers/lwp.rb"
- lwp["checksum"].should match(MD5)
- lwp["specificity"].should == "default"
-
- manifest["root_files"].should have(1).file_in_the_cookbook_root
-
- readme = manifest["root_files"].first
- readme["name"].should == "README.rdoc"
- readme["path"].should == "README.rdoc"
- readme["checksum"].should match(MD5)
- readme["specificity"].should == "default"
- end
-
it "determines whether a template is available for a given node" do
- @cookbook_version.should have_template_for_node(@node, "configuration.erb")
- @cookbook_version.should_not have_template_for_node(@node, "missing.erb")
+ expect(@cookbook_version).to have_template_for_node(@node, "configuration.erb")
+ expect(@cookbook_version).not_to have_template_for_node(@node, "missing.erb")
end
it "determines whether a cookbook_file is available for a given node" do
- @cookbook_version.should have_cookbook_file_for_node(@node, "giant_blob.tgz")
- @cookbook_version.should_not have_cookbook_file_for_node(@node, "missing.txt")
+ expect(@cookbook_version).to have_cookbook_file_for_node(@node, "giant_blob.tgz")
+ expect(@cookbook_version).not_to have_cookbook_file_for_node(@node, "missing.txt")
end
describe "raises an error when attempting to load a missing cookbook_file and" do
@@ -243,112 +142,16 @@ describe Chef::CookbookVersion do
it "describes the cookbook and version" do
useful_explanation = Regexp.new(Regexp.escape("Cookbook 'tatft' (0.0.0) does not contain"))
- @attempt_to_load_file.should raise_error(Chef::Exceptions::FileNotFound, useful_explanation)
+ expect(@attempt_to_load_file).to raise_error(Chef::Exceptions::FileNotFound, useful_explanation)
end
it "lists suggested places to look" do
useful_explanation = Regexp.new(Regexp.escape("files/default/no-such-thing.txt"))
- @attempt_to_load_file.should raise_error(Chef::Exceptions::FileNotFound, useful_explanation)
+ expect(@attempt_to_load_file).to raise_error(Chef::Exceptions::FileNotFound, useful_explanation)
end
end
end
- describe "and a cookbook_version with a different name" do
- before do
- # Currently the cookbook loader finds all the files then tells CookbookVersion
- # where they are.
- @cookbook_version = Chef::CookbookVersion.new("blarghle", @cookbook_root)
- @cookbook_version.attribute_filenames = @cookbook[:attribute_filenames]
- @cookbook_version.definition_filenames = @cookbook[:definition_filenames]
- @cookbook_version.recipe_filenames = @cookbook[:recipe_filenames]
- @cookbook_version.template_filenames = @cookbook[:template_filenames]
- @cookbook_version.file_filenames = @cookbook[:file_filenames]
- @cookbook_version.library_filenames = @cookbook[:library_filenames]
- @cookbook_version.resource_filenames = @cookbook[:resource_filenames]
- @cookbook_version.provider_filenames = @cookbook[:provider_filenames]
- @cookbook_version.root_filenames = @cookbook[:root_filenames]
- @cookbook_version.metadata_filenames = @cookbook[:metadata_filenames]
- end
-
- it "generates a manifest containing the cookbook's files" do
- manifest = @cookbook_version.manifest
-
- manifest["metadata"].should == Chef::Cookbook::Metadata.new
- manifest["cookbook_name"].should == "blarghle"
-
- manifest["recipes"].should have(1).recipe_file
-
- recipe = manifest["recipes"].first
- recipe["name"].should == "default.rb"
- recipe["path"].should == "recipes/default.rb"
- recipe["checksum"].should match(MD5)
- recipe["specificity"].should == "default"
-
- manifest["definitions"].should have(1).definition_file
-
- definition = manifest["definitions"].first
- definition["name"].should == "runit_service.rb"
- definition["path"].should == "definitions/runit_service.rb"
- definition["checksum"].should match(MD5)
- definition["specificity"].should == "default"
-
- manifest["libraries"].should have(1).library_file
-
- library = manifest["libraries"].first
- library["name"].should == "ownage.rb"
- library["path"].should == "libraries/ownage.rb"
- library["checksum"].should match(MD5)
- library["specificity"].should == "default"
-
- manifest["attributes"].should have(1).attribute_file
-
- attribute_file = manifest["attributes"].first
- attribute_file["name"].should == "default.rb"
- attribute_file["path"].should == "attributes/default.rb"
- attribute_file["checksum"].should match(MD5)
- attribute_file["specificity"].should == "default"
-
- manifest["files"].should have(1).cookbook_file
-
- cookbook_file = manifest["files"].first
- cookbook_file["name"].should == "giant_blob.tgz"
- cookbook_file["path"].should == "files/default/giant_blob.tgz"
- cookbook_file["checksum"].should match(MD5)
- cookbook_file["specificity"].should == "default"
-
- manifest["templates"].should have(1).template
-
- template = manifest["templates"].first
- template["name"].should == "configuration.erb"
- template["path"].should == "templates/default/configuration.erb"
- template["checksum"].should match(MD5)
- template["specificity"].should == "default"
-
- manifest["resources"].should have(1).lwr
-
- lwr = manifest["resources"].first
- lwr["name"].should == "lwr.rb"
- lwr["path"].should == "resources/lwr.rb"
- lwr["checksum"].should match(MD5)
- lwr["specificity"].should == "default"
-
- manifest["providers"].should have(1).lwp
-
- lwp = manifest["providers"].first
- lwp["name"].should == "lwp.rb"
- lwp["path"].should == "providers/lwp.rb"
- lwp["checksum"].should match(MD5)
- lwp["specificity"].should == "default"
-
- manifest["root_files"].should have(1).file_in_the_cookbook_root
-
- readme = manifest["root_files"].first
- readme["name"].should == "README.rdoc"
- readme["path"].should == "README.rdoc"
- readme["checksum"].should match(MD5)
- readme["specificity"].should == "default"
- end
- end
end
describe 'with a cookbook directory named cookbook2 that has unscoped files' do
@@ -389,43 +192,43 @@ describe Chef::CookbookVersion do
end
it "should see a template" do
- @cookbook_version.should have_template_for_node(@node, "test.erb")
+ expect(@cookbook_version).to have_template_for_node(@node, "test.erb")
end
it "should see a template using an array lookup" do
- @cookbook_version.should have_template_for_node(@node, ["test.erb"])
+ expect(@cookbook_version).to have_template_for_node(@node, ["test.erb"])
end
- it "should see a template using an array lookup with non-existant elements" do
- @cookbook_version.should have_template_for_node(@node, ["missing.txt", "test.erb"])
+ it "should see a template using an array lookup with non-existent elements" do
+ expect(@cookbook_version).to have_template_for_node(@node, ["missing.txt", "test.erb"])
end
it "should see a file" do
- @cookbook_version.should have_cookbook_file_for_node(@node, "test.txt")
+ expect(@cookbook_version).to have_cookbook_file_for_node(@node, "test.txt")
end
it "should see a file using an array lookup" do
- @cookbook_version.should have_cookbook_file_for_node(@node, ["test.txt"])
+ expect(@cookbook_version).to have_cookbook_file_for_node(@node, ["test.txt"])
end
- it "should see a file using an array lookup with non-existant elements" do
- @cookbook_version.should have_cookbook_file_for_node(@node, ["missing.txt", "test.txt"])
+ it "should see a file using an array lookup with non-existent elements" do
+ expect(@cookbook_version).to have_cookbook_file_for_node(@node, ["missing.txt", "test.txt"])
end
- it "should not see a non-existant template" do
- @cookbook_version.should_not have_template_for_node(@node, "missing.erb")
+ it "should not see a non-existent template" do
+ expect(@cookbook_version).not_to have_template_for_node(@node, "missing.erb")
end
- it "should not see a non-existant template using an array lookup" do
- @cookbook_version.should_not have_template_for_node(@node, ["missing.erb"])
+ it "should not see a non-existent template using an array lookup" do
+ expect(@cookbook_version).not_to have_template_for_node(@node, ["missing.erb"])
end
- it "should not see a non-existant file" do
- @cookbook_version.should_not have_cookbook_file_for_node(@node, "missing.txt")
+ it "should not see a non-existent file" do
+ expect(@cookbook_version).not_to have_cookbook_file_for_node(@node, "missing.txt")
end
- it "should not see a non-existant file using an array lookup" do
- @cookbook_version.should_not have_cookbook_file_for_node(@node, ["missing.txt"])
+ it "should not see a non-existent file using an array lookup" do
+ expect(@cookbook_version).not_to have_cookbook_file_for_node(@node, ["missing.txt"])
end
end
@@ -453,9 +256,9 @@ describe Chef::CookbookVersion do
lg = Chef::CookbookVersion.new("foo", '/tmp/blah')
sm.version = smaller
lg.version = larger
- sm.should be < lg
- lg.should be > sm
- sm.should_not == lg
+ expect(sm).to be < lg
+ expect(lg).to be > sm
+ expect(sm).not_to eq(lg)
end
end
@@ -464,7 +267,7 @@ describe Chef::CookbookVersion do
b = Chef::CookbookVersion.new("foo", '/tmp/blah')
a.version = "1.2"
b.version = "1.2.0"
- a.should == b
+ expect(a).to eq(b)
end
@@ -473,7 +276,7 @@ describe Chef::CookbookVersion do
apt.version = "1.0"
god = Chef::CookbookVersion.new "god", '/tmp/blah'
god.version = "2.0"
- lambda {apt <=> god}.should raise_error(Chef::Exceptions::CookbookVersionNameMismatch)
+ expect {apt <=> god}.to raise_error(Chef::Exceptions::CookbookVersionNameMismatch)
end
end
@@ -493,14 +296,69 @@ describe Chef::CookbookVersion do
"1 2 3", "1-2-3", "1_2_3", "1.2_3", "1.2-3"]
the_error = Chef::Exceptions::InvalidCookbookVersion
bad_versions.each do |v|
- lambda {@cbv.version = v}.should raise_error(the_error)
+ expect {@cbv.version = v}.to raise_error(the_error)
end
end
end
- include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
- let(:jsonable) { Chef::CookbookVersion.new("tatft", '/tmp/blah') }
+ describe "when deprecation warnings are errors" do
+
+ subject(:cbv) { Chef::CookbookVersion.new("version validation", '/tmp/blah') }
+
+ describe "HTTP Resource behaviors", pending: "will be deprected when CookbookManifest API is stablized" do
+
+ it "errors on #save_url" do
+ expect { cbv.save_url }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
+ end
+
+ it "errors on #force_save_url" do
+ expect { cbv.force_save_url }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
+ end
+
+ it "errors on #to_hash" do
+ expect { cbv.to_hash }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
+ end
+
+ it "errors on #to_json" do
+ expect { cbv.to_json }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
+ end
+
+ end
+
+ it "errors on #status and #status=" do
+ expect { cbv.status = :wat }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
+ expect { cbv.status }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
+ end
+
end
+ describe "deprecated features" do
+
+ subject(:cbv) { Chef::CookbookVersion.new("tatft", '/tmp/blah').tap { |c| c.version = "1.2.3" } }
+
+ before do
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
+ end
+
+ it "gives a save URL for the standard cookbook API" do
+ expect(cbv.save_url).to eq("cookbooks/tatft/1.2.3")
+ end
+
+ it "gives a force save URL for the standard cookbook API" do
+ expect(cbv.force_save_url).to eq("cookbooks/tatft/1.2.3?force=true")
+ end
+
+ it "is \"ready\"" do
+ # WTF is this? what are the valid states? and why aren't they set with encapsulating methods?
+ # [Dan 15-Jul-2010]
+ expect(cbv.status).to eq(:ready)
+ end
+
+
+ include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
+ let(:jsonable) { Chef::CookbookVersion.new("tatft", '/tmp/blah') }
+ end
+
+ end
end
diff --git a/spec/unit/daemon_spec.rb b/spec/unit/daemon_spec.rb
index 9132dae389..e020576a23 100644
--- a/spec/unit/daemon_spec.rb
+++ b/spec/unit/daemon_spec.rb
@@ -23,12 +23,12 @@ describe Chef::Daemon do
if windows?
mock_struct = #Struct::Passwd.new(nil, nil, 111, 111)
mock_struct = OpenStruct.new(:uid => 2342, :gid => 2342)
- Etc.stub(:getpwnam).and_return mock_struct
- Etc.stub(:getgrnam).and_return mock_struct
+ allow(Etc).to receive(:getpwnam).and_return mock_struct
+ allow(Etc).to receive(:getgrnam).and_return mock_struct
# mock unimplemented methods
- Process.stub(:initgroups).and_return nil
- Process::GID.stub(:change_privilege).and_return 11
- Process::UID.stub(:change_privilege).and_return 11
+ allow(Process).to receive(:initgroups).and_return nil
+ allow(Process::GID).to receive(:change_privilege).and_return 11
+ allow(Process::UID).to receive(:change_privilege).and_return 11
end
end
@@ -41,7 +41,7 @@ describe Chef::Daemon do
end
it "should return the supplied value" do
- Chef::Daemon.pid_file.should eql("/var/run/chef/chef-client.pid")
+ expect(Chef::Daemon.pid_file).to eql("/var/run/chef/chef-client.pid")
end
end
@@ -52,7 +52,7 @@ describe Chef::Daemon do
end
it "should return a valued based on @name" do
- Chef::Daemon.pid_file.should eql("/tmp/chef-client.pid")
+ expect(Chef::Daemon.pid_file).to eql("/tmp/chef-client.pid")
end
end
@@ -65,7 +65,7 @@ describe Chef::Daemon do
end
it "should suck the pid out of pid_file" do
- File.should_receive(:read).with("/var/run/chef/chef-client.pid").and_return("1337")
+ expect(File).to receive(:read).with("/var/run/chef/chef-client.pid").and_return("1337")
Chef::Daemon.pid_from_file
end
end
@@ -73,13 +73,13 @@ describe Chef::Daemon do
describe ".change_privilege" do
before do
- Chef::Application.stub(:fatal!).and_return(true)
+ allow(Chef::Application).to receive(:fatal!).and_return(true)
Chef::Config[:user] = 'aj'
- Dir.stub(:chdir)
+ allow(Dir).to receive(:chdir)
end
it "changes the working directory to root" do
- Dir.should_receive(:chdir).with("/").and_return(0)
+ expect(Dir).to receive(:chdir).with("/").and_return(0)
Chef::Daemon.change_privilege
end
@@ -90,24 +90,24 @@ describe Chef::Daemon do
end
it "should log an appropriate info message" do
- Chef::Log.should_receive(:info).with("About to change privilege to aj:staff")
+ expect(Chef::Log).to receive(:info).with("About to change privilege to aj:staff")
Chef::Daemon.change_privilege
end
it "should call _change_privilege with the user and group" do
- Chef::Daemon.should_receive(:_change_privilege).with("aj", "staff")
+ expect(Chef::Daemon).to receive(:_change_privilege).with("aj", "staff")
Chef::Daemon.change_privilege
end
end
describe "when just the user option is supplied" do
it "should log an appropriate info message" do
- Chef::Log.should_receive(:info).with("About to change privilege to aj")
+ expect(Chef::Log).to receive(:info).with("About to change privilege to aj")
Chef::Daemon.change_privilege
end
it "should call _change_privilege with just the user" do
- Chef::Daemon.should_receive(:_change_privilege).with("aj")
+ expect(Chef::Daemon).to receive(:_change_privilege).with("aj")
Chef::Daemon.change_privilege
end
end
@@ -116,56 +116,56 @@ describe Chef::Daemon do
describe "._change_privilege" do
before do
- Process.stub(:euid).and_return(0)
- Process.stub(:egid).and_return(0)
+ allow(Process).to receive(:euid).and_return(0)
+ allow(Process).to receive(:egid).and_return(0)
- Process::UID.stub(:change_privilege).and_return(nil)
- Process::GID.stub(:change_privilege).and_return(nil)
+ allow(Process::UID).to receive(:change_privilege).and_return(nil)
+ allow(Process::GID).to receive(:change_privilege).and_return(nil)
@pw_user = double("Struct::Passwd", :uid => 501)
@pw_group = double("Struct::Group", :gid => 20)
- Process.stub(:initgroups).and_return(true)
+ allow(Process).to receive(:initgroups).and_return(true)
- Etc.stub(:getpwnam).and_return(@pw_user)
- Etc.stub(:getgrnam).and_return(@pw_group)
+ allow(Etc).to receive(:getpwnam).and_return(@pw_user)
+ allow(Etc).to receive(:getgrnam).and_return(@pw_group)
end
describe "with sufficient privileges" do
before do
- Process.stub(:euid).and_return(0)
- Process.stub(:egid).and_return(0)
+ allow(Process).to receive(:euid).and_return(0)
+ allow(Process).to receive(:egid).and_return(0)
end
it "should initialize the supplemental group list" do
- Process.should_receive(:initgroups).with("aj", 20)
+ expect(Process).to receive(:initgroups).with("aj", 20)
Chef::Daemon._change_privilege("aj")
end
it "should attempt to change the process GID" do
- Process::GID.should_receive(:change_privilege).with(20).and_return(20)
+ expect(Process::GID).to receive(:change_privilege).with(20).and_return(20)
Chef::Daemon._change_privilege("aj")
end
it "should attempt to change the process UID" do
- Process::UID.should_receive(:change_privilege).with(501).and_return(501)
+ expect(Process::UID).to receive(:change_privilege).with(501).and_return(501)
Chef::Daemon._change_privilege("aj")
end
end
describe "with insufficient privileges" do
before do
- Process.stub(:euid).and_return(999)
- Process.stub(:egid).and_return(999)
+ allow(Process).to receive(:euid).and_return(999)
+ allow(Process).to receive(:egid).and_return(999)
end
it "should log an appropriate error message and fail miserably" do
- Process.stub(:initgroups).and_raise(Errno::EPERM)
+ allow(Process).to receive(:initgroups).and_raise(Errno::EPERM)
error = "Operation not permitted"
if RUBY_PLATFORM.match("solaris2") || RUBY_PLATFORM.match("aix")
error = "Not owner"
end
- Chef::Application.should_receive(:fatal!).with("Permission denied when trying to change 999:999 to 501:20. #{error}")
+ expect(Chef::Application).to receive(:fatal!).with("Permission denied when trying to change 999:999 to 501:20. #{error}")
Chef::Daemon._change_privilege("aj")
end
end
diff --git a/spec/unit/data_bag_item_spec.rb b/spec/unit/data_bag_item_spec.rb
index 5972d8a239..4348252388 100644
--- a/spec/unit/data_bag_item_spec.rb
+++ b/spec/unit/data_bag_item_spec.rb
@@ -20,107 +20,109 @@ require 'spec_helper'
require 'chef/data_bag_item'
describe Chef::DataBagItem do
- before(:each) do
- @data_bag_item = Chef::DataBagItem.new
- end
+ let(:data_bag_item) { Chef::DataBagItem.new }
describe "initialize" do
it "should be a Chef::DataBagItem" do
- @data_bag_item.should be_a_kind_of(Chef::DataBagItem)
+ expect(data_bag_item).to be_a_kind_of(Chef::DataBagItem)
end
end
describe "data_bag" do
it "should let you set the data_bag to a string" do
- @data_bag_item.data_bag("clowns").should == "clowns"
+ expect(data_bag_item.data_bag("clowns")).to eq("clowns")
end
it "should return the current data_bag type" do
- @data_bag_item.data_bag "clowns"
- @data_bag_item.data_bag.should == "clowns"
+ data_bag_item.data_bag "clowns"
+ expect(data_bag_item.data_bag).to eq("clowns")
end
it "should not accept spaces" do
- lambda { @data_bag_item.data_bag "clown masters" }.should raise_error(ArgumentError)
+ expect { data_bag_item.data_bag "clown masters" }.to raise_error(ArgumentError)
end
it "should throw an ArgumentError if you feed it anything but a string" do
- lambda { @data_bag_item.data_bag Hash.new }.should raise_error(ArgumentError)
+ expect { data_bag_item.data_bag Hash.new }.to raise_error(ArgumentError)
end
end
describe "raw_data" do
it "should let you set the raw_data with a hash" do
- lambda { @data_bag_item.raw_data = { "id" => "octahedron" } }.should_not raise_error
+ expect { data_bag_item.raw_data = { "id" => "octahedron" } }.not_to raise_error
end
it "should let you set the raw_data from a mash" do
- lambda { @data_bag_item.raw_data = Mash.new({ "id" => "octahedron" }) }.should_not raise_error
+ expect { data_bag_item.raw_data = Mash.new({ "id" => "octahedron" }) }.not_to raise_error
end
it "should raise an exception if you set the raw data without a key" do
- lambda { @data_bag_item.raw_data = { "monkey" => "pants" } }.should raise_error(ArgumentError)
+ expect { data_bag_item.raw_data = { "monkey" => "pants" } }.to raise_error(ArgumentError)
end
it "should raise an exception if you set the raw data to something other than a hash" do
- lambda { @data_bag_item.raw_data = "katie rules" }.should raise_error(ArgumentError)
+ expect { data_bag_item.raw_data = "katie rules" }.to raise_error(ArgumentError)
end
it "should accept alphanum/-/_ for the id" do
- lambda { @data_bag_item.raw_data = { "id" => "h1-_" } }.should_not raise_error
+ expect { data_bag_item.raw_data = { "id" => "h1-_" } }.not_to raise_error
end
it "should accept alphanum.alphanum for the id" do
- lambda { @data_bag_item.raw_data = { "id" => "foo.bar" } }.should_not raise_error
+ expect { data_bag_item.raw_data = { "id" => "foo.bar" } }.not_to raise_error
end
it "should accept .alphanum for the id" do
- lambda { @data_bag_item.raw_data = { "id" => ".bozo" } }.should_not raise_error
+ expect { data_bag_item.raw_data = { "id" => ".bozo" } }.not_to raise_error
end
it "should raise an exception if the id contains anything but alphanum/-/_" do
- lambda { @data_bag_item.raw_data = { "id" => "!@#" } }.should raise_error(ArgumentError)
+ expect { data_bag_item.raw_data = { "id" => "!@#" } }.to raise_error(ArgumentError)
end
it "should return the raw data" do
- @data_bag_item.raw_data = { "id" => "highway_of_emptiness" }
- @data_bag_item.raw_data.should == { "id" => "highway_of_emptiness" }
+ data_bag_item.raw_data = { "id" => "highway_of_emptiness" }
+ expect(data_bag_item.raw_data).to eq({ "id" => "highway_of_emptiness" })
end
it "should be a Mash by default" do
- @data_bag_item.raw_data.should be_a_kind_of(Mash)
+ expect(data_bag_item.raw_data).to be_a_kind_of(Mash)
end
end
describe "object_name" do
- before(:each) do
- @data_bag_item.data_bag("dreams")
- @data_bag_item.raw_data = { "id" => "the_beatdown" }
- end
+ let(:data_bag_item) {
+ data_bag_item = Chef::DataBagItem.new
+ data_bag_item.data_bag("dreams")
+ data_bag_item.raw_data = { "id" => "the_beatdown" }
+ data_bag_item
+ }
it "should return an object name based on the bag name and the raw_data id" do
- @data_bag_item.object_name.should == "data_bag_item_dreams_the_beatdown"
+ expect(data_bag_item.object_name).to eq("data_bag_item_dreams_the_beatdown")
end
end
describe "class method object_name" do
it "should return an object name based based on the bag name and an id" do
- Chef::DataBagItem.object_name("zen", "master").should == "data_bag_item_zen_master"
+ expect(Chef::DataBagItem.object_name("zen", "master")).to eq("data_bag_item_zen_master")
end
end
describe "when used like a Hash" do
- before(:each) do
- @data_bag_item.raw_data = { "id" => "journey", "trials" => "been through" }
- end
+ let(:data_bag_item) {
+ data_bag_item = Chef::DataBagItem.new
+ data_bag_item.raw_data = { "id" => "journey", "trials" => "been through" }
+ data_bag_item
+ }
it "responds to keys" do
- @data_bag_item.keys.should include("id")
- @data_bag_item.keys.should include("trials")
+ expect(data_bag_item.keys).to include("id")
+ expect(data_bag_item.keys).to include("trials")
end
it "supports element reference with []" do
- @data_bag_item["id"].should == "journey"
+ expect(data_bag_item["id"]).to eq("journey")
end
it "implements all the methods of Hash" do
@@ -131,100 +133,113 @@ describe Chef::DataBagItem do
:invert, :update, :replace, :merge!, :merge, :has_key?, :has_value?,
:key?, :value?]
methods.each do |m|
- @data_bag_item.should respond_to(m)
+ expect(data_bag_item).to respond_to(m)
end
end
-
end
describe "to_hash" do
- before(:each) do
- @data_bag_item.data_bag("still_lost")
- @data_bag_item.raw_data = { "id" => "whoa", "i_know" => "kung_fu" }
- @to_hash = @data_bag_item.to_hash
- end
+ let(:data_bag_item) {
+ data_bag_item = Chef::DataBagItem.new
+ data_bag_item.data_bag("still_lost")
+ data_bag_item.raw_data = { "id" => "whoa", "i_know" => "kung_fu" }
+ data_bag_item
+ }
+
+ let(:to_hash) { data_bag_item.to_hash }
it "should return a hash" do
- @to_hash.should be_a_kind_of(Hash)
+ expect(to_hash).to be_a_kind_of(Hash)
end
it "should have the raw_data keys as top level keys" do
- @to_hash["id"].should == "whoa"
- @to_hash["i_know"].should == "kung_fu"
+ expect(to_hash["id"]).to eq("whoa")
+ expect(to_hash["i_know"]).to eq("kung_fu")
end
it "should have the chef_type of data_bag_item" do
- @to_hash["chef_type"].should == "data_bag_item"
+ expect(to_hash["chef_type"]).to eq("data_bag_item")
end
it "should have the data_bag set" do
- @to_hash["data_bag"].should == "still_lost"
+ expect(to_hash["data_bag"]).to eq("still_lost")
end
end
describe "when deserializing from JSON" do
- before(:each) do
- @data_bag_item.data_bag('mars_volta')
- @data_bag_item.raw_data = { "id" => "octahedron", "snooze" => { "finally" => :world_will }}
- @deserial = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(@data_bag_item))
- end
+ let(:data_bag_item) {
+ data_bag_item = Chef::DataBagItem.new
+ data_bag_item.data_bag('mars_volta')
+ data_bag_item.raw_data = { "id" => "octahedron", "snooze" => { "finally" => :world_will } }
+ data_bag_item
+ }
+
+ let(:deserial) { Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(data_bag_item)) }
+
it "should deserialize to a Chef::DataBagItem object" do
- @deserial.should be_a_kind_of(Chef::DataBagItem)
+ expect(deserial).to be_a_kind_of(Chef::DataBagItem)
end
it "should have a matching 'data_bag' value" do
- @deserial.data_bag.should == @data_bag_item.data_bag
+ expect(deserial.data_bag).to eq(data_bag_item.data_bag)
end
it "should have a matching 'id' key" do
- @deserial["id"].should == "octahedron"
+ expect(deserial["id"]).to eq("octahedron")
end
it "should have a matching 'snooze' key" do
- @deserial["snooze"].should == { "finally" => "world_will" }
+ expect(deserial["snooze"]).to eq({ "finally" => "world_will" })
end
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
- let(:jsonable) { @data_bag_item }
+ let(:jsonable) { data_bag_item }
end
end
describe "when converting to a string" do
it "converts to a string in the form data_bag_item[ID]" do
- @data_bag_item['id'] = "heart of darkness"
- @data_bag_item.to_s.should == 'data_bag_item[heart of darkness]'
+ data_bag_item['id'] = "heart of darkness"
+ expect(data_bag_item.to_s).to eq('data_bag_item[heart of darkness]')
end
it "inspects as data_bag_item[BAG, ID, RAW_DATA]" do
raw_data = {"id" => "heart_of_darkness", "author" => "Conrad"}
- @data_bag_item.raw_data = raw_data
- @data_bag_item.data_bag("books")
+ data_bag_item.raw_data = raw_data
+ data_bag_item.data_bag("books")
- @data_bag_item.inspect.should == "data_bag_item[\"books\", \"heart_of_darkness\", #{raw_data.inspect}]"
+ expect(data_bag_item.inspect).to eq("data_bag_item[\"books\", \"heart_of_darkness\", #{raw_data.inspect}]")
end
end
describe "save" do
+ let(:server) { instance_double(Chef::REST) }
+
+ let(:data_bag_item) {
+ 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
+ }
+
before do
- @rest = double("Chef::REST")
- Chef::REST.stub(:new).and_return(@rest)
- @data_bag_item['id'] = "heart of darkness"
- raw_data = {"id" => "heart_of_darkness", "author" => "Conrad"}
- @data_bag_item.raw_data = raw_data
- @data_bag_item.data_bag("books")
+ expect(Chef::REST).to receive(:new).and_return(server)
end
+
it "should update the item when it already exists" do
- @rest.should_receive(:put_rest).with("data/books/heart_of_darkness", @data_bag_item)
- @data_bag_item.save
+ expect(server).to receive(:put_rest).with("data/books/heart_of_darkness", data_bag_item)
+ data_bag_item.save
end
it "should create if the item is not found" do
exception = double("404 error", :code => "404")
- @rest.should_receive(:put_rest).and_raise(Net::HTTPServerException.new("foo", exception))
- @rest.should_receive(:post_rest).with("data/books", @data_bag_item)
- @data_bag_item.save
+ expect(server).to receive(:put_rest).and_raise(Net::HTTPServerException.new("foo", exception))
+ expect(server).to receive(:post_rest).with("data/books", data_bag_item)
+ data_bag_item.save
end
+
describe "when whyrun mode is enabled" do
before do
Chef::Config[:why_run] = true
@@ -232,41 +247,60 @@ describe Chef::DataBagItem do
after do
Chef::Config[:why_run] = false
end
+
it "should not save" do
- @rest.should_not_receive(:put_rest)
- @rest.should_not_receive(:post_rest)
- @data_bag_item.data_bag("books")
- @data_bag_item.save
+ expect(server).not_to receive(:put_rest)
+ expect(server).not_to receive(:post_rest)
+ data_bag_item.data_bag("books")
+ data_bag_item.save
end
end
+ end
+
+ describe "destroy" do
+ let(:server) { instance_double(Chef::REST) }
+
+ let(:data_bag_item) {
+ 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
+ }
+ it "should set default parameters" do
+ expect(Chef::REST).to receive(:new).and_return(server)
+ expect(server).to receive(:delete_rest).with("data/a_baggy_bag/data_bag_item_a_baggy_bag_some_id")
+
+ data_bag_item.destroy
+ end
end
describe "when loading" do
before do
- @data_bag_item.raw_data = {"id" => "charlie", "shell" => "zsh", "ssh_keys" => %w{key1 key2}}
- @data_bag_item.data_bag("users")
+ data_bag_item.raw_data = {"id" => "charlie", "shell" => "zsh", "ssh_keys" => %w{key1 key2}}
+ data_bag_item.data_bag("users")
end
describe "from an API call" do
+ let(:http_client) { double("Chef::REST") }
+
before do
- @http_client = double("Chef::REST")
- Chef::REST.stub(:new).and_return(@http_client)
+ allow(Chef::REST).to receive(:new).and_return(http_client)
end
it "converts raw data to a data bag item" do
- @http_client.should_receive(:get_rest).with("data/users/charlie").and_return(@data_bag_item.to_hash)
+ expect(http_client).to receive(:get_rest).with("data/users/charlie").and_return(data_bag_item.to_hash)
item = Chef::DataBagItem.load(:users, "charlie")
- item.should be_a_kind_of(Chef::DataBagItem)
- item.should == @data_bag_item
+ expect(item).to be_a_kind_of(Chef::DataBagItem)
+ expect(item).to eq(data_bag_item)
end
it "does not convert when a DataBagItem is returned from the API call" do
- @http_client.should_receive(:get_rest).with("data/users/charlie").and_return(@data_bag_item)
+ expect(http_client).to receive(:get_rest).with("data/users/charlie").and_return(data_bag_item)
item = Chef::DataBagItem.load(:users, "charlie")
- item.should be_a_kind_of(Chef::DataBagItem)
- item.should equal(@data_bag_item)
+ expect(item).to be_a_kind_of(Chef::DataBagItem)
+ expect(item).to equal(data_bag_item)
end
end
@@ -280,13 +314,11 @@ describe Chef::DataBagItem do
end
it "converts the raw data to a data bag item" do
- Chef::DataBag.should_receive(:load).with('users').and_return({'charlie' => @data_bag_item.to_hash})
+ expect(Chef::DataBag).to receive(:load).with('users').and_return({'charlie' => data_bag_item.to_hash})
item = Chef::DataBagItem.load('users', 'charlie')
- item.should be_a_kind_of(Chef::DataBagItem)
- item.should == @data_bag_item
+ expect(item).to be_a_kind_of(Chef::DataBagItem)
+ expect(item).to eq(data_bag_item)
end
end
-
end
-
end
diff --git a/spec/unit/data_bag_spec.rb b/spec/unit/data_bag_spec.rb
index ff323902eb..f6db1e222a 100644
--- a/spec/unit/data_bag_spec.rb
+++ b/spec/unit/data_bag_spec.rb
@@ -22,36 +22,36 @@ require 'chef/data_bag'
describe Chef::DataBag do
before(:each) do
@data_bag = Chef::DataBag.new
- Chef::Platform::stub(:windows?) { false }
+ allow(Chef::Platform)::to receive(:windows?) { false }
end
describe "initialize" do
it "should be a Chef::DataBag" do
- @data_bag.should be_a_kind_of(Chef::DataBag)
+ expect(@data_bag).to be_a_kind_of(Chef::DataBag)
end
end
describe "name" do
it "should let you set the name to a string" do
- @data_bag.name("clowns").should == "clowns"
+ expect(@data_bag.name("clowns")).to eq("clowns")
end
it "should return the current name" do
@data_bag.name "clowns"
- @data_bag.name.should == "clowns"
+ expect(@data_bag.name).to eq("clowns")
end
it "should not accept spaces" do
- lambda { @data_bag.name "clown masters" }.should raise_error(ArgumentError)
+ expect { @data_bag.name "clown masters" }.to raise_error(ArgumentError)
end
it "should throw an ArgumentError if you feed it anything but a string" do
- lambda { @data_bag.name Hash.new }.should raise_error(ArgumentError)
+ expect { @data_bag.name Hash.new }.to raise_error(ArgumentError)
end
[ ".", "-", "_", "1"].each do |char|
it "should allow a '#{char}' character in the data bag name" do
- @data_bag.name("clown#{char}clown").should == "clown#{char}clown"
+ expect(@data_bag.name("clown#{char}clown")).to eq("clown#{char}clown")
end
end
end
@@ -63,14 +63,14 @@ describe Chef::DataBag do
end
it "should deserialize to a Chef::DataBag object" do
- @deserial.should be_a_kind_of(Chef::DataBag)
+ expect(@deserial).to be_a_kind_of(Chef::DataBag)
end
%w{
name
}.each do |t|
it "should match '#{t}'" do
- @deserial.send(t.to_sym).should == @data_bag.send(t.to_sym)
+ expect(@deserial.send(t.to_sym)).to eq(@data_bag.send(t.to_sym))
end
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
@@ -84,17 +84,17 @@ describe Chef::DataBag do
before do
@data_bag.name('piggly_wiggly')
@rest = double("Chef::REST")
- Chef::REST.stub(:new).and_return(@rest)
+ allow(Chef::REST).to receive(:new).and_return(@rest)
end
it "should silently proceed when the data bag already exists" do
exception = double("409 error", :code => "409")
- @rest.should_receive(:post_rest).and_raise(Net::HTTPServerException.new("foo", exception))
+ expect(@rest).to receive(:post_rest).and_raise(Net::HTTPServerException.new("foo", exception))
@data_bag.save
end
it "should create the data bag" do
- @rest.should_receive(:post_rest).with("data", @data_bag)
+ expect(@rest).to receive(:post_rest).with("data", @data_bag)
@data_bag.save
end
@@ -106,7 +106,7 @@ describe Chef::DataBag do
Chef::Config[:why_run] = false
end
it "should not save" do
- @rest.should_not_receive(:post_rest)
+ expect(@rest).not_to receive(:post_rest)
@data_bag.save
end
end
@@ -120,25 +120,25 @@ describe Chef::DataBag do
end
it "should get the data bag from the server" do
- Chef::REST.should_receive(:new).with('https://myserver.example.com').and_return(@http_client)
- @http_client.should_receive(:get_rest).with('data/foo')
+ expect(Chef::REST).to receive(:new).with('https://myserver.example.com').and_return(@http_client)
+ expect(@http_client).to receive(:get_rest).with('data/foo')
Chef::DataBag.load('foo')
end
it "should return the data bag" do
- Chef::REST.stub(:new).and_return(@http_client)
- @http_client.should_receive(:get_rest).with('data/foo').and_return({'bar' => 'https://myserver.example.com/data/foo/bar'})
+ allow(Chef::REST).to receive(:new).and_return(@http_client)
+ expect(@http_client).to receive(:get_rest).with('data/foo').and_return({'bar' => 'https://myserver.example.com/data/foo/bar'})
data_bag = Chef::DataBag.load('foo')
- data_bag.should == {'bar' => 'https://myserver.example.com/data/foo/bar'}
+ expect(data_bag).to eq({'bar' => 'https://myserver.example.com/data/foo/bar'})
end
end
def file_dir_stub(path, returns = true)
- File.should_receive(:directory?).with(path).and_return(returns)
+ expect(File).to receive(:directory?).with(path).and_return(returns)
end
def dir_glob_stub(path, returns = [])
- Dir.should_receive(:glob).with(File.join(path, 'foo/*.json')).and_return(returns)
+ expect(Dir).to receive(:glob).with(File.join(path, 'foo/*.json')).and_return(returns)
end
shared_examples_for "data bag in solo mode" do |data_bag_path|
@@ -177,21 +177,21 @@ describe Chef::DataBag do
dir_glob_stub(path)
end
end
- IO.should_receive(:read).with(File.join(@paths.first, 'foo/bar.json')).and_return('{"id": "bar", "name": "Bob Bar" }')
- IO.should_receive(:read).with(File.join(@paths.first, 'foo/baz.json')).and_return('{"id": "baz", "name": "John Baz" }')
+ expect(IO).to receive(:read).with(File.join(@paths.first, 'foo/bar.json')).and_return('{"id": "bar", "name": "Bob Bar" }')
+ expect(IO).to receive(:read).with(File.join(@paths.first, 'foo/baz.json')).and_return('{"id": "baz", "name": "John Baz" }')
data_bag = Chef::DataBag.load('foo')
- data_bag.should == { 'bar' => { 'id' => 'bar', 'name' => 'Bob Bar' }, 'baz' => { 'id' => 'baz', 'name' => 'John Baz' }}
+ expect(data_bag).to eq({ 'bar' => { 'id' => 'bar', 'name' => 'Bob Bar' }, 'baz' => { 'id' => 'baz', 'name' => 'John Baz' }})
end
it "should raise if data bag has items with similar names but different content" do
@paths.each do |path|
file_dir_stub(path)
item_with_different_content = "{\"id\": \"bar\", \"name\": \"Bob Bar\", \"path\": \"#{path}\"}"
- IO.should_receive(:read).with(File.join(path, 'foo/bar.json')).and_return(item_with_different_content)
+ expect(IO).to receive(:read).with(File.join(path, 'foo/bar.json')).and_return(item_with_different_content)
if data_bag_path.is_a?(String)
dir_glob_stub(path, [File.join(path, 'foo/bar.json'), File.join(path, 'foo/baz.json')])
item_2_with_different_content = '{"id": "bar", "name": "John Baz"}'
- IO.should_receive(:read).with(File.join(path, 'foo/baz.json')).and_return(item_2_with_different_content)
+ expect(IO).to receive(:read).with(File.join(path, 'foo/baz.json')).and_return(item_2_with_different_content)
else
dir_glob_stub(path, [File.join(path, 'foo/bar.json')])
end
@@ -204,12 +204,12 @@ describe Chef::DataBag do
file_dir_stub(path)
dir_glob_stub(path, [File.join(path, 'foo/bar.json'), File.join(path, 'foo/baz.json')])
item_with_same_content = '{"id": "bar", "name": "Bob Bar"}'
- IO.should_receive(:read).with(File.join(path, 'foo/bar.json')).and_return(item_with_same_content)
- IO.should_receive(:read).with(File.join(path, 'foo/baz.json')).and_return(item_with_same_content)
+ expect(IO).to receive(:read).with(File.join(path, 'foo/bar.json')).and_return(item_with_same_content)
+ expect(IO).to receive(:read).with(File.join(path, 'foo/baz.json')).and_return(item_with_same_content)
end
data_bag = Chef::DataBag.load('foo')
test_data_bag = { 'bar' => { 'id' => 'bar', 'name' => 'Bob Bar'} }
- data_bag.should == test_data_bag
+ expect(data_bag).to eq(test_data_bag)
end
it "should merge data bag items if there are no conflicts" do
@@ -217,33 +217,33 @@ describe Chef::DataBag do
file_dir_stub(path)
dir_glob_stub(path, [File.join(path, 'foo/bar.json'), File.join(path, 'foo/baz.json')])
test_item_with_same_content = '{"id": "bar", "name": "Bob Bar"}'
- IO.should_receive(:read).with(File.join(path, 'foo/bar.json')).and_return(test_item_with_same_content)
+ expect(IO).to receive(:read).with(File.join(path, 'foo/bar.json')).and_return(test_item_with_same_content)
test_uniq_item = "{\"id\": \"baz_#{index}\", \"name\": \"John Baz\", \"path\": \"#{path}\"}"
- IO.should_receive(:read).with(File.join(path, 'foo/baz.json')).and_return(test_uniq_item)
+ expect(IO).to receive(:read).with(File.join(path, 'foo/baz.json')).and_return(test_uniq_item)
end
data_bag = Chef::DataBag.load('foo')
test_data_bag = { 'bar' => { 'id' => 'bar', 'name' => 'Bob Bar'} }
@paths.each_with_index do |path, index|
test_data_bag["baz_#{index}"] = { "id" => "baz_#{index}", "name" => "John Baz", "path" => path }
end
- data_bag.should == test_data_bag
+ expect(data_bag).to eq(test_data_bag)
end
it "should return the data bag list" do
@paths.each do |path|
file_dir_stub(path)
- Dir.should_receive(:glob).and_return([File.join(path, 'foo'), File.join(path, 'bar')])
+ expect(Dir).to receive(:glob).and_return([File.join(path, 'foo'), File.join(path, 'bar')])
end
data_bag_list = Chef::DataBag.list
- data_bag_list.should == { 'bar' => 'bar', 'foo' => 'foo' }
+ expect(data_bag_list).to eq({ 'bar' => 'bar', 'foo' => 'foo' })
end
it 'should raise an error if the configured data_bag_path is invalid' do
file_dir_stub(@paths.first, false)
- lambda {
+ expect {
Chef::DataBag.load('foo')
- }.should raise_error Chef::Exceptions::InvalidDataBagPath, "Data bag path '/var/chef/data_bags' is invalid"
+ }.to raise_error Chef::Exceptions::InvalidDataBagPath, "Data bag path '/var/chef/data_bags' is invalid"
end
end
diff --git a/spec/unit/deprecation_spec.rb b/spec/unit/deprecation_spec.rb
index c5ab41fbab..f824cb7c76 100644
--- a/spec/unit/deprecation_spec.rb
+++ b/spec/unit/deprecation_spec.rb
@@ -54,32 +54,45 @@ describe Chef::Deprecation do
it "defines all methods on #{class_object} that were available in 11.0" do
old_methods.each do |old_method|
- current_methods.should include(old_method.to_sym)
+ expect(current_methods).to include(old_method.to_sym)
end
end
end
- context 'deprecation warning messages' do
- before(:each) do
- @warning_output = [ ]
- Chef::Log.stub(:warn) { |msg| @warning_output << msg }
+ context 'when Chef::Config[:treat_deprecation_warnings_as_errors] is off' do
+ before do
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
end
- it 'should be enabled for deprecated methods' do
- TestClass.new.deprecated_method(10)
- @warning_output.should_not be_empty
+ context 'deprecation warning messages' do
+ before(:each) do
+ @warning_output = [ ]
+ allow(Chef::Log).to receive(:warn) { |msg| @warning_output << msg }
+ end
+
+ it 'should be enabled for deprecated methods' do
+ TestClass.new.deprecated_method(10)
+ expect(@warning_output).not_to be_empty
+ end
+
+ it 'should contain stack trace' do
+ TestClass.new.deprecated_method(10)
+ expect(@warning_output.join("").include?(".rb")).to be_truthy
+ end
end
- it 'should contain stack trace' do
- TestClass.new.deprecated_method(10)
- @warning_output.join("").include?(".rb").should be_true
+ it 'deprecated methods should still be called' do
+ test_instance = TestClass.new
+ test_instance.deprecated_method(10)
+ expect(test_instance.get_value).to eq(10)
end
end
- it 'deprecated methods should still be called' do
+ it 'should raise when deprecation warnings are treated as errors' do
+ # rspec should set this
+ expect(Chef::Config[:treat_deprecation_warnings_as_errors]).to be true
test_instance = TestClass.new
- test_instance.deprecated_method(10)
- test_instance.get_value.should == 10
+ expect { test_instance.deprecated_method(10) }.to raise_error(Chef::Exceptions::DeprecatedFeatureError)
end
end
diff --git a/spec/unit/digester_spec.rb b/spec/unit/digester_spec.rb
index fdf20aca7c..51bcfbdde5 100644
--- a/spec/unit/digester_spec.rb
+++ b/spec/unit/digester_spec.rb
@@ -28,20 +28,20 @@ describe Chef::Digester do
describe "when computing checksums of cookbook files and templates" do
it "proxies the class method checksum_for_file to the instance" do
- @cache.should_receive(:checksum_for_file).with("a_file_or_a_fail")
+ expect(@cache).to receive(:checksum_for_file).with("a_file_or_a_fail")
Chef::Digester.checksum_for_file("a_file_or_a_fail")
end
it "computes a checksum of a file" do
fixture_file = CHEF_SPEC_DATA + "/checksum/random.txt"
expected = "09ee9c8cc70501763563bcf9c218d71b2fbf4186bf8e1e0da07f0f42c80a3394"
- @cache.checksum_for_file(fixture_file).should == expected
+ expect(@cache.checksum_for_file(fixture_file)).to eq(expected)
end
it "generates a checksum from a non-file IO object" do
io = StringIO.new("riseofthemachines\nriseofthechefs\n")
expected_md5 = '0e157ac1e2dd73191b76067fb6b4bceb'
- @cache.generate_md5_checksum(io).should == expected_md5
+ expect(@cache.generate_md5_checksum(io)).to eq(expected_md5)
end
end
diff --git a/spec/unit/dsl/audit_spec.rb b/spec/unit/dsl/audit_spec.rb
new file mode 100644
index 0000000000..28b28e0a7c
--- /dev/null
+++ b/spec/unit/dsl/audit_spec.rb
@@ -0,0 +1,43 @@
+
+require 'spec_helper'
+require 'chef/dsl/audit'
+
+class AuditDSLTester < Chef::Recipe
+ include Chef::DSL::Audit
+end
+
+class BadAuditDSLTester
+ include Chef::DSL::Audit
+end
+
+describe Chef::DSL::Audit do
+ let(:auditor) { AuditDSLTester.new("cookbook_name", "recipe_name", run_context) }
+ let(:run_context) { instance_double(Chef::RunContext, :audits => audits, :cookbook_collection => cookbook_collection) }
+ let(:audits) { {} }
+ let(:cookbook_collection) { {} }
+
+ it "raises an error when a block of audits is not provided" do
+ expect{ auditor.control_group "name" }.to raise_error(Chef::Exceptions::NoAuditsProvided)
+ end
+
+ it "raises an error when no audit name is given" do
+ expect{ auditor.control_group do end }.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)
+ end
+ end
+
+ context "included in a class without recipe DSL" 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'/)
+ end
+ end
+
+end
diff --git a/spec/unit/dsl/data_query_spec.rb b/spec/unit/dsl/data_query_spec.rb
index 78cd5569e8..b93ae1f1d6 100644
--- a/spec/unit/dsl/data_query_spec.rb
+++ b/spec/unit/dsl/data_query_spec.rb
@@ -28,7 +28,7 @@ describe Chef::DSL::DataQuery do
let(:language) do
language = DataQueryDSLTester.new
- language.stub(:node).and_return(@node)
+ allow(language).to receive(:node).and_return(@node)
language
end
diff --git a/spec/unit/dsl/platform_introspection_spec.rb b/spec/unit/dsl/platform_introspection_spec.rb
index f00d5a2ab8..e41560c034 100644
--- a/spec/unit/dsl/platform_introspection_spec.rb
+++ b/spec/unit/dsl/platform_introspection_spec.rb
@@ -48,37 +48,37 @@ describe Chef::DSL::PlatformIntrospection::PlatformDependentValue do
end
it "returns the default value when the platform doesn't match" do
- @platform_specific_value.value_for_node(:platform => :dos).should == 'bork da bork'
+ expect(@platform_specific_value.value_for_node(:platform => :dos)).to eq('bork da bork')
end
it "returns a value for a platform set as a group" do
- @platform_specific_value.value_for_node(:platform => :centos).should == '"stable"'
+ expect(@platform_specific_value.value_for_node(:platform => :centos)).to eq('"stable"')
end
it "returns a value for the platform when it was set as a symbol but fetched as a string" do
- @platform_specific_value.value_for_node(:platform => "centos").should == '"stable"'
+ expect(@platform_specific_value.value_for_node(:platform => "centos")).to eq('"stable"')
end
it "returns a value for a specific platform version" do
node = {:platform => 'ubuntu', :platform_version => '10.04'}
- @platform_specific_value.value_for_node(node).should == 'using upstart more'
+ expect(@platform_specific_value.value_for_node(node)).to eq('using upstart more')
end
it "returns a platform-default value if the platform version doesn't match an explicit one" do
node = {:platform => 'ubuntu', :platform_version => '9.10' }
- @platform_specific_value.value_for_node(node).should == 'using init more'
+ expect(@platform_specific_value.value_for_node(node)).to eq('using init more')
end
it "returns nil if there is no default and no platforms match" do
# this matches the behavior in the original implementation.
# whether or not it's correct is another matter.
platform_specific_value = Chef::DSL::PlatformIntrospection::PlatformDependentValue.new({})
- platform_specific_value.value_for_node(:platform => 'foo').should be_nil
+ expect(platform_specific_value.value_for_node(:platform => 'foo')).to be_nil
end
it "raises an argument error if the platform hash is not correctly structured" do
bad_hash = {:ubuntu => :foo} # should be :ubuntu => {:default => 'foo'}
- lambda {Chef::DSL::PlatformIntrospection::PlatformDependentValue.new(bad_hash)}.should raise_error(ArgumentError)
+ expect {Chef::DSL::PlatformIntrospection::PlatformDependentValue.new(bad_hash)}.to raise_error(ArgumentError)
end
end
@@ -98,33 +98,33 @@ describe Chef::DSL::PlatformIntrospection::PlatformFamilyDependentValue do
end
it "returns the default value when the platform family doesn't match" do
- @platform_family_value.value_for_node(:platform_family => :os2).should == 'default value'
+ expect(@platform_family_value.value_for_node(:platform_family => :os2)).to eq('default value')
end
it "returns a value for the platform family when it was set as a string but fetched as a symbol" do
- @platform_family_value.value_for_node(:platform_family => :debian).should == "debian value"
+ expect(@platform_family_value.value_for_node(:platform_family => :debian)).to eq("debian value")
end
it "returns a value for the platform family when it was set as a symbol but fetched as a string" do
- @platform_family_value.value_for_node(:platform_family => "gentoo").should == "gentoo value"
+ expect(@platform_family_value.value_for_node(:platform_family => "gentoo")).to eq("gentoo value")
end
it "returns an array value stored for a platform family" do
- @platform_family_value.value_for_node(:platform_family => "suse").should == @array_values
+ expect(@platform_family_value.value_for_node(:platform_family => "suse")).to eq(@array_values)
end
it "returns a value for the platform family when it was set within an array hash key as a symbol" do
- @platform_family_value.value_for_node(:platform_family => :rhel).should == "redhatty value"
+ expect(@platform_family_value.value_for_node(:platform_family => :rhel)).to eq("redhatty value")
end
it "returns a value for the platform family when it was set within an array hash key as a string" do
- @platform_family_value.value_for_node(:platform_family => "fedora").should == "redhatty value"
+ expect(@platform_family_value.value_for_node(:platform_family => "fedora")).to eq("redhatty value")
end
it "returns nil if there is no default and no platforms match" do
platform_specific_value = Chef::DSL::PlatformIntrospection::PlatformFamilyDependentValue.new({})
- platform_specific_value.value_for_node(:platform_family => 'foo').should be_nil
+ expect(platform_specific_value.value_for_node(:platform_family => 'foo')).to be_nil
end
end
diff --git a/spec/unit/dsl/reboot_pending_spec.rb b/spec/unit/dsl/reboot_pending_spec.rb
index 0d643514e0..0f2288740f 100644
--- a/spec/unit/dsl/reboot_pending_spec.rb
+++ b/spec/unit/dsl/reboot_pending_spec.rb
@@ -25,52 +25,52 @@ describe Chef::DSL::RebootPending do
let(:recipe) { Object.new.extend(Chef::DSL::RebootPending) }
before do
- recipe.stub(:platform?).and_return(false)
+ allow(recipe).to receive(:platform?).and_return(false)
end
context "platform is windows" do
before do
- recipe.stub(:platform?).with('windows').and_return(true)
- recipe.stub(:registry_key_exists?).and_return(false)
- recipe.stub(:registry_value_exists?).and_return(false)
+ allow(recipe).to receive(:platform?).with('windows').and_return(true)
+ allow(recipe).to receive(:registry_key_exists?).and_return(false)
+ allow(recipe).to receive(:registry_value_exists?).and_return(false)
end
it 'should return true if "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations" exists' do
- recipe.stub(:registry_value_exists?).with('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager', { :name => 'PendingFileRenameOperations' }).and_return(true)
- expect(recipe.reboot_pending?).to be_true
+ allow(recipe).to receive(:registry_value_exists?).with('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager', { :name => 'PendingFileRenameOperations' }).and_return(true)
+ expect(recipe.reboot_pending?).to be_truthy
end
it 'should return true if "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" exists' do
- recipe.stub(:registry_key_exists?).with('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired').and_return(true)
- expect(recipe.reboot_pending?).to be_true
+ allow(recipe).to receive(:registry_key_exists?).with('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired').and_return(true)
+ expect(recipe.reboot_pending?).to be_truthy
end
it 'should return true if key "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired" exists' do
- recipe.stub(:registry_key_exists?).with('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired').and_return(true)
- expect(recipe.reboot_pending?).to be_true
+ allow(recipe).to receive(:registry_key_exists?).with('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootRequired').and_return(true)
+ expect(recipe.reboot_pending?).to be_truthy
end
it 'should return true if value "HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile" contains specific data' do
- recipe.stub(:registry_key_exists?).with('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile').and_return(true)
- recipe.stub(:registry_get_values).with('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile').and_return(
+ allow(recipe).to receive(:registry_key_exists?).with('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile').and_return(true)
+ allow(recipe).to receive(:registry_get_values).with('HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile').and_return(
[{:name => "Flags", :type => :dword, :data => 3}])
- expect(recipe.reboot_pending?).to be_true
+ expect(recipe.reboot_pending?).to be_truthy
end
end
context "platform is ubuntu" do
before do
- recipe.stub(:platform?).with('ubuntu').and_return(true)
+ allow(recipe).to receive(:platform?).with('ubuntu').and_return(true)
end
it 'should return true if /var/run/reboot-required exists' do
- File.stub(:exists?).with('/var/run/reboot-required').and_return(true)
- expect(recipe.reboot_pending?).to be_true
+ allow(File).to receive(:exists?).with('/var/run/reboot-required').and_return(true)
+ expect(recipe.reboot_pending?).to be_truthy
end
it 'should return false if /var/run/reboot-required does not exist' do
- File.stub(:exists?).with('/var/run/reboot-required').and_return(false)
- expect(recipe.reboot_pending?).to be_false
+ allow(File).to receive(:exists?).with('/var/run/reboot-required').and_return(false)
+ expect(recipe.reboot_pending?).to be_falsey
end
end
diff --git a/spec/unit/dsl/regsitry_helper_spec.rb b/spec/unit/dsl/regsitry_helper_spec.rb
index 7fe08e310f..6508a12b6f 100644
--- a/spec/unit/dsl/regsitry_helper_spec.rb
+++ b/spec/unit/dsl/regsitry_helper_spec.rb
@@ -33,22 +33,22 @@ describe Chef::Resource::RegistryKey do
context "tests registry dsl" do
it "resource can access registry_helper method registry_key_exists" do
- @resource.respond_to?('registry_key_exists?').should == true
+ expect(@resource.respond_to?('registry_key_exists?')).to eq(true)
end
it "resource can access registry_helper method registry_get_values" do
- @resource.respond_to?('registry_get_values').should == true
+ expect(@resource.respond_to?('registry_get_values')).to eq(true)
end
it "resource can access registry_helper method registry_has_subkey" do
- @resource.respond_to?('registry_has_subkeys?').should == true
+ expect(@resource.respond_to?('registry_has_subkeys?')).to eq(true)
end
it "resource can access registry_helper method registry_get_subkeys" do
- @resource.respond_to?('registry_get_subkeys').should == true
+ expect(@resource.respond_to?('registry_get_subkeys')).to eq(true)
end
it "resource can access registry_helper method registry_value_exists" do
- @resource.respond_to?('registry_value_exists?').should == true
+ expect(@resource.respond_to?('registry_value_exists?')).to eq(true)
end
it "resource can access registry_helper method data_value_exists" do
- @resource.respond_to?('registry_data_exists?').should == true
+ expect(@resource.respond_to?('registry_data_exists?')).to eq(true)
end
end
end
diff --git a/spec/unit/encrypted_data_bag_item_spec.rb b/spec/unit/encrypted_data_bag_item_spec.rb
index 499fabdcf9..0a4306727b 100644
--- a/spec/unit/encrypted_data_bag_item_spec.rb
+++ b/spec/unit/encrypted_data_bag_item_spec.rb
@@ -39,7 +39,7 @@ describe Chef::EncryptedDataBagItem::Encryptor do
let(:key) { "passwd" }
it "encrypts to format version 1 by default" do
- encryptor.should be_a_instance_of(Chef::EncryptedDataBagItem::Encryptor::Version1Encryptor)
+ expect(encryptor).to be_a_instance_of(Chef::EncryptedDataBagItem::Encryptor::Version1Encryptor)
end
describe "generating a random IV" do
@@ -49,14 +49,14 @@ describe Chef::EncryptedDataBagItem::Encryptor do
# No API in ruby OpenSSL to get the iv is used for the encryption back
# out. Instead we test if the encrypted data is the same. If it *is* the
# same, we assume the IV was the same each time.
- encryptor.encrypted_data.should_not eq encryptor2.encrypted_data
+ expect(encryptor.encrypted_data).not_to eq encryptor2.encrypted_data
end
end
describe "when encrypting a non-hash non-array value" do
let(:plaintext_data) { 5 }
it "serializes the value in a de-serializable way" do
- Chef::JSONCompat.from_json(encryptor.serialized_data)["json_wrapper"].should eq 5
+ expect(Chef::JSONCompat.from_json(encryptor.serialized_data)["json_wrapper"]).to eq 5
end
end
@@ -64,10 +64,10 @@ describe Chef::EncryptedDataBagItem::Encryptor do
describe "wrapping secret values in an envelope" do
it "wraps the encrypted data in an envelope with the iv and version" do
final_data = encryptor.for_encrypted_item
- final_data["encrypted_data"].should eq encryptor.encrypted_data
- final_data["iv"].should eq Base64.encode64(encryptor.iv)
- final_data["version"].should eq 1
- final_data["cipher"].should eq"aes-256-cbc"
+ expect(final_data["encrypted_data"]).to eq encryptor.encrypted_data
+ expect(final_data["iv"]).to eq Base64.encode64(encryptor.iv)
+ expect(final_data["version"]).to eq 1
+ expect(final_data["cipher"]).to eq"aes-256-cbc"
end
end
@@ -78,17 +78,17 @@ describe Chef::EncryptedDataBagItem::Encryptor do
end
it "creates a version 2 encryptor" do
- encryptor.should be_a_instance_of(Chef::EncryptedDataBagItem::Encryptor::Version2Encryptor)
+ expect(encryptor).to be_a_instance_of(Chef::EncryptedDataBagItem::Encryptor::Version2Encryptor)
end
it "generates an hmac based on ciphertext with different iv" do
encryptor2 = Chef::EncryptedDataBagItem::Encryptor.new(plaintext_data, key)
- encryptor.hmac.should_not eq(encryptor2.hmac)
+ expect(encryptor.hmac).not_to eq(encryptor2.hmac)
end
it "includes the hmac in the envelope" do
final_data = encryptor.for_encrypted_item
- final_data["hmac"].should eq(encryptor.hmac)
+ expect(final_data["hmac"]).to eq(encryptor.hmac)
end
end
@@ -100,23 +100,23 @@ describe Chef::EncryptedDataBagItem::Encryptor do
context "on supported platforms", :aes_256_gcm_only, :ruby_20_only do
it "creates a version 3 encryptor" do
- encryptor.should be_a_instance_of(Chef::EncryptedDataBagItem::Encryptor::Version3Encryptor)
+ expect(encryptor).to be_a_instance_of(Chef::EncryptedDataBagItem::Encryptor::Version3Encryptor)
end
it "generates different authentication tags" do
encryptor3 = Chef::EncryptedDataBagItem::Encryptor.new(plaintext_data, key)
encryptor.for_encrypted_item # required to generate the auth_tag
encryptor3.for_encrypted_item
- encryptor.auth_tag.should_not eq(encryptor3.auth_tag)
+ expect(encryptor.auth_tag).not_to eq(encryptor3.auth_tag)
end
it "includes the auth_tag in the envelope" do
final_data = encryptor.for_encrypted_item
- final_data["auth_tag"].should eq(Base64::encode64(encryptor.auth_tag))
+ expect(final_data["auth_tag"]).to eq(Base64::encode64(encryptor.auth_tag))
end
it "throws an error if auth tag is read before encrypting the data" do
- lambda { encryptor.auth_tag }.should raise_error(Chef::EncryptedDataBagItem::EncryptionFailure)
+ expect { encryptor.auth_tag }.to raise_error(Chef::EncryptedDataBagItem::EncryptionFailure)
end
end # context on supported platforms
@@ -124,34 +124,18 @@ describe Chef::EncryptedDataBagItem::Encryptor do
context "on unsupported platforms" do
let(:aead_algorithm) { Chef::EncryptedDataBagItem::AEAD_ALGORITHM }
- it "throws an error warning about the Ruby version if it has no GCM support" do
- # Force OpenSSL with AEAD support
- OpenSSL::Cipher.stub(:ciphers).and_return([ aead_algorithm ])
- # Ruby without AEAD support
- OpenSSL::Cipher.should_receive(:method_defined?).with(:auth_data=).and_return(false)
- lambda { encryptor }.should raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires Ruby/)
- end
-
it "throws an error warning about the OpenSSL version if it has no GCM support" do
# Force Ruby with AEAD support
- OpenSSL::Cipher.stub(:method_defined?).with(:auth_data=).and_return(true)
+ allow(OpenSSL::Cipher).to receive(:method_defined?).with(:auth_data=).and_return(true)
# OpenSSL without AEAD support
- OpenSSL::Cipher.should_receive(:ciphers).and_return([])
- lambda { encryptor }.should raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires an OpenSSL/)
+ expect(OpenSSL::Cipher).to receive(:ciphers).and_return([])
+ expect { encryptor }.to raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires an OpenSSL/)
end
- context "on platforms with old Ruby", :ruby_lt_20 do
-
- it "throws an error warning about the Ruby version" do
- lambda { encryptor }.should raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires Ruby/)
- end
-
- end # context on platforms with old Ruby
-
context "on platforms with old OpenSSL", :openssl_lt_101 do
it "throws an error warning about the OpenSSL version" do
- lambda { encryptor }.should raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires an OpenSSL/)
+ expect { encryptor }.to raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires an OpenSSL/)
end
end # context on platforms with old OpenSSL
@@ -172,11 +156,11 @@ describe Chef::EncryptedDataBagItem::Decryptor do
shared_examples "decryption examples" do
it "decrypts the encrypted value" do
- decryptor.decrypted_data.should eq(json_wrapped_data)
+ expect(decryptor.decrypted_data).to eq(json_wrapped_data)
end
it "unwraps the encrypted data and returns it" do
- decryptor.for_decrypted_item.should eq plaintext_data
+ expect(decryptor.for_decrypted_item).to eq plaintext_data
end
end
@@ -194,12 +178,12 @@ describe Chef::EncryptedDataBagItem::Decryptor do
it "rejects the data if the authentication tag is wrong" do
encrypted_value["auth_tag"] = bogus_auth_tag
- lambda { decryptor.for_decrypted_item }.should raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
+ expect { decryptor.for_decrypted_item }.to raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
end
it "rejects the data if the authentication tag is missing" do
encrypted_value.delete("auth_tag")
- lambda { decryptor.for_decrypted_item }.should raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
+ expect { decryptor.for_decrypted_item }.to raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
end
end # context on supported platforms
@@ -214,18 +198,10 @@ describe Chef::EncryptedDataBagItem::Decryptor do
}
end
- context "on platforms with old Ruby", :ruby_lt_20 do
-
- it "throws an error warning about the Ruby version" do
- lambda { decryptor }.should raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires Ruby/)
- end
-
- end # context on platforms with old Ruby
-
context "on platforms with old OpenSSL", :openssl_lt_101 do
it "throws an error warning about the OpenSSL version" do
- lambda { decryptor }.should raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires an OpenSSL/)
+ expect { decryptor }.to raise_error(Chef::EncryptedDataBagItem::EncryptedDataBagRequirementsFailure, /requires an OpenSSL/)
end
end # context on unsupported platforms
@@ -249,12 +225,12 @@ describe Chef::EncryptedDataBagItem::Decryptor do
it "rejects the data if the hmac is wrong" do
encrypted_value["hmac"] = bogus_hmac
- lambda { decryptor.for_decrypted_item }.should raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
+ expect { decryptor.for_decrypted_item }.to raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
end
it "rejects the data if the hmac is missing" do
encrypted_value.delete("hmac")
- lambda { decryptor.for_decrypted_item }.should raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
+ expect { decryptor.for_decrypted_item }.to raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
end
end
@@ -266,7 +242,7 @@ describe Chef::EncryptedDataBagItem::Decryptor do
end
it "selects the correct strategy for version 1" do
- decryptor.should be_a_instance_of Chef::EncryptedDataBagItem::Decryptor::Version1Decryptor
+ expect(decryptor).to be_a_instance_of Chef::EncryptedDataBagItem::Decryptor::Version1Decryptor
end
include_examples "decryption examples"
@@ -276,8 +252,8 @@ describe Chef::EncryptedDataBagItem::Decryptor do
# Over a large number of tests on a variety of systems, we occasionally
# see the decryption step "succeed" but return invalid data (e.g., not
# the original plain text) [CHEF-3858]
- decryptor.should_receive(:decrypted_data).and_return("lksajdf")
- lambda { decryptor.for_decrypted_item }.should raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
+ expect(decryptor).to receive(:decrypted_data).and_return("lksajdf")
+ expect { decryptor.for_decrypted_item }.to raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
end
end
@@ -285,7 +261,7 @@ describe Chef::EncryptedDataBagItem::Decryptor do
let(:decryption_key) { "wrong-passwd" }
it "raises a sensible error" do
- lambda { decryptor.for_decrypted_item }.should raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
+ expect { decryptor.for_decrypted_item }.to raise_error(Chef::EncryptedDataBagItem::DecryptionFailure)
end
end
@@ -297,7 +273,7 @@ describe Chef::EncryptedDataBagItem::Decryptor do
end
it "raises a sensible error" do
- lambda { decryptor.for_decrypted_item }.should raise_error(Chef::EncryptedDataBagItem::UnsupportedCipher)
+ expect { decryptor.for_decrypted_item }.to raise_error(Chef::EncryptedDataBagItem::UnsupportedCipher)
end
end
@@ -307,7 +283,7 @@ describe Chef::EncryptedDataBagItem::Decryptor do
end
it "raises an error attempting to decrypt" do
- lambda { decryptor }.should raise_error(Chef::EncryptedDataBagItem::UnacceptableEncryptedDataBagItemFormat)
+ expect { decryptor }.to raise_error(Chef::EncryptedDataBagItem::UnacceptableEncryptedDataBagItemFormat)
end
end
@@ -320,11 +296,11 @@ describe Chef::EncryptedDataBagItem::Decryptor do
end
it "selects the correct strategy for version 0" do
- decryptor.should be_a_instance_of(Chef::EncryptedDataBagItem::Decryptor::Version0Decryptor)
+ expect(decryptor).to be_a_instance_of(Chef::EncryptedDataBagItem::Decryptor::Version0Decryptor)
end
it "decrypts the encrypted value" do
- decryptor.for_decrypted_item.should eq plaintext_data
+ expect(decryptor.for_decrypted_item).to eq plaintext_data
end
context "and version 1 format is required" do
@@ -333,7 +309,7 @@ describe Chef::EncryptedDataBagItem::Decryptor do
end
it "raises an error attempting to decrypt" do
- lambda { decryptor }.should raise_error(Chef::EncryptedDataBagItem::UnacceptableEncryptedDataBagItemFormat)
+ expect { decryptor }.to raise_error(Chef::EncryptedDataBagItem::UnacceptableEncryptedDataBagItemFormat)
end
end
@@ -355,27 +331,27 @@ describe Chef::EncryptedDataBagItem do
describe "encrypting" do
it "doesn't encrypt the 'id' key" do
- encoded_data["id"].should eq "item_name"
+ expect(encoded_data["id"]).to eq "item_name"
end
it "encrypts non-collection objects" do
- encoded_data["greeting"]["version"].should eq 1
- encoded_data["greeting"].should have_key("iv")
+ expect(encoded_data["greeting"]["version"]).to eq 1
+ expect(encoded_data["greeting"]).to have_key("iv")
iv = encoded_data["greeting"]["iv"]
encryptor = Chef::EncryptedDataBagItem::Encryptor.new("hello", secret, iv)
- encoded_data["greeting"]["encrypted_data"].should eq(encryptor.for_encrypted_item["encrypted_data"])
+ expect(encoded_data["greeting"]["encrypted_data"]).to eq(encryptor.for_encrypted_item["encrypted_data"])
end
it "encrypts nested values" do
- encoded_data["nested"]["version"].should eq 1
- encoded_data["nested"].should have_key("iv")
+ expect(encoded_data["nested"]["version"]).to eq 1
+ expect(encoded_data["nested"]).to have_key("iv")
iv = encoded_data["nested"]["iv"]
encryptor = Chef::EncryptedDataBagItem::Encryptor.new(plaintext_data["nested"], secret, iv)
- encoded_data["nested"]["encrypted_data"].should eq(encryptor.for_encrypted_item["encrypted_data"])
+ expect(encoded_data["nested"]["encrypted_data"]).to eq(encryptor.for_encrypted_item["encrypted_data"])
end
end
@@ -383,31 +359,31 @@ describe Chef::EncryptedDataBagItem do
describe "decrypting" do
it "doesn't try to decrypt 'id'" do
- encrypted_data_bag_item["id"].should eq(plaintext_data["id"])
+ expect(encrypted_data_bag_item["id"]).to eq(plaintext_data["id"])
end
it "decrypts 'greeting'" do
- encrypted_data_bag_item["greeting"].should eq(plaintext_data["greeting"])
+ expect(encrypted_data_bag_item["greeting"]).to eq(plaintext_data["greeting"])
end
it "decrypts 'nested'" do
- encrypted_data_bag_item["nested"].should eq(plaintext_data["nested"])
+ expect(encrypted_data_bag_item["nested"]).to eq(plaintext_data["nested"])
end
it "decrypts everyting via to_hash" do
- encrypted_data_bag_item.to_hash.should eq(plaintext_data)
+ expect(encrypted_data_bag_item.to_hash).to eq(plaintext_data)
end
it "handles missing keys gracefully" do
- encrypted_data_bag_item["no-such-key"].should be_nil
+ expect(encrypted_data_bag_item["no-such-key"]).to be_nil
end
end
describe "loading" do
it "should defer to Chef::DataBagItem.load" do
- Chef::DataBagItem.stub(:load).with(:the_bag, "my_codes").and_return(encoded_data)
+ allow(Chef::DataBagItem).to receive(:load).with(:the_bag, "my_codes").and_return(encoded_data)
edbi = Chef::EncryptedDataBagItem.load(:the_bag, "my_codes", secret)
- edbi["greeting"].should eq(plaintext_data["greeting"])
+ expect(edbi["greeting"]).to eq(plaintext_data["greeting"])
end
end
@@ -416,45 +392,45 @@ describe Chef::EncryptedDataBagItem do
context "when /var/mysecret exists" do
before do
- ::File.stub(:exist?).with("/var/mysecret").and_return(true)
- IO.stub(:read).with("/var/mysecret").and_return(secret)
+ allow(::File).to receive(:exist?).with("/var/mysecret").and_return(true)
+ allow(IO).to receive(:read).with("/var/mysecret").and_return(secret)
end
it "load_secret('/var/mysecret') reads the secret" do
- Chef::EncryptedDataBagItem.load_secret("/var/mysecret").should eq secret
+ expect(Chef::EncryptedDataBagItem.load_secret("/var/mysecret")).to eq secret
end
end
context "when /etc/chef/encrypted_data_bag_secret exists" do
before do
path = Chef::Config.platform_specific_path("/etc/chef/encrypted_data_bag_secret")
- ::File.stub(:exist?).with(path).and_return(true)
- IO.stub(:read).with(path).and_return(secret)
+ allow(::File).to receive(:exist?).with(path).and_return(true)
+ allow(IO).to receive(:read).with(path).and_return(secret)
end
it "load_secret(nil) reads the secret" do
- Chef::EncryptedDataBagItem.load_secret(nil).should eq secret
+ expect(Chef::EncryptedDataBagItem.load_secret(nil)).to eq secret
end
end
context "when /etc/chef/encrypted_data_bag_secret does not exist" do
before do
path = Chef::Config.platform_specific_path("/etc/chef/encrypted_data_bag_secret")
- ::File.stub(:exist?).with(path).and_return(false)
+ allow(::File).to receive(:exist?).with(path).and_return(false)
end
it "load_secret(nil) emits a reasonable error message" do
- lambda { Chef::EncryptedDataBagItem.load_secret(nil) }.should raise_error(ArgumentError, /No secret specified and no secret found at #{Chef::Config[:encrypted_data_bag_secret]}/)
+ expect { Chef::EncryptedDataBagItem.load_secret(nil) }.to raise_error(ArgumentError, /No secret specified and no secret found at #{Chef::Config[:encrypted_data_bag_secret]}/)
end
end
context "path argument is a URL" do
before do
- Kernel.stub(:open).with("http://www.opscode.com/").and_return(StringIO.new(secret))
+ allow(Kernel).to receive(:open).with("http://www.opscode.com/").and_return(StringIO.new(secret))
end
it "reads from the URL" do
- Chef::EncryptedDataBagItem.load_secret("http://www.opscode.com/").should eq secret
+ expect(Chef::EncryptedDataBagItem.load_secret("http://www.opscode.com/")).to eq secret
end
end
end
diff --git a/spec/unit/environment_spec.rb b/spec/unit/environment_spec.rb
index ffb8fbfeaf..ee3b8b21e1 100644
--- a/spec/unit/environment_spec.rb
+++ b/spec/unit/environment_spec.rb
@@ -29,75 +29,75 @@ describe Chef::Environment do
describe "initialize" do
it "should be a Chef::Environment" do
- @environment.should be_a_kind_of(Chef::Environment)
+ expect(@environment).to be_a_kind_of(Chef::Environment)
end
end
describe "name" do
it "should let you set the name to a string" do
- @environment.name("production").should == "production"
+ expect(@environment.name("production")).to eq("production")
end
it "should return the current name" do
@environment.name("production")
- @environment.name.should == "production"
+ expect(@environment.name).to eq("production")
end
it "should not accept spaces" do
- lambda { @environment.name("production environment") }.should raise_error(ArgumentError)
+ expect { @environment.name("production environment") }.to raise_error(ArgumentError)
end
it "should not accept anything but strings" do
- lambda { @environment.name(Array.new) }.should raise_error(ArgumentError)
- lambda { @environment.name(Hash.new) }.should raise_error(ArgumentError)
- lambda { @environment.name(2) }.should raise_error(ArgumentError)
+ expect { @environment.name(Array.new) }.to raise_error(ArgumentError)
+ expect { @environment.name(Hash.new) }.to raise_error(ArgumentError)
+ expect { @environment.name(2) }.to raise_error(ArgumentError)
end
end
describe "description" do
it "should let you set the description to a string" do
- @environment.description("this is my test environment").should == "this is my test environment"
+ expect(@environment.description("this is my test environment")).to eq("this is my test environment")
end
it "should return the correct description" do
@environment.description("I like running tests")
- @environment.description.should == "I like running tests"
+ expect(@environment.description).to eq("I like running tests")
end
it "should not accept anything but strings" do
- lambda { @environment.description(Array.new) }.should raise_error(ArgumentError)
- lambda { @environment.description(Hash.new) }.should raise_error(ArgumentError)
- lambda { @environment.description(42) }.should raise_error(ArgumentError)
+ expect { @environment.description(Array.new) }.to raise_error(ArgumentError)
+ expect { @environment.description(Hash.new) }.to raise_error(ArgumentError)
+ expect { @environment.description(42) }.to raise_error(ArgumentError)
end
end
describe "default attributes" do
it "should let you set the attributes hash explicitly" do
- @environment.default_attributes({ :one => 'two' }).should == { :one => 'two' }
+ expect(@environment.default_attributes({ :one => 'two' })).to eq({ :one => 'two' })
end
it "should let you return the attributes hash" do
@environment.default_attributes({ :one => 'two' })
- @environment.default_attributes.should == { :one => 'two' }
+ expect(@environment.default_attributes).to eq({ :one => 'two' })
end
it "should throw an ArgumentError if we aren't a kind of hash" do
- lambda { @environment.default_attributes(Array.new) }.should raise_error(ArgumentError)
+ expect { @environment.default_attributes(Array.new) }.to raise_error(ArgumentError)
end
end
describe "override attributes" do
it "should let you set the attributes hash explicitly" do
- @environment.override_attributes({ :one => 'two' }).should == { :one => 'two' }
+ expect(@environment.override_attributes({ :one => 'two' })).to eq({ :one => 'two' })
end
it "should let you return the attributes hash" do
@environment.override_attributes({ :one => 'two' })
- @environment.override_attributes.should == { :one => 'two' }
+ expect(@environment.override_attributes).to eq({ :one => 'two' })
end
it "should throw an ArgumentError if we aren't a kind of hash" do
- lambda { @environment.override_attributes(Array.new) }.should raise_error(ArgumentError)
+ expect { @environment.override_attributes(Array.new) }.to raise_error(ArgumentError)
end
end
@@ -111,22 +111,22 @@ describe Chef::Environment do
end
it "should let you set the cookbook versions in a hash" do
- @environment.cookbook_versions(@cookbook_versions).should == @cookbook_versions
+ expect(@environment.cookbook_versions(@cookbook_versions)).to eq(@cookbook_versions)
end
it "should return the cookbook versions" do
@environment.cookbook_versions(@cookbook_versions)
- @environment.cookbook_versions.should == @cookbook_versions
+ expect(@environment.cookbook_versions).to eq(@cookbook_versions)
end
it "should not accept anything but a hash" do
- lambda { @environment.cookbook_versions("I am a string!") }.should raise_error(ArgumentError)
- lambda { @environment.cookbook_versions(Array.new) }.should raise_error(ArgumentError)
- lambda { @environment.cookbook_versions(42) }.should raise_error(ArgumentError)
+ expect { @environment.cookbook_versions("I am a string!") }.to raise_error(ArgumentError)
+ expect { @environment.cookbook_versions(Array.new) }.to raise_error(ArgumentError)
+ expect { @environment.cookbook_versions(42) }.to raise_error(ArgumentError)
end
it "should validate the hash" do
- Chef::Environment.should_receive(:validate_cookbook_versions).with(@cookbook_versions).and_return true
+ expect(Chef::Environment).to receive(:validate_cookbook_versions).with(@cookbook_versions).and_return true
@environment.cookbook_versions(@cookbook_versions)
end
end
@@ -134,11 +134,11 @@ describe Chef::Environment do
describe "cookbook" do
it "should set the version of the cookbook in the cookbook_versions hash" do
@environment.cookbook("apt", "~> 1.2.3")
- @environment.cookbook_versions["apt"].should == "~> 1.2.3"
+ expect(@environment.cookbook_versions["apt"]).to eq("~> 1.2.3")
end
it "should validate the cookbook version it is passed" do
- Chef::Environment.should_receive(:validate_cookbook_version).with(">= 1.2.3").and_return true
+ expect(Chef::Environment).to receive(:validate_cookbook_version).with(">= 1.2.3").and_return true
@environment.cookbook("apt", ">= 1.2.3")
end
end
@@ -157,9 +157,9 @@ describe Chef::Environment do
it "should update everything but name" do
@environment.update_from!(@example)
- @environment.name.should == "prod"
- @environment.description.should == @example.description
- @environment.cookbook_versions.should == @example.cookbook_versions
+ expect(@environment.name).to eq("prod")
+ expect(@environment.description).to eq(@example.description)
+ expect(@environment.cookbook_versions).to eq(@example.cookbook_versions)
end
end
@@ -173,16 +173,16 @@ describe Chef::Environment do
%w{name description cookbook_versions}.each do |t|
it "should include '#{t}'" do
- @hash[t].should == @environment.send(t.to_sym)
+ expect(@hash[t]).to eq(@environment.send(t.to_sym))
end
end
it "should include 'json_class'" do
- @hash["json_class"].should == "Chef::Environment"
+ expect(@hash["json_class"]).to eq("Chef::Environment")
end
it "should include 'chef_type'" do
- @hash["chef_type"].should == "environment"
+ expect(@hash["chef_type"]).to eq("environment")
end
end
@@ -196,16 +196,16 @@ describe Chef::Environment do
%w{name description cookbook_versions}.each do |t|
it "should include '#{t}'" do
- @json.should =~ /"#{t}":#{Regexp.escape(Chef::JSONCompat.to_json(@environment.send(t.to_sym)))}/
+ expect(@json).to match(/"#{t}":#{Regexp.escape(Chef::JSONCompat.to_json(@environment.send(t.to_sym)))}/)
end
end
it "should include 'json_class'" do
- @json.should =~ /"json_class":"Chef::Environment"/
+ expect(@json).to match(/"json_class":"Chef::Environment"/)
end
it "should include 'chef_type'" do
- @json.should =~ /"chef_type":"environment"/
+ expect(@json).to match(/"chef_type":"environment"/)
end
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
@@ -230,12 +230,12 @@ describe Chef::Environment do
end
it "should return a Chef::Environment" do
- @environment.should be_a_kind_of(Chef::Environment)
+ expect(@environment).to be_a_kind_of(Chef::Environment)
end
%w{name description cookbook_versions}.each do |t|
it "should match '#{t}'" do
- @environment.send(t.to_sym).should == @data[t]
+ expect(@environment.send(t.to_sym)).to eq(@data[t])
end
end
end
@@ -251,39 +251,39 @@ describe Chef::Environment do
it "should validate the version string of each cookbook" do
@cookbook_versions.each do |cookbook, version|
- Chef::Environment.should_receive(:validate_cookbook_version).with(version).and_return true
+ expect(Chef::Environment).to receive(:validate_cookbook_version).with(version).and_return true
end
Chef::Environment.validate_cookbook_versions(@cookbook_versions)
end
it "should return false if anything other than a hash is passed as the argument" do
- Chef::Environment.validate_cookbook_versions(Array.new).should == false
- Chef::Environment.validate_cookbook_versions(42).should == false
- Chef::Environment.validate_cookbook_versions(Chef::CookbookVersion.new("meta")).should == false
- Chef::Environment.validate_cookbook_versions("cookbook => 1.2.3").should == false
+ expect(Chef::Environment.validate_cookbook_versions(Array.new)).to eq(false)
+ expect(Chef::Environment.validate_cookbook_versions(42)).to eq(false)
+ expect(Chef::Environment.validate_cookbook_versions(Chef::CookbookVersion.new("meta"))).to eq(false)
+ expect(Chef::Environment.validate_cookbook_versions("cookbook => 1.2.3")).to eq(false)
end
end
describe "self.validate_cookbook_version" do
it "should validate correct version numbers" do
- Chef::Environment.validate_cookbook_version("= 1.2.3").should == true
- Chef::Environment.validate_cookbook_version("=1.2.3").should == true
- Chef::Environment.validate_cookbook_version(">= 0.0.3").should == true
- Chef::Environment.validate_cookbook_version(">=0.0.3").should == true
+ expect(Chef::Environment.validate_cookbook_version("= 1.2.3")).to eq(true)
+ expect(Chef::Environment.validate_cookbook_version("=1.2.3")).to eq(true)
+ expect(Chef::Environment.validate_cookbook_version(">= 0.0.3")).to eq(true)
+ expect(Chef::Environment.validate_cookbook_version(">=0.0.3")).to eq(true)
# A lone version is allowed, interpreted as implicit '='
- Chef::Environment.validate_cookbook_version("1.2.3").should == true
+ expect(Chef::Environment.validate_cookbook_version("1.2.3")).to eq(true)
end
it "should return false when an invalid version is given" do
- Chef::Environment.validate_cookbook_version(Chef::CookbookVersion.new("meta")).should == false
- Chef::Environment.validate_cookbook_version("= 1.2.3a").should == false
- Chef::Environment.validate_cookbook_version("=1.2.3a").should == false
- Chef::Environment.validate_cookbook_version("= 1").should == false
- Chef::Environment.validate_cookbook_version("=1").should == false
- Chef::Environment.validate_cookbook_version("= a").should == false
- Chef::Environment.validate_cookbook_version("=a").should == false
- Chef::Environment.validate_cookbook_version("= 1.2.3.4").should == false
- Chef::Environment.validate_cookbook_version("=1.2.3.4").should == false
+ expect(Chef::Environment.validate_cookbook_version(Chef::CookbookVersion.new("meta"))).to eq(false)
+ expect(Chef::Environment.validate_cookbook_version("= 1.2.3a")).to eq(false)
+ expect(Chef::Environment.validate_cookbook_version("=1.2.3a")).to eq(false)
+ expect(Chef::Environment.validate_cookbook_version("= 1")).to eq(false)
+ expect(Chef::Environment.validate_cookbook_version("=1")).to eq(false)
+ expect(Chef::Environment.validate_cookbook_version("= a")).to eq(false)
+ expect(Chef::Environment.validate_cookbook_version("=a")).to eq(false)
+ expect(Chef::Environment.validate_cookbook_version("= 1.2.3.4")).to eq(false)
+ expect(Chef::Environment.validate_cookbook_version("=1.2.3.4")).to eq(false)
end
describe "in solo mode" do
@@ -296,9 +296,9 @@ describe Chef::Environment do
end
it "should raise and exception" do
- lambda {
+ expect {
Chef::Environment.validate_cookbook_version("= 1.2.3.4")
- }.should raise_error Chef::Exceptions::IllegalVersionConstraint,
+ }.to raise_error Chef::Exceptions::IllegalVersionConstraint,
"Environment cookbook version constraints not allowed in chef-solo"
end
end
@@ -312,17 +312,17 @@ describe Chef::Environment do
it "updates the name from parameters[:name]" do
@environment.update_from_params(:name => "kurrupt")
- @environment.name.should == "kurrupt"
+ expect(@environment.name).to eq("kurrupt")
end
it "validates the name given in the params" do
- @environment.update_from_params(:name => "@$%^&*()").should be_false
- @environment.invalid_fields[:name].should == %q|Option name's value @$%^&*() does not match regular expression /^[\-[:alnum:]_]+$/|
+ expect(@environment.update_from_params(:name => "@$%^&*()")).to be_falsey
+ expect(@environment.invalid_fields[:name]).to eq(%q|Option name's value @$%^&*() does not match regular expression /^[\-[:alnum:]_]+$/|)
end
it "updates the description from parameters[:description]" do
@environment.update_from_params(:description => "wow, writing your own object mapper is kinda painful")
- @environment.description.should == "wow, writing your own object mapper is kinda painful"
+ expect(@environment.description).to eq("wow, writing your own object mapper is kinda painful")
end
it "updates cookbook version constraints from the hash in parameters[:cookbook_version_constraints]" do
@@ -331,34 +331,34 @@ describe Chef::Environment do
# the way merb does params
params = {:name=>"superbowl", :cookbook_version => {"0" => "apache2 ~> 1.0.0", "1" => "nginx < 2.0.0"}}
@environment.update_from_params(params)
- @environment.cookbook_versions.should == {"apache2" => "~> 1.0.0", "nginx" => "< 2.0.0"}
+ expect(@environment.cookbook_versions).to eq({"apache2" => "~> 1.0.0", "nginx" => "< 2.0.0"})
end
it "validates the cookbook constraints" do
params = {:cookbook_version => {"0" => "apache2 >>> 1.0.0"}}
- @environment.update_from_params(params).should be_false
+ expect(@environment.update_from_params(params)).to be_falsey
err_msg = @environment.invalid_fields[:cookbook_version]["0"]
- err_msg.should == "apache2 >>> 1.0.0 is not a valid cookbook constraint"
+ expect(err_msg).to eq("apache2 >>> 1.0.0 is not a valid cookbook constraint")
end
it "is not valid if the name is not present" do
- @environment.validate_required_attrs_present.should be_false
- @environment.invalid_fields[:name].should == "name cannot be empty"
+ expect(@environment.validate_required_attrs_present).to be_falsey
+ expect(@environment.invalid_fields[:name]).to eq("name cannot be empty")
end
it "is not valid after updating from params if the name is not present" do
- @environment.update_from_params({}).should be_false
- @environment.invalid_fields[:name].should == "name cannot be empty"
+ expect(@environment.update_from_params({})).to be_falsey
+ expect(@environment.invalid_fields[:name]).to eq("name cannot be empty")
end
it "updates default attributes from a JSON string in params[:attributes]" do
@environment.update_from_params(:name => "fuuu", :default_attributes => %q|{"fuuu":"RAGE"}|)
- @environment.default_attributes.should == {"fuuu" => "RAGE"}
+ expect(@environment.default_attributes).to eq({"fuuu" => "RAGE"})
end
it "updates override attributes from a JSON string in params[:attributes]" do
@environment.update_from_params(:name => "fuuu", :override_attributes => %q|{"foo":"override"}|)
- @environment.override_attributes.should == {"foo" => "override"}
+ expect(@environment.override_attributes).to eq({"foo" => "override"})
end
end
@@ -366,25 +366,25 @@ describe Chef::Environment do
describe "api model" do
before(:each) do
@rest = double("Chef::REST")
- Chef::REST.stub(:new).and_return(@rest)
+ allow(Chef::REST).to receive(:new).and_return(@rest)
@query = double("Chef::Search::Query")
- Chef::Search::Query.stub(:new).and_return(@query)
+ allow(Chef::Search::Query).to receive(:new).and_return(@query)
end
describe "list" do
describe "inflated" do
it "should return a hash of environment names and objects" do
e1 = double("Chef::Environment", :name => "one")
- @query.should_receive(:search).with(:environment).and_yield(e1)
+ expect(@query).to receive(:search).with(:environment).and_yield(e1)
r = Chef::Environment.list(true)
- r["one"].should == e1
+ expect(r["one"]).to eq(e1)
end
end
it "should return a hash of environment names and urls" do
- @rest.should_receive(:get_rest).and_return({ "one" => "http://foo" })
+ expect(@rest).to receive(:get_rest).and_return({ "one" => "http://foo" })
r = Chef::Environment.list
- r["one"].should == "http://foo"
+ expect(r["one"]).to eq("http://foo")
end
end
end
@@ -401,18 +401,18 @@ describe Chef::Environment do
end
it "should get the environment from the environment_path" do
- File.should_receive(:directory?).with(Chef::Config[:environment_path]).and_return(true)
- File.should_receive(:exists?).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(false)
- File.should_receive(:exists?).with(File.join(Chef::Config[:environment_path], 'foo.rb')).exactly(2).times.and_return(true)
- File.should_receive(:readable?).with(File.join(Chef::Config[:environment_path], 'foo.rb')).and_return(true)
+ expect(File).to receive(:directory?).with(Chef::Config[:environment_path]).and_return(true)
+ 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')).exactly(2).times.and_return(true)
+ expect(File).to receive(:readable?).with(File.join(Chef::Config[:environment_path], 'foo.rb')).and_return(true)
role_dsl="name \"foo\"\ndescription \"desc\"\n"
- IO.should_receive(:read).with(File.join(Chef::Config[:environment_path], 'foo.rb')).and_return(role_dsl)
+ expect(IO).to receive(:read).with(File.join(Chef::Config[:environment_path], 'foo.rb')).and_return(role_dsl)
Chef::Environment.load('foo')
end
it "should return a Chef::Environment object from JSON" do
- File.should_receive(:directory?).with(Chef::Config[:environment_path]).and_return(true)
- File.should_receive(:exists?).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(true)
+ expect(File).to receive(:directory?).with(Chef::Config[:environment_path]).and_return(true)
+ expect(File).to receive(:exists?).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(true)
environment_hash = {
"name" => "foo",
"default_attributes" => {
@@ -424,45 +424,45 @@ describe Chef::Environment do
"description" => "desc",
"chef_type" => "environment"
}
- IO.should_receive(:read).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(Chef::JSONCompat.to_json(environment_hash))
+ expect(IO).to receive(:read).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(Chef::JSONCompat.to_json(environment_hash))
environment = Chef::Environment.load('foo')
- environment.should be_a_kind_of(Chef::Environment)
- environment.name.should == environment_hash['name']
- environment.description.should == environment_hash['description']
- environment.default_attributes.should == environment_hash['default_attributes']
+ expect(environment).to be_a_kind_of(Chef::Environment)
+ expect(environment.name).to eq(environment_hash['name'])
+ expect(environment.description).to eq(environment_hash['description'])
+ expect(environment.default_attributes).to eq(environment_hash['default_attributes'])
end
it "should return a Chef::Environment object from Ruby DSL" do
- File.should_receive(:directory?).with(Chef::Config[:environment_path]).and_return(true)
- File.should_receive(:exists?).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(false)
- File.should_receive(:exists?).with(File.join(Chef::Config[:environment_path], 'foo.rb')).exactly(2).times.and_return(true)
- File.should_receive(:readable?).with(File.join(Chef::Config[:environment_path], 'foo.rb')).and_return(true)
+ expect(File).to receive(:directory?).with(Chef::Config[:environment_path]).and_return(true)
+ 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')).exactly(2).times.and_return(true)
+ expect(File).to receive(:readable?).with(File.join(Chef::Config[:environment_path], 'foo.rb')).and_return(true)
role_dsl="name \"foo\"\ndescription \"desc\"\n"
- IO.should_receive(:read).with(File.join(Chef::Config[:environment_path], 'foo.rb')).and_return(role_dsl)
+ expect(IO).to receive(:read).with(File.join(Chef::Config[:environment_path], 'foo.rb')).and_return(role_dsl)
environment = Chef::Environment.load('foo')
- environment.should be_a_kind_of(Chef::Environment)
- environment.name.should == 'foo'
- environment.description.should == 'desc'
+ expect(environment).to be_a_kind_of(Chef::Environment)
+ expect(environment.name).to eq('foo')
+ expect(environment.description).to eq('desc')
end
it 'should raise an error if the configured environment_path is invalid' do
- File.should_receive(:directory?).with(Chef::Config[:environment_path]).and_return(false)
+ expect(File).to receive(:directory?).with(Chef::Config[:environment_path]).and_return(false)
- lambda {
+ expect {
Chef::Environment.load('foo')
- }.should raise_error Chef::Exceptions::InvalidEnvironmentPath, "Environment path '/var/chef/environments' is invalid"
+ }.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
- File.should_receive(:directory?).with(Chef::Config[:environment_path]).and_return(true)
- File.should_receive(:exists?).with(File.join(Chef::Config[:environment_path], 'foo.json')).and_return(false)
- File.should_receive(:exists?).with(File.join(Chef::Config[:environment_path], 'foo.rb')).and_return(false)
+ expect(File).to receive(:directory?).with(Chef::Config[:environment_path]).and_return(true)
+ 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)
- lambda {
+ expect {
Chef::Environment.load('foo')
- }.should raise_error Chef::Exceptions::EnvironmentNotFound, "Environment 'foo' could not be loaded from disk"
+ }.to raise_error Chef::Exceptions::EnvironmentNotFound, "Environment 'foo' could not be loaded from disk"
end
end
end
diff --git a/spec/unit/exceptions_spec.rb b/spec/unit/exceptions_spec.rb
index 21b0abb9bf..d35ecc8ec8 100644
--- a/spec/unit/exceptions_spec.rb
+++ b/spec/unit/exceptions_spec.rb
@@ -72,7 +72,7 @@ describe Chef::Exceptions do
exception_to_super_class.each do |exception, expected_super_class|
it "should have an exception class of #{exception} which inherits from #{expected_super_class}" do
- lambda{ raise exception }.should raise_error(expected_super_class)
+ expect{ raise exception }.to raise_error(expected_super_class)
end
if exception.methods.include?(:to_json)
@@ -81,4 +81,50 @@ describe Chef::Exceptions do
end
end
end
+
+ describe Chef::Exceptions::RunFailedWrappingError do
+ shared_examples "RunFailedWrappingError expectations" do
+ it "should initialize with a default message" do
+ expect(e.message).to eq("Found #{num_errors} errors, they are stored in the backtrace")
+ end
+
+ it "should provide a modified backtrace when requested" do
+ e.fill_backtrace
+ expect(e.backtrace).to eq(backtrace)
+ end
+ end
+
+ context "initialized with nothing" do
+ let(:e) { Chef::Exceptions::RunFailedWrappingError.new }
+ let(:num_errors) { 0 }
+ let(:backtrace) { [] }
+
+ include_examples "RunFailedWrappingError expectations"
+ end
+
+ context "initialized with nil" do
+ let(:e) { Chef::Exceptions::RunFailedWrappingError.new(nil, nil) }
+ let(:num_errors) { 0 }
+ let(:backtrace) { [] }
+
+ include_examples "RunFailedWrappingError expectations"
+ end
+
+ context "initialized with 1 error and nil" do
+ let(:e) { Chef::Exceptions::RunFailedWrappingError.new(RuntimeError.new("foo"), nil) }
+ let(:num_errors) { 1 }
+ let(:backtrace) { ["1) RuntimeError - foo", ""] }
+
+ include_examples "RunFailedWrappingError expectations"
+ end
+
+ context "initialized with 2 errors" do
+ let(:e) { Chef::Exceptions::RunFailedWrappingError.new(RuntimeError.new("foo"), RuntimeError.new("bar")) }
+ let(:num_errors) { 2 }
+ let(:backtrace) { ["1) RuntimeError - foo", "", "2) RuntimeError - bar", ""] }
+
+ include_examples "RunFailedWrappingError expectations"
+ end
+
+ end
end
diff --git a/spec/unit/file_access_control_spec.rb b/spec/unit/file_access_control_spec.rb
index 4e257c2a22..2c68792c63 100644
--- a/spec/unit/file_access_control_spec.rb
+++ b/spec/unit/file_access_control_spec.rb
@@ -42,48 +42,54 @@ describe Chef::FileAccessControl do
end
end
+ describe 'class methods' do
+ it 'responds to #writable?' do
+ expect(Chef::FileAccessControl).to respond_to(:writable?)
+ end
+ end
+
it "has a resource" do
- @fac.resource.should equal(@resource)
+ expect(@fac.resource).to equal(@resource)
end
it "has a file to manage" do
- @fac.file.should == '/tmp/different_file.txt'
+ expect(@fac.file).to eq('/tmp/different_file.txt')
end
it "is not modified yet" do
- @fac.should_not be_modified
+ expect(@fac).not_to be_modified
end
it "determines the uid of the owner specified by the resource" do
- Etc.should_receive(:getpwnam).with('toor').and_return(OpenStruct.new(:uid => 2342))
- @fac.target_uid.should == 2342
+ expect(Etc).to receive(:getpwnam).with('toor').and_return(OpenStruct.new(:uid => 2342))
+ expect(@fac.target_uid).to eq(2342)
end
it "raises a Chef::Exceptions::UserIDNotFound error when Etc can't find the user's name" do
- Etc.should_receive(:getpwnam).with('toor').and_raise(ArgumentError)
- lambda { @fac.target_uid ; @provider_requirements.run(:create) }.should raise_error(Chef::Exceptions::UserIDNotFound, "cannot determine user id for 'toor', does the user exist on this system?")
+ 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?")
end
it "does not attempt to resolve the uid if the user is not specified" do
resource = Chef::Resource::File.new("a file")
fac = Chef::FileAccessControl.new(@current_resource, resource, @provider)
- fac.target_uid.should be_nil
+ expect(fac.target_uid).to be_nil
end
it "does not want to update the owner if none is specified" do
resource = Chef::Resource::File.new("a file")
fac = Chef::FileAccessControl.new(@current_resource, resource, @provider)
- fac.should_update_owner?.should be_false
+ expect(fac.should_update_owner?).to be_falsey
end
it "raises an ArgumentError if the resource's owner is set to something wack" do
@resource.instance_variable_set(:@owner, :diaf)
- lambda { @fac.target_uid ; @provider_requirements.run(:create) }.should 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
@resource.owner(2342)
- @fac.target_uid.should == 2342
+ expect(@fac.target_uid).to eq(2342)
end
it "wraps uids to their negative complements to correctly handle negative uids" do
@@ -93,28 +99,28 @@ describe Chef::FileAccessControl do
# uids. So we have to get ruby and negative uids to smoke the peace pipe
# with each other.
@resource.owner('nobody')
- Etc.should_receive(:getpwnam).with('nobody').and_return(OpenStruct.new(:uid => (4294967294)))
- @fac.target_uid.should == -2
+ expect(Etc).to receive(:getpwnam).with('nobody').and_return(OpenStruct.new(:uid => (4294967294)))
+ expect(@fac.target_uid).to eq(-2)
end
it "does not wrap uids to their negative complements beyond -9" do
# More: when OSX userIDs are created by ActiveDirectory sync, it tends to use huge numbers
# which had been incorrectly wrapped. It does not look like the OSX IDs go below -2
@resource.owner('bigdude')
- Etc.should_receive(:getpwnam).with('bigdude').and_return(OpenStruct.new(:uid => (4294967286)))
- @fac.target_uid.should == 4294967286
+ expect(Etc).to receive(:getpwnam).with('bigdude').and_return(OpenStruct.new(:uid => (4294967286)))
+ expect(@fac.target_uid).to eq(4294967286)
end
it "wants to update the owner when the current owner is nil (creating a file)" do
@current_resource.owner(nil)
@resource.owner(2342)
- @fac.should_update_owner?.should be_true
+ expect(@fac.should_update_owner?).to be_truthy
end
it "wants to update the owner when the current owner doesn't match desired" do
@current_resource.owner(3224)
@resource.owner(2342)
- @fac.should_update_owner?.should be_true
+ expect(@fac.should_update_owner?).to be_truthy
end
it "includes updating ownership in its list of desired changes" do
@@ -122,72 +128,72 @@ describe Chef::FileAccessControl do
resource.owner(2342)
@current_resource.owner(100)
fac = Chef::FileAccessControl.new(@current_resource, resource, @provider)
- fac.describe_changes.should == ["change owner from '100' to '2342'"]
+ expect(fac.describe_changes).to eq(["change owner from '100' to '2342'"])
end
it "sets the file's owner as specified in the resource when the current owner is incorrect" do
@resource.owner(2342)
- File.should_receive(:chown).with(2342, nil, '/tmp/different_file.txt')
+ expect(File).to receive(:chown).with(2342, nil, '/tmp/different_file.txt')
@fac.set_owner
- @fac.should be_modified
+ expect(@fac).to be_modified
end
it "doesn't set the file's owner if it already matches" do
@resource.owner(2342)
@current_resource.owner(2342)
- File.should_not_receive(:chown)
+ expect(File).not_to receive(:chown)
@fac.set_owner
- @fac.should_not be_modified
+ expect(@fac).not_to be_modified
end
it "doesn't want to update a file's owner when it's already correct" do
@resource.owner(2342)
@current_resource.owner(2342)
- @fac.should_update_owner?.should be_false
+ expect(@fac.should_update_owner?).to be_falsey
end
it "determines the gid of the group specified by the resource" do
- Etc.should_receive(:getgrnam).with('wheel').and_return(OpenStruct.new(:gid => 2342))
- @fac.target_gid.should == 2342
+ expect(Etc).to receive(:getgrnam).with('wheel').and_return(OpenStruct.new(:gid => 2342))
+ expect(@fac.target_gid).to eq(2342)
end
it "uses a user specified gid as the gid" do
@resource.group(2342)
- @fac.target_gid.should == 2342
+ expect(@fac.target_gid).to eq(2342)
end
it "raises a Chef::Exceptions::GroupIDNotFound error when Etc can't find the user's name" do
- Etc.should_receive(:getgrnam).with('wheel').and_raise(ArgumentError)
- lambda { @fac.target_gid; @provider_requirements.run(:create) }.should raise_error(Chef::Exceptions::GroupIDNotFound, "cannot determine group id for 'wheel', does the group exist on this system?")
+ expect(Etc).to receive(:getgrnam).with('wheel').and_raise(ArgumentError)
+ expect { @fac.target_gid; @provider_requirements.run(:create) }.to raise_error(Chef::Exceptions::GroupIDNotFound, "cannot determine group id for 'wheel', does the group exist on this system?")
end
it "does not attempt to resolve a gid when none is supplied" do
resource = Chef::Resource::File.new('crab')
fac = Chef::FileAccessControl.new(@current_resource, resource, @provider)
- fac.target_gid.should be_nil
+ expect(fac.target_gid).to be_nil
end
it "does not want to update the group when no target group is specified" do
resource = Chef::Resource::File.new('crab')
fac = Chef::FileAccessControl.new(@current_resource, resource, @provider)
- fac.should_update_group?.should be_false
+ expect(fac.should_update_group?).to be_falsey
end
it "raises an error when the supplied group name is an alien" do
@resource.instance_variable_set(:@group, :failburger)
- lambda { @fac.target_gid; @provider_requirements.run(:create) }.should raise_error(ArgumentError)
+ expect { @fac.target_gid; @provider_requirements.run(:create) }.to raise_error(ArgumentError)
end
it "wants to update the group when the current group is nil (creating a file)" do
@resource.group(2342)
@current_resource.group(nil)
- @fac.should_update_group?.should be_true
+ expect(@fac.should_update_group?).to be_truthy
end
it "wants to update the group when the current group doesn't match the target group" do
@resource.group(2342)
@current_resource.group(815)
- @fac.should_update_group?.should be_true
+ expect(@fac.should_update_group?).to be_truthy
end
it "includes updating the group in the list of changes" do
@@ -195,22 +201,22 @@ describe Chef::FileAccessControl do
resource.group(2342)
@current_resource.group(815)
fac = Chef::FileAccessControl.new(@current_resource, resource, @provider)
- fac.describe_changes.should == ["change group from '815' to '2342'"]
+ expect(fac.describe_changes).to eq(["change group from '815' to '2342'"])
end
it "sets the file's group as specified in the resource when the group is not correct" do
@resource.group(2342)
@current_resource.group(815)
- File.should_receive(:chown).with(nil, 2342, '/tmp/different_file.txt')
+ expect(File).to receive(:chown).with(nil, 2342, '/tmp/different_file.txt')
@fac.set_group
- @fac.should be_modified
+ expect(@fac).to be_modified
end
it "doesn't want to modify the file's group when the current group is correct" do
@resource.group(2342)
@current_resource.group(2342)
- @fac.should_update_group?.should be_false
+ expect(@fac.should_update_group?).to be_falsey
end
it "doesnt set the file's group if it is already correct" do
@@ -218,43 +224,43 @@ describe Chef::FileAccessControl do
@current_resource.group(2342)
# @fac.stub(:stat).and_return(OpenStruct.new(:gid => 2342))
- File.should_not_receive(:chown)
+ expect(File).not_to receive(:chown)
@fac.set_group
- @fac.should_not be_modified
+ expect(@fac).not_to be_modified
end
it "uses the supplied mode as octal when it's a string" do
@resource.mode('444')
- @fac.target_mode.should == 292 # octal 444 => decimal 292
+ expect(@fac.target_mode).to eq(292) # octal 444 => decimal 292
end
it "uses the supplied mode verbatim when it's an integer" do
@resource.mode(00444)
- @fac.target_mode.should == 292
+ expect(@fac.target_mode).to eq(292)
end
it "does not try to determine the mode when none is given" do
resource = Chef::Resource::File.new('blahblah')
fac = Chef::FileAccessControl.new(@current_resource, resource, @provider)
- fac.target_mode.should be_nil
+ expect(fac.target_mode).to be_nil
end
it "doesn't want to update the mode when no target mode is given" do
resource = Chef::Resource::File.new('blahblah')
fac = Chef::FileAccessControl.new(@current_resource, resource, @provider)
- fac.should_update_mode?.should be_false
+ expect(fac.should_update_mode?).to be_falsey
end
it "wants to update the mode when the current mode is nil (creating a file)" do
@resource.mode("0400")
@current_resource.mode(nil)
- @fac.should_update_mode?.should be_true
+ expect(@fac.should_update_mode?).to be_truthy
end
it "wants to update the mode when the desired mode does not match the current mode" do
@resource.mode("0400")
@current_resource.mode("0644")
- @fac.should_update_mode?.should be_true
+ expect(@fac.should_update_mode?).to be_truthy
end
it "includes changing the mode in the list of desired changes" do
@@ -262,41 +268,41 @@ describe Chef::FileAccessControl do
resource.mode("0750")
@current_resource.mode("0444")
fac = Chef::FileAccessControl.new(@current_resource, resource, @provider)
- fac.describe_changes.should == ["change mode from '0444' to '0750'"]
+ expect(fac.describe_changes).to eq(["change mode from '0444' to '0750'"])
end
it "sets the file's mode as specified in the resource when the current modes are incorrect" do
# stat returns modes like 0100644 (octal) => 33188 (decimal)
#@fac.stub(:stat).and_return(OpenStruct.new(:mode => 33188))
@current_resource.mode("0644")
- File.should_receive(:chmod).with(256, '/tmp/different_file.txt')
+ expect(File).to receive(:chmod).with(256, '/tmp/different_file.txt')
@fac.set_mode
- @fac.should be_modified
+ expect(@fac).to be_modified
end
it "does not want to update the mode when the current mode is correct" do
@current_resource.mode("0400")
- @fac.should_update_mode?.should be_false
+ expect(@fac.should_update_mode?).to be_falsey
end
it "does not set the file's mode when the current modes are correct" do
#@fac.stub(:stat).and_return(OpenStruct.new(:mode => 0100400))
@current_resource.mode("0400")
- File.should_not_receive(:chmod)
+ expect(File).not_to receive(:chmod)
@fac.set_mode
- @fac.should_not be_modified
+ expect(@fac).not_to be_modified
end
it "sets all access controls on a file" do
- @fac.stub(:stat).and_return(OpenStruct.new(:owner => 99, :group => 99, :mode => 0100444))
+ allow(@fac).to receive(:stat).and_return(OpenStruct.new(:owner => 99, :group => 99, :mode => 0100444))
@resource.mode(0400)
@resource.owner(0)
@resource.group(0)
- File.should_receive(:chmod).with(0400, '/tmp/different_file.txt')
- File.should_receive(:chown).with(0, nil, '/tmp/different_file.txt')
- File.should_receive(:chown).with(nil, 0, '/tmp/different_file.txt')
+ expect(File).to receive(:chmod).with(0400, '/tmp/different_file.txt')
+ expect(File).to receive(:chown).with(0, nil, '/tmp/different_file.txt')
+ expect(File).to receive(:chown).with(nil, 0, '/tmp/different_file.txt')
@fac.set_all
- @fac.should be_modified
+ expect(@fac).to be_modified
end
end
end
diff --git a/spec/unit/file_cache_spec.rb b/spec/unit/file_cache_spec.rb
index f57f11dcc2..a24c3d3b97 100644
--- a/spec/unit/file_cache_spec.rb
+++ b/spec/unit/file_cache_spec.rb
@@ -32,11 +32,11 @@ describe Chef::FileCache do
describe "when the relative path to the cache file doesn't exist" do
it "creates intermediate directories as needed" do
Chef::FileCache.store("whiz/bang", "I found a poop")
- File.should exist(File.join(@file_cache_path, 'whiz'))
+ expect(File).to exist(File.join(@file_cache_path, 'whiz'))
end
it "creates the cached file at the correct relative path" do
- File.should_receive(:open).with(File.join(@file_cache_path, 'whiz', 'bang'), "w",416).and_yield(@io)
+ expect(File).to receive(:open).with(File.join(@file_cache_path, 'whiz', 'bang'), "w",416).and_yield(@io)
Chef::FileCache.store("whiz/bang", "borkborkbork")
end
@@ -44,12 +44,12 @@ describe Chef::FileCache do
describe "when storing a file" do
before do
- File.stub(:open).and_yield(@io)
+ allow(File).to receive(:open).and_yield(@io)
end
it "should print the contents to the file" do
Chef::FileCache.store("whiz/bang", "borkborkbork")
- @io.string.should == "borkborkbork"
+ expect(@io.string).to eq("borkborkbork")
end
end
@@ -58,11 +58,11 @@ describe Chef::FileCache do
it "finds and reads the cached file" do
FileUtils.mkdir_p(File.join(@file_cache_path, 'whiz'))
File.open(File.join(@file_cache_path, 'whiz', 'bang'), 'w') { |f| f.print("borkborkbork") }
- Chef::FileCache.load('whiz/bang').should == 'borkborkbork'
+ expect(Chef::FileCache.load('whiz/bang')).to eq('borkborkbork')
end
it "should raise a Chef::Exceptions::FileNotFound if the file doesn't exist" do
- lambda { Chef::FileCache.load('whiz/bang') }.should raise_error(Chef::Exceptions::FileNotFound)
+ expect { Chef::FileCache.load('whiz/bang') }.to raise_error(Chef::Exceptions::FileNotFound)
end
end
@@ -74,7 +74,7 @@ describe Chef::FileCache do
it "unlinks the file" do
Chef::FileCache.delete("whiz/bang")
- File.should_not exist(File.join(@file_cache_path, 'whiz', 'bang'))
+ expect(File).not_to exist(File.join(@file_cache_path, 'whiz', 'bang'))
end
end
@@ -88,11 +88,11 @@ describe Chef::FileCache do
end
it "should return the relative paths" do
- Chef::FileCache.list.sort.should == %w{snappy/patter whiz/bang}
+ expect(Chef::FileCache.list.sort).to eq(%w{snappy/patter whiz/bang})
end
it "searches for cached files by globbing" do
- Chef::FileCache.find('snappy/**/*').should == %w{snappy/patter}
+ expect(Chef::FileCache.find('snappy/**/*')).to eq(%w{snappy/patter})
end
end
@@ -104,11 +104,11 @@ describe Chef::FileCache do
it "has a key if the corresponding cache file exists" do
FileUtils.touch(File.join(@file_cache_path, 'whiz', 'bang'))
- Chef::FileCache.should have_key("whiz/bang")
+ expect(Chef::FileCache).to have_key("whiz/bang")
end
it "doesn't have a key if the corresponding cache file doesn't exist" do
- Chef::FileCache.should_not have_key("whiz/bang")
+ expect(Chef::FileCache).not_to have_key("whiz/bang")
end
end
end
diff --git a/spec/unit/file_content_management/deploy/cp_spec.rb b/spec/unit/file_content_management/deploy/cp_spec.rb
index dacf39295c..5c6583e8a6 100644
--- a/spec/unit/file_content_management/deploy/cp_spec.rb
+++ b/spec/unit/file_content_management/deploy/cp_spec.rb
@@ -26,7 +26,7 @@ describe Chef::FileContentManagement::Deploy::Cp do
describe "creating the file" do
it "touches the file to create it" do
- FileUtils.should_receive(:touch).with(target_file_path)
+ expect(FileUtils).to receive(:touch).with(target_file_path)
content_deployer.create(target_file_path)
end
end
@@ -36,7 +36,7 @@ describe Chef::FileContentManagement::Deploy::Cp do
let(:staging_file_path) { "/tmp/random-dir/staging-file.tmp" }
it "copies the staging file's content" do
- FileUtils.should_receive(:cp).with(staging_file_path, target_file_path)
+ expect(FileUtils).to receive(:cp).with(staging_file_path, target_file_path)
content_deployer.deploy(staging_file_path, target_file_path)
end
diff --git a/spec/unit/file_content_management/deploy/mv_unix_spec.rb b/spec/unit/file_content_management/deploy/mv_unix_spec.rb
index 0e8662b8ec..4511f91180 100644
--- a/spec/unit/file_content_management/deploy/mv_unix_spec.rb
+++ b/spec/unit/file_content_management/deploy/mv_unix_spec.rb
@@ -26,7 +26,7 @@ describe Chef::FileContentManagement::Deploy::MvUnix do
describe "creating the file" do
it "touches the file to create it" do
- FileUtils.should_receive(:touch).with(target_file_path)
+ expect(FileUtils).to receive(:touch).with(target_file_path)
content_deployer.create(target_file_path)
end
end
@@ -44,9 +44,9 @@ describe Chef::FileContentManagement::Deploy::MvUnix do
end
before do
- File.should_receive(:stat).with(target_file_path).and_return(target_file_stat)
- File.should_receive(:chmod).with(target_file_mode, staging_file_path).and_return(1)
- FileUtils.should_receive(:mv).with(staging_file_path, target_file_path)
+ expect(File).to receive(:stat).with(target_file_path).and_return(target_file_stat)
+ expect(File).to receive(:chmod).with(target_file_mode, staging_file_path).and_return(1)
+ expect(FileUtils).to receive(:mv).with(staging_file_path, target_file_path)
end
# This context represents the case where:
@@ -63,8 +63,8 @@ describe Chef::FileContentManagement::Deploy::MvUnix do
let(:target_file_gid) { 1001 }
before do
- File.should_receive(:chown).with(target_file_uid, nil, staging_file_path).and_return(1)
- File.should_receive(:chown).with(nil, target_file_gid, staging_file_path).and_return(1)
+ expect(File).to receive(:chown).with(target_file_uid, nil, staging_file_path).and_return(1)
+ expect(File).to receive(:chown).with(nil, target_file_gid, staging_file_path).and_return(1)
end
it "fixes up permissions and moves the file into place" do
@@ -85,11 +85,11 @@ describe Chef::FileContentManagement::Deploy::MvUnix do
let(:target_file_gid) { 20 }
before do
- File.should_receive(:chown).with(target_file_uid, nil, staging_file_path).and_raise(Errno::EPERM)
- File.should_receive(:chown).with(nil, target_file_gid, staging_file_path).and_raise(Errno::EPERM)
+ expect(File).to receive(:chown).with(target_file_uid, nil, staging_file_path).and_raise(Errno::EPERM)
+ expect(File).to receive(:chown).with(nil, target_file_gid, staging_file_path).and_raise(Errno::EPERM)
- Chef::Log.should_receive(:warn).with(/^Could not set uid/)
- Chef::Log.should_receive(:warn).with(/^Could not set gid/)
+ expect(Chef::Log).to receive(:warn).with(/^Could not set uid/)
+ expect(Chef::Log).to receive(:warn).with(/^Could not set gid/)
end
it "fixes up permissions and moves the file into place" do
diff --git a/spec/unit/file_content_management/deploy/mv_windows_spec.rb b/spec/unit/file_content_management/deploy/mv_windows_spec.rb
index 7c2a2d7e71..c52001cd26 100644
--- a/spec/unit/file_content_management/deploy/mv_windows_spec.rb
+++ b/spec/unit/file_content_management/deploy/mv_windows_spec.rb
@@ -41,7 +41,7 @@ describe Chef::FileContentManagement::Deploy::MvWindows do
describe "creating the file" do
it "touches the file to create it" do
- FileUtils.should_receive(:touch).with(target_file_path)
+ expect(FileUtils).to receive(:touch).with(target_file_path)
content_deployer.create(target_file_path)
end
end
@@ -59,8 +59,8 @@ describe Chef::FileContentManagement::Deploy::MvWindows do
end
before do
- Chef::ReservedNames::Win32::Security::SecurableObject.
- stub(:new).
+ allow(Chef::ReservedNames::Win32::Security::SecurableObject).
+ to receive(:new).
with(target_file_path).
and_return(target_file_security_object, updated_target_security_object)
@@ -68,11 +68,11 @@ describe Chef::FileContentManagement::Deploy::MvWindows do
context "when run without adminstrator privileges" do
before do
- target_file_security_object.should_receive(:security_descriptor).and_raise(Chef::Exceptions::Win32APIError)
+ expect(target_file_security_object).to receive(:security_descriptor).and_raise(Chef::Exceptions::Win32APIError)
end
it "errors out with a WindowsNotAdmin error" do
- lambda { content_deployer.deploy(staging_file_path, target_file_path)}.should raise_error(Chef::Exceptions::WindowsNotAdmin)
+ expect { content_deployer.deploy(staging_file_path, target_file_path)}.to raise_error(Chef::Exceptions::WindowsNotAdmin)
end
end
@@ -94,19 +94,19 @@ describe Chef::FileContentManagement::Deploy::MvWindows do
before do
- target_file_security_object.stub(:security_descriptor).and_return(target_file_security_descriptor)
+ allow(target_file_security_object).to receive(:security_descriptor).and_return(target_file_security_descriptor)
- FileUtils.should_receive(:mv).with(staging_file_path, target_file_path)
+ expect(FileUtils).to receive(:mv).with(staging_file_path, target_file_path)
- updated_target_security_object.should_receive(:group=).with(original_target_file_group)
- updated_target_security_object.should_receive(:owner=).with(original_target_file_owner)
+ expect(updated_target_security_object).to receive(:group=).with(original_target_file_group)
+ expect(updated_target_security_object).to receive(:owner=).with(original_target_file_owner)
end
context "and the target file has no dacl or sacl" do
before do
- target_file_security_descriptor.stub(:dacl_present?).and_return(false)
- target_file_security_descriptor.stub(:sacl_present?).and_return(false)
+ allow(target_file_security_descriptor).to receive(:dacl_present?).and_return(false)
+ allow(target_file_security_descriptor).to receive(:sacl_present?).and_return(false)
end
it "fixes up permissions and moves the file into place" do
@@ -129,26 +129,26 @@ describe Chef::FileContentManagement::Deploy::MvWindows do
let(:custom_sacl) { double("Windows ACL for non-inherited sacl aces") }
before do
- target_file_security_descriptor.stub(:dacl_present?).and_return(true)
- target_file_security_descriptor.stub(:dacl_inherits?).and_return(dacl_inherits?)
+ allow(target_file_security_descriptor).to receive(:dacl_present?).and_return(true)
+ allow(target_file_security_descriptor).to receive(:dacl_inherits?).and_return(dacl_inherits?)
- target_file_security_descriptor.stub(:dacl).and_return(original_target_file_dacl)
- Chef::ReservedNames::Win32::Security::ACL.
- should_receive(:create).
+ allow(target_file_security_descriptor).to receive(:dacl).and_return(original_target_file_dacl)
+ expect(Chef::ReservedNames::Win32::Security::ACL).
+ to receive(:create).
with([not_inherited_dacl_ace]).
and_return(custom_dacl)
- target_file_security_descriptor.stub(:sacl_present?).and_return(true)
- target_file_security_descriptor.stub(:sacl_inherits?).and_return(sacl_inherits?)
+ allow(target_file_security_descriptor).to receive(:sacl_present?).and_return(true)
+ allow(target_file_security_descriptor).to receive(:sacl_inherits?).and_return(sacl_inherits?)
- target_file_security_descriptor.stub(:sacl).and_return(original_target_file_sacl)
- Chef::ReservedNames::Win32::Security::ACL.
- should_receive(:create).
+ allow(target_file_security_descriptor).to receive(:sacl).and_return(original_target_file_sacl)
+ expect(Chef::ReservedNames::Win32::Security::ACL).
+ to receive(:create).
with([not_inherited_sacl_ace]).
and_return(custom_sacl)
- updated_target_security_object.should_receive(:set_dacl).with(custom_dacl, dacl_inherits?)
- updated_target_security_object.should_receive(:set_sacl).with(custom_sacl, sacl_inherits?)
+ expect(updated_target_security_object).to receive(:set_dacl).with(custom_dacl, dacl_inherits?)
+ expect(updated_target_security_object).to receive(:set_sacl).with(custom_sacl, sacl_inherits?)
end
context "and the dacl and sacl don't inherit" do
diff --git a/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb b/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb
index 95911689e4..ac19e91922 100644
--- a/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb
@@ -51,7 +51,7 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
# Error inspector originally used file_cache_path which is incorrect on
# chef-solo. Using cookbook_path should do the right thing for client and
# solo.
- Chef::Config.stub(:cookbook_path).and_return([ "/home/someuser/dev-laptop/cookbooks" ])
+ allow(Chef::Config).to receive(:cookbook_path).and_return([ "/home/someuser/dev-laptop/cookbooks" ])
@trace = [
"/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:14:in `from_file'",
"/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:11:in `from_file'",
@@ -65,15 +65,15 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
"/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:14:in `from_file'",
"/home/someuser/dev-laptop/cookbooks/syntax-err/recipes/default.rb:11:in `from_file'",
]
- @inspector.filtered_bt.should == @expected_filtered_trace
+ expect(@inspector.filtered_bt).to eq(@expected_filtered_trace)
end
end
describe "when explaining an error in the compile phase" do
before do
- Chef::Config.stub(:cookbook_path).and_return([ "/var/chef/cache/cookbooks" ])
+ allow(Chef::Config).to receive(:cookbook_path).and_return([ "/var/chef/cache/cookbooks" ])
recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" }
- IO.should_receive(:readlines).with("/var/chef/cache/cookbooks/syntax-err/recipes/default.rb").and_return(recipe_lines)
+ expect(IO).to receive(:readlines).with("/var/chef/cache/cookbooks/syntax-err/recipes/default.rb").and_return(recipe_lines)
@trace = [
"/var/chef/cache/cookbooks/syntax-err/recipes/default.rb:14:in `from_file'",
"/var/chef/cache/cookbooks/syntax-err/recipes/default.rb:11:in `from_file'",
@@ -86,7 +86,7 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
end
it "finds the line number of the error from the stacktrace" do
- @inspector.culprit_line.should == 14
+ expect(@inspector.culprit_line).to eq(14)
end
it "prints a pretty message" do
@@ -96,9 +96,9 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
describe "when explaining an error on windows" do
before do
- Chef::Config.stub(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ])
+ allow(Chef::Config).to receive(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ])
recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" }
- IO.should_receive(:readlines).at_least(1).times.with(/:\/opscode\/chef\/var\/cache\/cookbooks\/foo\/recipes\/default.rb/).and_return(recipe_lines)
+ expect(IO).to receive(:readlines).at_least(1).times.with(/:\/opscode\/chef\/var\/cache\/cookbooks\/foo\/recipes\/default.rb/).and_return(recipe_lines)
@trace = [
"C:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb:14 in `from_file'",
"C:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:144:in `rescue in block in load_libraries'",
@@ -131,7 +131,7 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
describe "and examining the stack trace for a recipe" do
it "find the culprit recipe name when the drive letter is upper case" do
- @inspector.culprit_file.should == "C:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb"
+ expect(@inspector.culprit_file).to eq("C:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb")
end
it "find the culprit recipe name when the drive letter is lower case" do
@@ -139,12 +139,12 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
@exception.set_backtrace(@trace)
@inspector = described_class.new(@path, @exception)
@inspector.add_explanation(@description)
- @inspector.culprit_file.should == "c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb"
+ expect(@inspector.culprit_file).to eq("c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb")
end
end
it "finds the line number of the error from the stack trace" do
- @inspector.culprit_line.should == 14
+ expect(@inspector.culprit_line).to eq(14)
end
it "prints a pretty message" do
@@ -154,9 +154,9 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
describe "when explaining an error on windows, and the backtrace lowercases the drive letter" do
before do
- Chef::Config.stub(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ])
+ allow(Chef::Config).to receive(:cookbook_path).and_return([ "C:/opscode/chef/var/cache/cookbooks" ])
recipe_lines = BAD_RECIPE.split("\n").map {|l| l << "\n" }
- IO.should_receive(:readlines).with("c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb").and_return(recipe_lines)
+ expect(IO).to receive(:readlines).with("c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb").and_return(recipe_lines)
@trace = [
"c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb:14 in `from_file'",
"c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.14.0/lib/chef/run_context.rb:144:in `rescue in block in load_libraries'",
@@ -187,11 +187,11 @@ describe Chef::Formatters::ErrorInspectors::CompileErrorInspector do
end
it "finds the culprit recipe name from the stacktrace" do
- @inspector.culprit_file.should == "c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb"
+ expect(@inspector.culprit_file).to eq("c:/opscode/chef/var/cache/cookbooks/foo/recipes/default.rb")
end
it "finds the line number of the error from the stack trace" do
- @inspector.culprit_line.should == 14
+ expect(@inspector.culprit_line).to eq(14)
end
it "prints a pretty message" do
diff --git a/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb b/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb
index 06d45472e4..7e4d89f144 100644
--- a/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb
@@ -34,7 +34,7 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
@response_body = %Q({"error": [{"message": "gtfo"}])
@response = Net::HTTPForbidden.new("1.1", "403", "(response) forbidden")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) forbidden", @response)
@inspector = Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector.new(@expanded_run_list, @exception)
@@ -42,7 +42,7 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
end
it "prints a nice message" do
- lambda { @description.display(@outputter) }.should_not raise_error
+ expect { @description.display(@outputter) }.not_to raise_error
end
end
@@ -55,7 +55,7 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
@response_body = "{\"error\":[\"{\\\"non_existent_cookbooks\\\":[\\\"apache2\\\"],\\\"cookbooks_with_no_versions\\\":[\\\"users\\\"],\\\"message\\\":\\\"Run list contains invalid items: no such cookbook nope.\\\"}\"]}"
@response = Net::HTTPPreconditionFailed.new("1.1", "412", "(response) unauthorized")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) precondition failed", @response)
@inspector = Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector.new(@expanded_run_list, @exception)
@@ -66,9 +66,9 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
@description.display(@outputter)
@outputter_output.rewind
observed_output = @outputter_output.read
- observed_output.should include("apache2")
- observed_output.should include("users")
- observed_output.should_not include("Run list contains invalid items: no such cookbook nope.")
+ expect(observed_output).to include("apache2")
+ expect(observed_output).to include("users")
+ expect(observed_output).not_to include("Run list contains invalid items: no such cookbook nope.")
end
end
@@ -83,7 +83,7 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
@response_body = "{\"error\":[{\"non_existent_cookbooks\":[],\"cookbooks_with_no_versions\":[],\"message\":\"unable to solve dependencies in alotted time.\"}]}"
@response = Net::HTTPPreconditionFailed.new("1.1", "412", "(response) unauthorized")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) precondition failed", @response)
@inspector = Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector.new(@expanded_run_list, @exception)
@@ -93,7 +93,7 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
it "prints a pretty message" do
@description.display(@outputter)
@outputter_output.rewind
- @outputter_output.read.should include("unable to solve dependencies in alotted time.")
+ expect(@outputter_output.read).to include("unable to solve dependencies in alotted time.")
end
end
@@ -106,7 +106,7 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
@response_body = "{\"error\":[{\"non_existent_cookbooks\":[\"apache2\"],\"cookbooks_with_no_versions\":[\"users\"],\"message\":\"Run list contains invalid items: no such cookbook nope.\"}]}"
@response = Net::HTTPPreconditionFailed.new("1.1", "412", "(response) unauthorized")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) precondition failed", @response)
@inspector = Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector.new(@expanded_run_list, @exception)
@@ -117,9 +117,9 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
@description.display(@outputter)
@outputter_output.rewind
observed_output = @outputter_output.read
- observed_output.should include("apache2")
- observed_output.should include("users")
- observed_output.should_not include("Run list contains invalid items: no such cookbook nope.")
+ expect(observed_output).to include("apache2")
+ expect(observed_output).to include("users")
+ expect(observed_output).not_to include("Run list contains invalid items: no such cookbook nope.")
end
end
diff --git a/spec/unit/formatters/error_inspectors/cookbook_sync_error_inspector_spec.rb b/spec/unit/formatters/error_inspectors/cookbook_sync_error_inspector_spec.rb
index 87c3708ef1..775a1838f3 100644
--- a/spec/unit/formatters/error_inspectors/cookbook_sync_error_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/cookbook_sync_error_inspector_spec.rb
@@ -29,7 +29,7 @@ describe Chef::Formatters::ErrorInspectors::CookbookSyncErrorInspector do
before do
@response_body = "sad trombone orchestra"
@response = Net::HTTPBadGateway.new("1.1", "502", "(response) bad gateway")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPFatalError.new("(exception) bad gateway", @response)
@inspector = described_class.new({}, @exception)
@inspector.add_explanation(@description)
diff --git a/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb b/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb
index 6691553ddd..a42d234601 100644
--- a/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb
@@ -42,7 +42,7 @@ describe Chef::Formatters::ErrorInspectors::ResourceFailureInspector do
@outputter = Chef::Formatters::IndentableOutputStream.new(@stdout, STDERR)
#@outputter = Chef::Formatters::IndentableOutputStream.new(STDOUT, STDERR)
- Chef::Config.stub(:cookbook_path).and_return([ "/var/chef/cache" ])
+ allow(Chef::Config).to receive(:cookbook_path).and_return([ "/var/chef/cache" ])
end
describe "when explaining an error converging a resource" do
@@ -74,7 +74,7 @@ describe Chef::Formatters::ErrorInspectors::ResourceFailureInspector do
"/var/chef/cache/cookbooks/syntax-err/recipes/default.rb:11:in `from_file'",
]
- @inspector.filtered_bt.should == @expected_filtered_trace
+ expect(@inspector.filtered_bt).to eq(@expected_filtered_trace)
end
it "prints a pretty message" do
@@ -105,7 +105,7 @@ describe Chef::Formatters::ErrorInspectors::ResourceFailureInspector do
it "includes contextual info from the template error in the output" do
@description.display(@outputter)
- @stdout.string.should include(@error.source_listing)
+ expect(@stdout.string).to include(@error.source_listing)
end
@@ -114,41 +114,41 @@ describe Chef::Formatters::ErrorInspectors::ResourceFailureInspector do
describe "recipe_snippet" do
before do
# fake code to run through #recipe_snippet
- source_file = [ "if true", "var = non_existant", "end" ]
- IO.stub(:readlines).and_return(source_file)
- File.stub(:exists?).and_return(true)
+ source_file = [ "if true", "var = non_existent", "end" ]
+ allow(IO).to receive(:readlines).and_return(source_file)
+ allow(File).to receive(:exists?).and_return(true)
end
it "parses a Windows path" do
- source_line = "C:/Users/btm/chef/chef/spec/unit/fake_file.rb:2: undefined local variable or method `non_existant' for main:Object (NameError)"
+ source_line = "C:/Users/btm/chef/chef/spec/unit/fake_file.rb:2: undefined local variable or method `non_existent' for main:Object (NameError)"
@resource.source_line = source_line
@inspector = Chef::Formatters::ErrorInspectors::ResourceFailureInspector.new(@resource, :create, @exception)
- @inspector.recipe_snippet.should match(/^# In C:\/Users\/btm/)
+ expect(@inspector.recipe_snippet).to match(/^# In C:\/Users\/btm/)
end
it "parses a unix path" do
- source_line = "/home/btm/src/chef/chef/spec/unit/fake_file.rb:2: undefined local variable or method `non_existant' for main:Object (NameError)"
+ source_line = "/home/btm/src/chef/chef/spec/unit/fake_file.rb:2: undefined local variable or method `non_existent' for main:Object (NameError)"
@resource.source_line = source_line
@inspector = Chef::Formatters::ErrorInspectors::ResourceFailureInspector.new(@resource, :create, @exception)
- @inspector.recipe_snippet.should match(/^# In \/home\/btm/)
+ expect(@inspector.recipe_snippet).to match(/^# In \/home\/btm/)
end
context "when the recipe file does not exist" do
before do
- File.stub(:exists?).and_return(false)
- IO.stub(:readlines).and_raise(Errno::ENOENT)
+ allow(File).to receive(:exists?).and_return(false)
+ allow(IO).to receive(:readlines).and_raise(Errno::ENOENT)
end
it "does not try to parse a recipe in chef-shell/irb (CHEF-3411)" do
@resource.source_line = "(irb#1):1:in `irb_binding'"
@inspector = Chef::Formatters::ErrorInspectors::ResourceFailureInspector.new(@resource, :create, @exception)
- @inspector.recipe_snippet.should be_nil
+ expect(@inspector.recipe_snippet).to be_nil
end
- it "does not raise an exception trying to load a non-existant file (CHEF-3411)" do
+ it "does not raise an exception trying to load a non-existent file (CHEF-3411)" do
@resource.source_line = "/somewhere/in/space"
@inspector = Chef::Formatters::ErrorInspectors::ResourceFailureInspector.new(@resource, :create, @exception)
- lambda { @inspector.recipe_snippet }.should_not raise_error
+ expect { @inspector.recipe_snippet }.not_to raise_error
end
end
end
@@ -175,7 +175,7 @@ describe Chef::Formatters::ErrorInspectors::ResourceFailureInspector do
end
it "does not generate an error" do
- lambda { @inspector.add_explanation(@description) }.should_not raise_error
+ expect { @inspector.add_explanation(@description) }.not_to raise_error
@description.display(@outputter)
end
end
diff --git a/spec/unit/formatters/error_inspectors/run_list_expansion_error_inspector_spec.rb b/spec/unit/formatters/error_inspectors/run_list_expansion_error_inspector_spec.rb
index 7f68c4fba4..1cd97596a7 100644
--- a/spec/unit/formatters/error_inspectors/run_list_expansion_error_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/run_list_expansion_error_inspector_spec.rb
@@ -55,10 +55,10 @@ describe Chef::Formatters::ErrorInspectors::RunListExpansionErrorInspector do
@response_body = "forbidden"
@response = Net::HTTPForbidden.new("1.1", "403", "(response) forbidden")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) forbidden", @response)
@inspector = Chef::Formatters::ErrorInspectors::RunListExpansionErrorInspector.new(@node, @exception)
- @inspector.stub(:config).and_return(:node_name => "unit-test.example.com")
+ allow(@inspector).to receive(:config).and_return(:node_name => "unit-test.example.com")
@inspector.add_explanation(@description)
end
@@ -73,11 +73,11 @@ describe Chef::Formatters::ErrorInspectors::RunListExpansionErrorInspector do
before do
@response_body = "check your key and node name"
@response = Net::HTTPUnauthorized.new("1.1", "401", "(response) unauthorized")
- @response.stub(:body).and_return(@response_body)
+ allow(@response).to receive(:body).and_return(@response_body)
@exception = Net::HTTPServerException.new("(exception) unauthorized", @response)
@inspector = Chef::Formatters::ErrorInspectors::RunListExpansionErrorInspector.new(@node, @exception)
- @inspector.stub(:config).and_return(:node_name => "unit-test.example.com",
+ allow(@inspector).to receive(:config).and_return(:node_name => "unit-test.example.com",
:client_key => "/etc/chef/client.pem",
:chef_server_url => "http://chef.example.com")
diff --git a/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb b/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb
index a122ac5515..4cf3ba827a 100644
--- a/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb
+++ b/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb
@@ -29,28 +29,118 @@ describe Chef::GuardInterpreter::ResourceGuardInterpreter do
let(:run_context) { Chef::RunContext.new(node, nil, nil) }
- let(:resource) do
- resource = Chef::Resource.new("powershell_unit_test", run_context)
- resource.stub(:run_action)
- resource.stub(:updated).and_return(true)
- resource
+ let(:parent_resource) do
+ parent_resource = Chef::Resource.new("powershell_unit_test", run_context)
+ allow(parent_resource).to receive(:run_action)
+ allow(parent_resource).to receive(:updated).and_return(true)
+ parent_resource
end
+ let(:guard_interpreter) { Chef::GuardInterpreter::ResourceGuardInterpreter.new(parent_resource, "echo hi", nil) }
describe "get_interpreter_resource" do
it "allows the guard interpreter to be set to Chef::Resource::Script" do
- resource.guard_interpreter(:script)
- expect { Chef::GuardInterpreter::ResourceGuardInterpreter.new(resource, "echo hi", nil) }.not_to raise_error
+ parent_resource.guard_interpreter(:script)
+ expect { guard_interpreter }.not_to raise_error
end
-
+
it "allows the guard interpreter to be set to Chef::Resource::PowershellScript derived indirectly from Chef::Resource::Script" do
- resource.guard_interpreter(:powershell_script)
- expect { Chef::GuardInterpreter::ResourceGuardInterpreter.new(resource, "echo hi", nil) }.not_to raise_error
+ parent_resource.guard_interpreter(:powershell_script)
+ expect { guard_interpreter }.not_to raise_error
end
-
+
it "raises an exception if guard_interpreter is set to a resource not derived from Chef::Resource::Script" do
- resource.guard_interpreter(:file)
- expect { Chef::GuardInterpreter::ResourceGuardInterpreter.new(resource, "echo hi", nil) }.to raise_error(ArgumentError)
+ parent_resource.guard_interpreter(:file)
+ expect { guard_interpreter }.to raise_error(ArgumentError, 'Specified guard interpreter class Chef::Resource::File must be a kind of Chef::Resource::Execute resource')
+ end
+
+ context "when the resource cannot be found for the platform" do
+ before do
+ expect(Chef::Resource).to receive(:resource_for_node).with(:foobar, node).and_return(nil)
+ end
+
+ it "raises an exception" do
+ parent_resource.guard_interpreter(:foobar)
+ expect { guard_interpreter }.to raise_error(ArgumentError, 'Specified guard_interpreter resource foobar unknown for this platform')
+ end
+ end
+
+ it "fails when parent_resource is nil" do
+ expect { Chef::GuardInterpreter::ResourceGuardInterpreter.new(nil, "echo hi", nil) }.to raise_error(ArgumentError, /Node for guard resource parent must not be nil/)
+ end
+
+ end
+
+ describe "#evaluate" do
+ let(:guard_interpreter) { Chef::GuardInterpreter::ResourceGuardInterpreter.new(parent_resource, "echo hi", {}) }
+ let(:parent_resource) do
+ parent_resource = Chef::Resource.new("execute resource", run_context)
+ parent_resource.guard_interpreter(:execute)
+ parent_resource
+ end
+
+ it "successfully evaluates the resource" do
+ expect(guard_interpreter.evaluate).to eq(true)
+ end
+
+ describe "script command opts switch" do
+ let(:command_opts) { {} }
+ let(:guard_interpreter) { Chef::GuardInterpreter::ResourceGuardInterpreter.new(parent_resource, "exit 0", command_opts) }
+
+ context "resource is a Script" do
+ context "and guard_interpreter is a :script" do
+ let(:parent_resource) do
+ parent_resource = Chef::Resource::Script.new("resource", run_context)
+ # Ruby scripts are cross platform to both Linux and Windows
+ parent_resource.guard_interpreter(:ruby)
+ parent_resource
+ end
+
+ let(:shell_out) {
+ instance_double(Mixlib::ShellOut, :live_stream => true, :run_command => true, :error! => nil)
+ }
+
+ before do
+ # TODO for some reason Windows is failing on executing a ruby script
+ expect(Mixlib::ShellOut).to receive(:new) do |*args|
+ expect(args[0]).to match(/^"ruby"/)
+ shell_out
+ end
+ end
+
+ it "merges to :code" do
+ expect(command_opts).to receive(:merge).with({:code => "exit 0"}).and_call_original
+ expect(guard_interpreter.evaluate).to eq(true)
+ end
+ end
+
+ context "and guard_interpreter is :execute" do
+ let(:parent_resource) do
+ parent_resource = Chef::Resource::Script.new("resource", run_context)
+ parent_resource.guard_interpreter(:execute)
+ parent_resource
+ end
+
+ it "merges to :code" do
+ expect(command_opts).to receive(:merge).with({:command => "exit 0"}).and_call_original
+ expect(guard_interpreter.evaluate).to eq(true)
+ end
+ end
+ end
+
+ context "resource is not a Script" do
+ let(:parent_resource) do
+ parent_resource = Chef::Resource::Execute.new("resource", run_context)
+ parent_resource.guard_interpreter(:execute)
+ parent_resource
+ end
+
+ it "merges to :command" do
+ expect(command_opts).to receive(:merge).with({:command => "exit 0"}).and_call_original
+ expect(guard_interpreter.evaluate).to eq(true)
+ end
+ end
+
end
end
end
diff --git a/spec/unit/guard_interpreter_spec.rb b/spec/unit/guard_interpreter_spec.rb
new file mode 100644
index 0000000000..a7fe064948
--- /dev/null
+++ b/spec/unit/guard_interpreter_spec.rb
@@ -0,0 +1,41 @@
+#
+# Author:: Steven Danna (steve@chef.io)
+# Copyright:: Copyright (c) 2015 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 'spec_helper'
+
+describe Chef::GuardInterpreter do
+ describe "#for_resource" do
+ let (:resource) { Chef::Resource.new("foo")}
+
+ it "returns a DefaultGuardInterpreter if the resource has guard_interpreter set to :default" do
+ resource.guard_interpreter :default
+ interpreter = Chef::GuardInterpreter.for_resource(resource, "", {})
+ expect(interpreter.class).to eq(Chef::GuardInterpreter::DefaultGuardInterpreter)
+ end
+
+ it "returns a ResourceGuardInterpreter if the resource has guard_interpreter set to !:default" do
+ resource.guard_interpreter :foobar
+ # Mock the resource guard interpreter to avoid having to set up a lot of state
+ # currently we are only testing that we get the correct class of object back
+ rgi = double("Chef::GuardInterpreter::ResourceGuardInterpreter")
+ allow(Chef::GuardInterpreter::ResourceGuardInterpreter).to receive(:new).and_return(rgi)
+ interpreter = Chef::GuardInterpreter.for_resource(resource, "", {})
+ expect(interpreter).to eq(rgi)
+ end
+ end
+end
diff --git a/spec/unit/handler/json_file_spec.rb b/spec/unit/handler/json_file_spec.rb
index 05270e4731..f6c14a166e 100644
--- a/spec/unit/handler/json_file_spec.rb
+++ b/spec/unit/handler/json_file_spec.rb
@@ -24,12 +24,12 @@ describe Chef::Handler::JsonFile do
end
it "accepts arbitrary config options" do
- @handler.config[:the_sun].should == "will rise"
+ expect(@handler.config[:the_sun]).to eq("will rise")
end
it "creates the directory where the reports will be saved" do
- FileUtils.should_receive(:mkdir_p).with('/tmp/foobarbazqux')
- File.should_receive(:chmod).with(00700, '/tmp/foobarbazqux')
+ expect(FileUtils).to receive(:mkdir_p).with('/tmp/foobarbazqux')
+ expect(File).to receive(:chmod).with(00700, '/tmp/foobarbazqux')
@handler.build_report_dir
end
@@ -39,25 +39,25 @@ describe Chef::Handler::JsonFile do
@events = Chef::EventDispatch::Dispatcher.new
@run_status = Chef::RunStatus.new(@node, @events)
@expected_time = Time.now
- Time.stub(:now).and_return(@expected_time, @expected_time + 5)
+ allow(Time).to receive(:now).and_return(@expected_time, @expected_time + 5)
@run_status.start_clock
@run_status.stop_clock
@run_context = Chef::RunContext.new(@node, {}, @events)
@run_status.run_context = @run_context
@run_status.exception = Exception.new("Boy howdy!")
@file_mock = StringIO.new
- File.stub(:open).and_yield(@file_mock)
+ allow(File).to receive(:open).and_yield(@file_mock)
end
it "saves run status data to a file as JSON" do
- @handler.should_receive(:build_report_dir)
+ expect(@handler).to receive(:build_report_dir)
@handler.run_report_unsafe(@run_status)
reported_data = Chef::JSONCompat.from_json(@file_mock.string)
- reported_data['exception'].should == "Exception: Boy howdy!"
- reported_data['start_time'].should == @expected_time.to_s
- reported_data['end_time'].should == (@expected_time + 5).to_s
- reported_data['elapsed_time'].should == 5
+ expect(reported_data['exception']).to eq("Exception: Boy howdy!")
+ expect(reported_data['start_time']).to eq(@expected_time.to_s)
+ expect(reported_data['end_time']).to eq((@expected_time + 5).to_s)
+ expect(reported_data['elapsed_time']).to eq(5)
end
end
diff --git a/spec/unit/handler_spec.rb b/spec/unit/handler_spec.rb
index 3a7e046dd5..e7f67405fc 100644
--- a/spec/unit/handler_spec.rb
+++ b/spec/unit/handler_spec.rb
@@ -42,54 +42,54 @@ describe Chef::Handler do
@run_status.run_context = @run_context
@start_time = Time.now
@end_time = @start_time + 4.2
- Time.stub(:now).and_return(@start_time, @end_time)
+ allow(Time).to receive(:now).and_return(@start_time, @end_time)
@run_status.start_clock
@run_status.stop_clock
end
it "has a shortcut for the exception" do
- @handler.exception.should == @exception
+ expect(@handler.exception).to eq(@exception)
end
it "has a shortcut for the backtrace" do
- @handler.backtrace.should == @backtrace
+ expect(@handler.backtrace).to eq(@backtrace)
end
it "has a shortcut for all resources" do
- @handler.all_resources.should == @all_resources
+ expect(@handler.all_resources).to eq(@all_resources)
end
it "has a shortcut for just the updated resources" do
- @handler.updated_resources.should == [@all_resources.first]
+ expect(@handler.updated_resources).to eq([@all_resources.first])
end
it "has a shortcut for the start time" do
- @handler.start_time.should == @start_time
+ expect(@handler.start_time).to eq(@start_time)
end
it "has a shortcut for the end time" do
- @handler.end_time.should == @end_time
+ expect(@handler.end_time).to eq(@end_time)
end
it "has a shortcut for the elapsed time" do
- @handler.elapsed_time.should == 4.2
+ expect(@handler.elapsed_time).to eq(4.2)
end
it "has a shortcut for the node" do
- @handler.node.should == @node
+ expect(@handler.node).to eq(@node)
end
it "has a shortcut for the run context" do
- @handler.run_context.should == @run_context
+ expect(@handler.run_context).to eq(@run_context)
end
it "has a shortcut for the success? and failed? predicates" do
- @handler.success?.should be_false # becuase there's an exception
- @handler.failed?.should be_true
+ expect(@handler.success?).to be_falsey # because there's an exception
+ expect(@handler.failed?).to be_truthy
end
it "has a shortcut to the hash representation of the run status" do
- @handler.data.should == @run_status.to_hash
+ expect(@handler.data).to eq(@run_status.to_hash)
end
end
@@ -100,16 +100,16 @@ describe Chef::Handler do
$report_ran = true
raise Exception, "I died the deth"
end
- lambda {@handler.run_report_safely(@run_status)}.should_not raise_error
- $report_ran.should be_true
+ expect {@handler.run_report_safely(@run_status)}.not_to raise_error
+ expect($report_ran).to be_truthy
end
it "does not fail if the report handler does not raise an exception" do
$report_ran = false
def @handler.report
$report_ran = true
end
- lambda {@handler.run_report_safely(@run_status)}.should_not raise_error
- $report_ran.should be_true
+ expect {@handler.run_report_safely(@run_status)}.not_to raise_error
+ expect($report_ran).to be_truthy
end
end
@@ -123,46 +123,46 @@ describe Chef::Handler do
@run_status.run_context = @run_context
@start_time = Time.now
@end_time = @start_time + 4.2
- Time.stub(:now).and_return(@start_time, @end_time)
+ allow(Time).to receive(:now).and_return(@start_time, @end_time)
@run_status.start_clock
@run_status.stop_clock
end
it "has a shortcut for all resources" do
- @handler.all_resources.should == @all_resources
+ expect(@handler.all_resources).to eq(@all_resources)
end
it "has a shortcut for just the updated resources" do
- @handler.updated_resources.should == [@all_resources.first]
+ expect(@handler.updated_resources).to eq([@all_resources.first])
end
it "has a shortcut for the start time" do
- @handler.start_time.should == @start_time
+ expect(@handler.start_time).to eq(@start_time)
end
it "has a shortcut for the end time" do
- @handler.end_time.should == @end_time
+ expect(@handler.end_time).to eq(@end_time)
end
it "has a shortcut for the elapsed time" do
- @handler.elapsed_time.should == 4.2
+ expect(@handler.elapsed_time).to eq(4.2)
end
it "has a shortcut for the node" do
- @handler.node.should == @node
+ expect(@handler.node).to eq(@node)
end
it "has a shortcut for the run context" do
- @handler.run_context.should == @run_context
+ expect(@handler.run_context).to eq(@run_context)
end
it "has a shortcut for the success? and failed? predicates" do
- @handler.success?.should be_true
- @handler.failed?.should be_false
+ expect(@handler.success?).to be_truthy
+ expect(@handler.failed?).to be_falsey
end
it "has a shortcut to the hash representation of the run status" do
- @handler.data.should == @run_status.to_hash
+ expect(@handler.data).to eq(@run_status.to_hash)
end
end
@@ -170,45 +170,45 @@ describe Chef::Handler do
describe "when running a start handler" do
before do
@start_time = Time.now
- Time.stub(:now).and_return(@start_time)
+ allow(Time).to receive(:now).and_return(@start_time)
@run_status.start_clock
end
it "should not have all resources" do
- @handler.all_resources.should be_false
+ expect(@handler.all_resources).to be_falsey
end
it "should not have updated resources" do
- @handler.updated_resources.should be_false
+ expect(@handler.updated_resources).to be_falsey
end
it "has a shortcut for the start time" do
- @handler.start_time.should == @start_time
+ expect(@handler.start_time).to eq(@start_time)
end
it "does not have a shortcut for the end time" do
- @handler.end_time.should be_false
+ expect(@handler.end_time).to be_falsey
end
it "does not have a shortcut for the elapsed time" do
- @handler.elapsed_time.should be_false
+ expect(@handler.elapsed_time).to be_falsey
end
it "has a shortcut for the node" do
- @handler.node.should == @node
+ expect(@handler.node).to eq(@node)
end
it "does not have a shortcut for the run context" do
- @handler.run_context.should be_false
+ expect(@handler.run_context).to be_falsey
end
it "has a shortcut for the success? and failed? predicates" do
- @handler.success?.should be_true # for some reason this is true
- @handler.failed?.should be_false
+ expect(@handler.success?).to be_truthy # for some reason this is true
+ expect(@handler.failed?).to be_falsey
end
it "has a shortcut to the hash representation of the run status" do
- @handler.data.should == @run_status.to_hash
+ expect(@handler.data).to eq(@run_status.to_hash)
end
end
diff --git a/spec/unit/http/basic_client_spec.rb b/spec/unit/http/basic_client_spec.rb
index cb1f2fd979..eb133f943e 100644
--- a/spec/unit/http/basic_client_spec.rb
+++ b/spec/unit/http/basic_client_spec.rb
@@ -35,7 +35,7 @@ describe "HTTP Connection" do
end
it "should set an open timeout" do
- subject.build_http_client.open_timeout.should_not be_nil
+ expect(subject.build_http_client.open_timeout).not_to be_nil
end
end
@@ -52,12 +52,12 @@ describe "HTTP Connection" do
it "should contain the host" do
proxy_uri = subject.proxy_uri
- proxy_uri.host.should == proxy_host
+ expect(proxy_uri.host).to eq(proxy_host)
end
it "should contain the port" do
proxy_uri = subject.proxy_uri
- proxy_uri.port.should == proxy_port
+ expect(proxy_uri.port).to eq(proxy_port)
end
end
diff --git a/spec/unit/http/http_request_spec.rb b/spec/unit/http/http_request_spec.rb
index d573d4c5dc..3bba201963 100644
--- a/spec/unit/http/http_request_spec.rb
+++ b/spec/unit/http/http_request_spec.rb
@@ -25,31 +25,31 @@ describe Chef::HTTP::HTTPRequest do
it "should not include port 80 in Host header" do
request = Chef::HTTP::HTTPRequest.new(:GET, URI('http://dummy.com'), '')
- request.headers['Host'].should eql('dummy.com')
+ expect(request.headers['Host']).to eql('dummy.com')
end
it "should not include explicit port 80 in Host header" do
request = Chef::HTTP::HTTPRequest.new(:GET, URI('http://dummy.com:80'), '')
- request.headers['Host'].should eql('dummy.com')
+ expect(request.headers['Host']).to eql('dummy.com')
end
it "should include explicit port 8000 in Host header" do
request = Chef::HTTP::HTTPRequest.new(:GET, URI('http://dummy.com:8000'), '')
- request.headers['Host'].should eql('dummy.com:8000')
+ expect(request.headers['Host']).to eql('dummy.com:8000')
end
it "should include explicit 443 port in Host header" do
request = Chef::HTTP::HTTPRequest.new(:GET, URI('http://dummy.com:443'), '')
- request.headers['Host'].should eql('dummy.com:443')
+ expect(request.headers['Host']).to eql('dummy.com:443')
end
it "should pass on explicit Host header unchanged" do
request = Chef::HTTP::HTTPRequest.new(:GET, URI('http://dummy.com:8000'), '', { 'Host' => 'yourhost.com:8888' })
- request.headers['Host'].should eql('yourhost.com:8888')
+ expect(request.headers['Host']).to eql('yourhost.com:8888')
end
end
@@ -59,25 +59,25 @@ describe Chef::HTTP::HTTPRequest do
it "should not include port 443 in Host header" do
request = Chef::HTTP::HTTPRequest.new(:GET, URI('https://dummy.com'), '')
- request.headers['Host'].should eql('dummy.com')
+ expect(request.headers['Host']).to eql('dummy.com')
end
it "should include explicit port 80 in Host header" do
request = Chef::HTTP::HTTPRequest.new(:GET, URI('https://dummy.com:80'), '')
- request.headers['Host'].should eql('dummy.com:80')
+ expect(request.headers['Host']).to eql('dummy.com:80')
end
it "should include explicit port 8000 in Host header" do
request = Chef::HTTP::HTTPRequest.new(:GET, URI('https://dummy.com:8000'), '')
- request.headers['Host'].should eql('dummy.com:8000')
+ expect(request.headers['Host']).to eql('dummy.com:8000')
end
it "should not include explicit port 443 in Host header" do
request = Chef::HTTP::HTTPRequest.new(:GET, URI('https://dummy.com:443'), '')
- request.headers['Host'].should eql('dummy.com')
+ expect(request.headers['Host']).to eql('dummy.com')
end
end
@@ -85,7 +85,7 @@ describe Chef::HTTP::HTTPRequest do
it "should pass on explicit Host header unchanged" do
request = Chef::HTTP::HTTPRequest.new(:GET, URI('http://dummy.com:8000'), '', { 'Host' => 'myhost.com:80' })
- request.headers['Host'].should eql('myhost.com:80')
+ expect(request.headers['Host']).to eql('myhost.com:80')
end
end
diff --git a/spec/unit/http/simple_spec.rb b/spec/unit/http/simple_spec.rb
index b33ef1d553..c8fb52e8b2 100644
--- a/spec/unit/http/simple_spec.rb
+++ b/spec/unit/http/simple_spec.rb
@@ -25,8 +25,8 @@ describe Chef::HTTP::Simple do
content_length = middlewares.find_index { |e| e.is_a? Chef::HTTP::ValidateContentLength }
decompressor = middlewares.find_index { |e| e.is_a? Chef::HTTP::Decompressor }
- content_length.should_not be_nil
- decompressor.should_not be_nil
- (decompressor < content_length).should be_true
+ expect(content_length).not_to be_nil
+ expect(decompressor).not_to be_nil
+ expect(decompressor < content_length).to be_truthy
end
end
diff --git a/spec/unit/http/ssl_policies_spec.rb b/spec/unit/http/ssl_policies_spec.rb
index b95e13a370..5ebebf39b1 100644
--- a/spec/unit/http/ssl_policies_spec.rb
+++ b/spec/unit/http/ssl_policies_spec.rb
@@ -45,31 +45,31 @@ describe "HTTP SSL Policy" do
end
it "configures the HTTP client to use SSL when given a URL with the https protocol" do
- http_client.use_ssl?.should be_true
+ expect(http_client.use_ssl?).to be_truthy
end
it "sets the OpenSSL verify mode to verify_peer" do
- http_client.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
+ expect(http_client.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER)
end
it "raises a ConfigurationError if :ssl_ca_path is set to a path that doesn't exist" do
Chef::Config[:ssl_ca_path] = "/dev/null/nothing_here"
- lambda {http_client}.should raise_error(Chef::Exceptions::ConfigurationError)
+ expect {http_client}.to raise_error(Chef::Exceptions::ConfigurationError)
end
it "should set the CA path if that is set in the configuration" do
Chef::Config[:ssl_ca_path] = File.join(CHEF_SPEC_DATA, "ssl")
- http_client.ca_path.should == File.join(CHEF_SPEC_DATA, "ssl")
+ expect(http_client.ca_path).to eq(File.join(CHEF_SPEC_DATA, "ssl"))
end
it "raises a ConfigurationError if :ssl_ca_file is set to a file that does not exist" do
Chef::Config[:ssl_ca_file] = "/dev/null/nothing_here"
- lambda {http_client}.should raise_error(Chef::Exceptions::ConfigurationError)
+ expect {http_client}.to raise_error(Chef::Exceptions::ConfigurationError)
end
it "should set the CA file if that is set in the configuration" do
Chef::Config[:ssl_ca_file] = CHEF_SPEC_DATA + '/ssl/5e707473.0'
- http_client.ca_file.should == CHEF_SPEC_DATA + '/ssl/5e707473.0'
+ expect(http_client.ca_file).to eq(CHEF_SPEC_DATA + '/ssl/5e707473.0')
end
end
@@ -80,7 +80,7 @@ describe "HTTP SSL Policy" do
end
it "sets the OpenSSL verify mode to :verify_none" do
- http_client.verify_mode.should == OpenSSL::SSL::VERIFY_NONE
+ expect(http_client.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE)
end
end
@@ -90,26 +90,26 @@ describe "HTTP SSL Policy" do
it "raises ConfigurationError if the certificate file doesn't exist" do
Chef::Config[:ssl_client_cert] = "/dev/null/nothing_here"
Chef::Config[:ssl_client_key] = CHEF_SPEC_DATA + '/ssl/chef-rspec.key'
- lambda {http_client}.should raise_error(Chef::Exceptions::ConfigurationError)
+ expect {http_client}.to raise_error(Chef::Exceptions::ConfigurationError)
end
it "raises ConfigurationError if the certificate file doesn't exist" do
Chef::Config[:ssl_client_cert] = CHEF_SPEC_DATA + '/ssl/chef-rspec.cert'
Chef::Config[:ssl_client_key] = "/dev/null/nothing_here"
- lambda {http_client}.should raise_error(Chef::Exceptions::ConfigurationError)
+ expect {http_client}.to raise_error(Chef::Exceptions::ConfigurationError)
end
it "raises a ConfigurationError if one of :ssl_client_cert and :ssl_client_key is set but not both" do
Chef::Config[:ssl_client_cert] = "/dev/null/nothing_here"
Chef::Config[:ssl_client_key] = nil
- lambda {http_client}.should raise_error(Chef::Exceptions::ConfigurationError)
+ expect {http_client}.to raise_error(Chef::Exceptions::ConfigurationError)
end
it "configures the HTTP client's cert and private key" do
Chef::Config[:ssl_client_cert] = CHEF_SPEC_DATA + '/ssl/chef-rspec.cert'
Chef::Config[:ssl_client_key] = CHEF_SPEC_DATA + '/ssl/chef-rspec.key'
- http_client.cert.to_s.should == OpenSSL::X509::Certificate.new(IO.read(CHEF_SPEC_DATA + '/ssl/chef-rspec.cert')).to_s
- http_client.key.to_s.should == IO.read(CHEF_SPEC_DATA + '/ssl/chef-rspec.key')
+ expect(http_client.cert.to_s).to eq(OpenSSL::X509::Certificate.new(IO.read(CHEF_SPEC_DATA + '/ssl/chef-rspec.cert')).to_s)
+ expect(http_client.key.to_s).to eq(IO.read(CHEF_SPEC_DATA + '/ssl/chef-rspec.key'))
end
end
@@ -125,7 +125,7 @@ describe "HTTP SSL Policy" do
end
it "enables verification of self-signed certificates" do
- http_client.cert_store.verify(self_signed_crt).should be_true
+ expect(http_client.cert_store.verify(self_signed_crt)).to be_truthy
end
it "enables verification of cert chains" do
@@ -137,7 +137,7 @@ describe "HTTP SSL Policy" do
# If the machine running the test doesn't have ruby SSL configured correctly,
# then the root cert also has to be loaded for the test to succeed.
# The system under test **SHOULD** do both of these things.
- http_client.cert_store.verify(additional_pem).should be_true
+ expect(http_client.cert_store.verify(additional_pem)).to be_truthy
end
context "and some certs are duplicates" do
@@ -161,7 +161,7 @@ describe "HTTP SSL Policy" do
end
it "sets the OpenSSL verify mode to verify_peer" do
- http_client.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
+ expect(http_client.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER)
end
end
diff --git a/spec/unit/http/validate_content_length_spec.rb b/spec/unit/http/validate_content_length_spec.rb
index 091f2b0757..79bd539af3 100644
--- a/spec/unit/http/validate_content_length_spec.rb
+++ b/spec/unit/http/validate_content_length_spec.rb
@@ -45,7 +45,7 @@ describe Chef::HTTP::ValidateContentLength do
let(:response) {
m = double('HttpResponse', :body => response_body)
- m.stub(:[]) do |key|
+ allow(m).to receive(:[]) do |key|
response_headers[key]
end
@@ -83,19 +83,24 @@ describe Chef::HTTP::ValidateContentLength do
let(:debug_stream) { StringIO.new }
let(:debug_output) { debug_stream.string }
- before(:each) {
+ before(:each) do
+ @original_log_level = Chef::Log.level
Chef::Log.level = :debug
- Chef::Log.stub(:debug) do |message|
+ allow(Chef::Log).to receive(:debug) do |message|
debug_stream.puts message
end
- }
+ end
+
+ after(:each) do
+ Chef::Log.level = @original_log_level
+ end
describe "without response body" do
let(:request_type) { :direct }
let(:response_body) { "Thanks for checking in." }
it "shouldn't raise error" do
- lambda { run_content_length_validation }.should_not raise_error
+ expect { run_content_length_validation }.not_to raise_error
end
end
@@ -108,7 +113,7 @@ describe Chef::HTTP::ValidateContentLength do
it "should skip validation and log for debug" do
run_content_length_validation
- debug_output.should include("HTTP server did not include a Content-Length header in response")
+ expect(debug_output).to include("HTTP server did not include a Content-Length header in response")
end
end
end
@@ -121,7 +126,7 @@ describe Chef::HTTP::ValidateContentLength do
it "should validate correctly" do
run_content_length_validation
- debug_output.should include("Content-Length validated correctly.")
+ expect(debug_output).to include("Content-Length validated correctly.")
end
end
end
@@ -134,7 +139,7 @@ describe Chef::HTTP::ValidateContentLength do
let(:request_type) { req_type.to_sym }
it "should raise ContentLengthMismatch error" do
- lambda { run_content_length_validation }.should raise_error(Chef::Exceptions::ContentLengthMismatch)
+ expect { run_content_length_validation }.to raise_error(Chef::Exceptions::ContentLengthMismatch)
end
end
end
@@ -144,7 +149,7 @@ describe Chef::HTTP::ValidateContentLength do
let(:streaming_length) { 12 }
it "should raise ContentLengthMismatch error" do
- lambda { run_content_length_validation }.should raise_error(Chef::Exceptions::ContentLengthMismatch)
+ expect { run_content_length_validation }.to raise_error(Chef::Exceptions::ContentLengthMismatch)
end
end
@@ -162,7 +167,7 @@ describe Chef::HTTP::ValidateContentLength do
it "should skip validation and log for debug" do
run_content_length_validation
- debug_output.should include("Transfer-Encoding header is set, skipping Content-Length check.")
+ expect(debug_output).to include("Transfer-Encoding header is set, skipping Content-Length check.")
end
end
end
@@ -171,16 +176,16 @@ describe Chef::HTTP::ValidateContentLength do
describe "when client is being reused" do
before do
run_content_length_validation
- debug_output.should include("Content-Length validated correctly.")
+ expect(debug_output).to include("Content-Length validated correctly.")
end
it "should reset internal counter" do
- middleware.instance_variable_get(:@content_length_counter).should be_nil
+ expect(middleware.instance_variable_get(:@content_length_counter)).to be_nil
end
it "should validate correctly second time" do
run_content_length_validation
- debug_output.should include("Content-Length validated correctly.")
+ expect(debug_output).to include("Content-Length validated correctly.")
end
end
diff --git a/spec/unit/http_spec.rb b/spec/unit/http_spec.rb
index 1cd226b4ee..ddfc56583d 100644
--- a/spec/unit/http_spec.rb
+++ b/spec/unit/http_spec.rb
@@ -31,17 +31,24 @@ describe Chef::HTTP do
it 'should return a correctly formatted url 1/3 CHEF-5261' do
http = Chef::HTTP.new('http://www.getchef.com')
- http.create_url('api/endpoint').should eql(URI.parse('http://www.getchef.com/api/endpoint'))
+ expect(http.create_url('api/endpoint')).to eql(URI.parse('http://www.getchef.com/api/endpoint'))
end
it 'should return a correctly formatted url 2/3 CHEF-5261' do
http = Chef::HTTP.new('http://www.getchef.com/')
- http.create_url('/organization/org/api/endpoint/').should eql(URI.parse('http://www.getchef.com/organization/org/api/endpoint/'))
+ expect(http.create_url('/organization/org/api/endpoint/')).to eql(URI.parse('http://www.getchef.com/organization/org/api/endpoint/'))
end
it 'should return a correctly formatted url 3/3 CHEF-5261' do
http = Chef::HTTP.new('http://www.getchef.com/organization/org///')
- http.create_url('///api/endpoint?url=http://foo.bar').should eql(URI.parse('http://www.getchef.com/organization/org/api/endpoint?url=http://foo.bar'))
+ expect(http.create_url('///api/endpoint?url=http://foo.bar')).to eql(URI.parse('http://www.getchef.com/organization/org/api/endpoint?url=http://foo.bar'))
+ end
+
+ # As per: https://github.com/opscode/chef/issues/2500
+ it 'should treat scheme part of the URI in a case-insensitive manner' do
+ http = Chef::HTTP.allocate # Calling Chef::HTTP::new sets @url, don't want that.
+ expect { http.create_url('HTTP://www1.chef.io/') }.not_to raise_error
+ expect(http.create_url('HTTP://www2.chef.io/')).to eql(URI.parse('http://www2.chef.io/'))
end
end # create_url
@@ -50,20 +57,20 @@ describe Chef::HTTP do
it 'should return nil for a "200 Success" response (CHEF-4762)' do
resp = Net::HTTPOK.new("1.1", 200, "OK")
- resp.should_receive(:read_body).and_return(nil)
+ expect(resp).to receive(:read_body).and_return(nil)
http = Chef::HTTP.new("")
- Chef::HTTP::BasicClient.any_instance.should_receive(:request).and_return(["request", resp])
+ expect_any_instance_of(Chef::HTTP::BasicClient).to receive(:request).and_return(["request", resp])
- http.head("http://www.getchef.com/").should eql(nil)
+ expect(http.head("http://www.getchef.com/")).to eql(nil)
end
it 'should return false for a "304 Not Modified" response (CHEF-4762)' do
resp = Net::HTTPNotModified.new("1.1", 304, "Not Modified")
- resp.should_receive(:read_body).and_return(nil)
+ expect(resp).to receive(:read_body).and_return(nil)
http = Chef::HTTP.new("")
- Chef::HTTP::BasicClient.any_instance.should_receive(:request).and_return(["request", resp])
+ expect_any_instance_of(Chef::HTTP::BasicClient).to receive(:request).and_return(["request", resp])
- http.head("http://www.getchef.com/").should eql(false)
+ expect(http.head("http://www.getchef.com/")).to eql(false)
end
end # head
diff --git a/spec/unit/knife/bootstrap/chef_vault_handler_spec.rb b/spec/unit/knife/bootstrap/chef_vault_handler_spec.rb
new file mode 100644
index 0000000000..d8f84265b7
--- /dev/null
+++ b/spec/unit/knife/bootstrap/chef_vault_handler_spec.rb
@@ -0,0 +1,153 @@
+#
+# Author:: Lamont Granquist <lamont@chef.io>)
+# Copyright:: Copyright (c) 2015 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 'spec_helper'
+
+describe Chef::Knife::Bootstrap::ChefVaultHandler do
+
+ let(:stdout) { StringIO.new }
+ let(:stderr) { StringIO.new }
+ let(:stdin) { StringIO.new }
+ let(:ui) { Chef::Knife::UI.new(stdout, stderr, stdin, {}) }
+
+ let(:knife_config) { {} }
+
+ let(:node_name) { "bevell.wat" }
+
+ let(:chef_vault_handler) {
+ chef_vault_handler = Chef::Knife::Bootstrap::ChefVaultHandler.new(knife_config: knife_config, ui: ui)
+ chef_vault_handler
+ }
+
+ context "when there's no vault option" do
+ it "should report its not doing anything" do
+ expect(chef_vault_handler.doing_chef_vault?).to be false
+ end
+
+ it "shouldn't do anything" do
+ expect(chef_vault_handler).to_not receive(:sanity_check)
+ expect(chef_vault_handler).to_not receive(:update_bootstrap_vault_json!)
+ chef_vault_handler
+ end
+ end
+
+ context "when setting chef vault items" do
+ let(:bootstrap_vault_item) { double("ChefVault::Item") }
+
+ before do
+ expect(chef_vault_handler).to receive(:wait_for_client).and_return(false)
+ expect(chef_vault_handler).to receive(:require_chef_vault!).at_least(:once)
+ expect(bootstrap_vault_item).to receive(:clients).with("name:#{node_name}").at_least(:once)
+ expect(bootstrap_vault_item).to receive(:save).at_least(:once)
+ end
+
+ context "from knife_config[:bootstrap_vault_item]" do
+ it "sets a single item as a scalar" do
+ knife_config[:bootstrap_vault_item] = { 'vault' => 'item1' }
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item1').and_return(bootstrap_vault_item)
+ chef_vault_handler.run(node_name: node_name)
+ end
+
+ it "sets a single item as an array" do
+ knife_config[:bootstrap_vault_item] = { 'vault' => [ 'item1' ] }
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item1').and_return(bootstrap_vault_item)
+ chef_vault_handler.run(node_name: node_name)
+ end
+
+ it "sets two items as an array" do
+ knife_config[:bootstrap_vault_item] = { 'vault' => [ 'item1', 'item2' ] }
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item1').and_return(bootstrap_vault_item)
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item2').and_return(bootstrap_vault_item)
+ chef_vault_handler.run(node_name: node_name)
+ end
+
+ it "sets two vaults from different hash keys" do
+ knife_config[:bootstrap_vault_item] = { 'vault' => [ 'item1', 'item2' ], 'vault2' => [ 'item3' ] }
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item1').and_return(bootstrap_vault_item)
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item2').and_return(bootstrap_vault_item)
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault2', 'item3').and_return(bootstrap_vault_item)
+ chef_vault_handler.run(node_name: node_name)
+ end
+ end
+
+ context "from knife_config[:bootstrap_vault_json]" do
+ it "sets a single item as a scalar" do
+ knife_config[:bootstrap_vault_json] = '{ "vault": "item1" }'
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item1').and_return(bootstrap_vault_item)
+ chef_vault_handler.run(node_name: node_name)
+ end
+
+ it "sets a single item as an array" do
+ knife_config[:bootstrap_vault_json] = '{ "vault": [ "item1" ] }'
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item1').and_return(bootstrap_vault_item)
+ chef_vault_handler.run(node_name: node_name)
+ end
+
+ it "sets two items as an array" do
+ knife_config[:bootstrap_vault_json] = '{ "vault": [ "item1", "item2" ] }'
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item1').and_return(bootstrap_vault_item)
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item2').and_return(bootstrap_vault_item)
+ chef_vault_handler.run(node_name: node_name)
+ end
+
+ it "sets two vaults from different hash keys" do
+ knife_config[:bootstrap_vault_json] = '{ "vault": [ "item1", "item2" ], "vault2": [ "item3" ] }'
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item1').and_return(bootstrap_vault_item)
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item2').and_return(bootstrap_vault_item)
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault2', 'item3').and_return(bootstrap_vault_item)
+ chef_vault_handler.run(node_name: node_name)
+ end
+ end
+
+ context "from knife_config[:bootstrap_vault_file]" do
+
+ def setup_file_contents(json)
+ stringio = StringIO.new(json)
+ knife_config[:bootstrap_vault_file] = "/foo/bar/baz"
+ expect(File).to receive(:read).with(knife_config[:bootstrap_vault_file]).and_return(stringio)
+ end
+
+ it "sets a single item as a scalar" do
+ setup_file_contents('{ "vault": "item1" }')
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item1').and_return(bootstrap_vault_item)
+ chef_vault_handler.run(node_name: node_name)
+ end
+
+ it "sets a single item as an array" do
+ setup_file_contents('{ "vault": [ "item1" ] }')
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item1').and_return(bootstrap_vault_item)
+ chef_vault_handler.run(node_name: node_name)
+ end
+
+ it "sets two items as an array" do
+ setup_file_contents('{ "vault": [ "item1", "item2" ] }')
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item1').and_return(bootstrap_vault_item)
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item2').and_return(bootstrap_vault_item)
+ chef_vault_handler.run(node_name: node_name)
+ end
+
+ it "sets two vaults from different hash keys" do
+ setup_file_contents('{ "vault": [ "item1", "item2" ], "vault2": [ "item3" ] }')
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item1').and_return(bootstrap_vault_item)
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault', 'item2').and_return(bootstrap_vault_item)
+ expect(chef_vault_handler).to receive(:load_chef_bootstrap_vault_item).with('vault2', 'item3').and_return(bootstrap_vault_item)
+ chef_vault_handler.run(node_name: node_name)
+ end
+ end
+ end
+end
diff --git a/spec/unit/knife/bootstrap/client_builder_spec.rb b/spec/unit/knife/bootstrap/client_builder_spec.rb
new file mode 100644
index 0000000000..e6aa307c7e
--- /dev/null
+++ b/spec/unit/knife/bootstrap/client_builder_spec.rb
@@ -0,0 +1,178 @@
+#
+# Author:: Lamont Granquist <lamont@chef.io>)
+# Copyright:: Copyright (c) 2015 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 'spec_helper'
+
+
+describe Chef::Knife::Bootstrap::ClientBuilder do
+
+ let(:stdout) { StringIO.new }
+ let(:stderr) { StringIO.new }
+ let(:stdin) { StringIO.new }
+ let(:ui) { Chef::Knife::UI.new(stdout, stderr, stdin, {}) }
+
+ let(:knife_config) { {} }
+
+ let(:chef_config) { {} }
+
+ let(:node_name) { "bevell.wat" }
+
+ let(:rest) { double("Chef::REST") }
+
+ let(:client_builder) {
+ 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
+ }
+
+ context "#sanity_check!" do
+ let(:response_404) { OpenStruct.new(:code => '404') }
+ let(:exception_404) { Net::HTTPServerException.new("404 not found", response_404) }
+
+ context "in cases where the prompting fails" do
+ before do
+ # should fail early in #run
+ expect(client_builder).to_not receive(:create_client!)
+ expect(client_builder).to_not receive(:create_node!)
+ end
+
+ it "exits when the node exists and the user does not want to delete" do
+ expect(rest).to receive(:get_rest).with("nodes/#{node_name}")
+ expect(ui.stdin).to receive(:readline).and_return('n')
+ expect { client_builder.run }.to raise_error(SystemExit)
+ end
+
+ it "exits when the client exists and the user does not want to delete" do
+ expect(rest).to receive(:get_rest).with("nodes/#{node_name}").and_raise(exception_404)
+ expect(rest).to receive(:get_rest).with("clients/#{node_name}")
+ expect(ui.stdin).to receive(:readline).and_return('n')
+ expect { client_builder.run }.to raise_error(SystemExit)
+ end
+ end
+
+ context "in cases where the prompting succeeds" do
+ before do
+ # mock out the rest of #run
+ expect(client_builder).to receive(:create_client!)
+ expect(client_builder).to receive(:create_node!)
+ end
+
+ it "when both the client and node do not exist it succeeds" do
+ expect(rest).to receive(:get_rest).with("nodes/#{node_name}").and_raise(exception_404)
+ expect(rest).to receive(:get_rest).with("clients/#{node_name}").and_raise(exception_404)
+ expect { client_builder.run }.not_to raise_error
+ end
+
+ it "when we are allowed to delete an old node" do
+ expect(rest).to receive(:get_rest).with("nodes/#{node_name}")
+ expect(ui.stdin).to receive(:readline).and_return('y')
+ expect(rest).to receive(:get_rest).with("clients/#{node_name}").and_raise(exception_404)
+ expect(rest).to receive(:delete).with("nodes/#{node_name}")
+ expect { client_builder.run }.not_to raise_error
+ end
+
+ it "when we are allowed to delete an old client" do
+ expect(rest).to receive(:get_rest).with("nodes/#{node_name}").and_raise(exception_404)
+ expect(rest).to receive(:get_rest).with("clients/#{node_name}")
+ expect(ui.stdin).to receive(:readline).and_return('y')
+ expect(rest).to receive(:delete).with("clients/#{node_name}")
+ expect { client_builder.run }.not_to raise_error
+ end
+
+ it "when we are are allowed to delete both an old client and node" do
+ expect(rest).to receive(:get_rest).with("nodes/#{node_name}")
+ expect(rest).to receive(:get_rest).with("clients/#{node_name}")
+ expect(ui.stdin).to receive(:readline).twice.and_return('y')
+ expect(rest).to receive(:delete).with("nodes/#{node_name}")
+ expect(rest).to receive(:delete).with("clients/#{node_name}")
+ expect { client_builder.run }.not_to raise_error
+ end
+ end
+ end
+
+ context "#create_client!" do
+ before do
+ # mock out the rest of #run
+ expect(client_builder).to receive(:sanity_check)
+ expect(client_builder).to receive(:create_node!)
+ end
+
+ it "delegates everything to Chef::ApiClient::Registration" do
+ reg_double = double("Chef::ApiClient::Registration")
+ expect(Chef::ApiClient::Registration).to receive(:new).with(node_name, client_builder.client_path, http_api: rest).and_return(reg_double)
+ expect(reg_double).to receive(:run)
+ client_builder.run
+ end
+
+ end
+
+ context "#client_path" do
+ it "has a public API for the temporary client.pem file" do
+ expect(client_builder.client_path).to match(/#{node_name}.pem/)
+ end
+ end
+
+ context "#create_node!" do
+ before do
+ # mock out the rest of #run
+ expect(client_builder).to receive(:sanity_check)
+ expect(client_builder).to receive(:create_client!)
+ # mock out default node building steps
+ expect(client_builder).to receive(:client_rest).and_return(client_rest)
+ expect(Chef::Node).to receive(:new).with(chef_server_rest: client_rest).and_return(node)
+ expect(node).to receive(:name).with(node_name)
+ expect(node).to receive(:save)
+ end
+
+ let(:client_rest) { double("Chef::REST (client)") }
+
+ let(:node) { double("Chef::Node") }
+
+ it "builds a node with a default run_list of []" do
+ expect(node).to receive(:run_list).with([])
+ client_builder.run
+ end
+
+ it "builds a node when the run_list is a string" do
+ knife_config[:run_list] = "role[base],role[app]"
+ expect(node).to receive(:run_list).with(["role[base]", "role[app]"])
+ client_builder.run
+ end
+
+ it "builds a node when the run_list is an Array" do
+ knife_config[:run_list] = ["role[base]", "role[app]"]
+ expect(node).to receive(:run_list).with(["role[base]", "role[app]"])
+ client_builder.run
+ end
+
+ it "builds a node with first_boot_attributes if they're given" do
+ knife_config[:first_boot_attributes] = {:baz => :quux}
+ expect(node).to receive(:normal_attrs=).with({:baz=>:quux})
+ expect(node).to receive(:run_list).with([])
+ client_builder.run
+ end
+
+ it "builds a node with an environment if its given" do
+ knife_config[:environment] = "production"
+ expect(node).to receive(:environment).with("production")
+ expect(node).to receive(:run_list).with([])
+ client_builder.run
+ end
+ end
+end
diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb
index 9769be5b8a..5a2e1f1c96 100644
--- a/spec/unit/knife/bootstrap_spec.rb
+++ b/spec/unit/knife/bootstrap_spec.rb
@@ -23,7 +23,7 @@ require 'net/ssh'
describe Chef::Knife::Bootstrap do
before do
- Chef::Platform.stub(:windows?) { false }
+ allow(Chef::Platform).to receive(:windows?) { false }
end
let(:knife) do
Chef::Log.logger = Logger.new(StringIO.new)
@@ -32,7 +32,7 @@ describe Chef::Knife::Bootstrap do
k = Chef::Knife::Bootstrap.new(bootstrap_cli_options)
k.merge_configs
- k.ui.stub(:stderr).and_return(stderr)
+ allow(k.ui).to receive(:stderr).and_return(stderr)
allow(k).to receive(:encryption_secret_provided_ignore_encrypt_flag?).and_return(false)
k
end
@@ -44,8 +44,15 @@ describe Chef::Knife::Bootstrap do
let(:bootstrap_cli_options) { [ ] }
it "should use chef-full as default template" do
- knife.bootstrap_template.should be_a_kind_of(String)
- File.basename(knife.bootstrap_template).should eq("chef-full")
+ expect(knife.bootstrap_template).to be_a_kind_of(String)
+ expect(File.basename(knife.bootstrap_template)).to eq("chef-full")
+ end
+
+ context "with --bootstrap-vault-item" do
+ let(:bootstrap_cli_options) { [ "--bootstrap-vault-item", "vault1:item1", "--bootstrap-vault-item", "vault1:item2", "--bootstrap-vault-item", "vault2:item1" ] }
+ it "sets the knife config cli option correctly" do
+ expect(knife.config[:bootstrap_vault_item]).to eq({"vault1"=>["item1", "item2"], "vault2"=>["item1"]})
+ end
end
context "with :distro and :bootstrap_template cli options" do
@@ -78,7 +85,7 @@ describe Chef::Knife::Bootstrap do
let(:bootstrap_template) { "/opt/blah/not/exists/template.erb" }
it "raises an error" do
- lambda { knife.find_template }.should raise_error
+ expect { knife.find_template }.to raise_error
end
end
@@ -86,8 +93,8 @@ describe Chef::Knife::Bootstrap do
let(:bootstrap_template) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test.erb")) }
it "loads the given file as the template" do
- Chef::Log.should_receive(:debug)
- knife.find_template.should eq(File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test.erb")))
+ expect(Chef::Log).to receive(:debug)
+ expect(knife.find_template).to eq(File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test.erb")))
end
end
end
@@ -95,7 +102,7 @@ describe Chef::Knife::Bootstrap do
context "when :bootstrap_template config is set to a template name" do
let(:bootstrap_template) { "example" }
- let(:builtin_template_path) { File.expand_path(File.join(File.dirname(__FILE__), '../../../lib/chef/knife/bootstrap', "example.erb"))}
+ let(:builtin_template_path) { File.expand_path(File.join(File.dirname(__FILE__), '../../../lib/chef/knife/bootstrap/templates', "example.erb"))}
let(:chef_config_dir_template_path) { "/knife/chef/config/bootstrap/example.erb" }
@@ -104,7 +111,7 @@ describe Chef::Knife::Bootstrap do
let(:gem_files_template_path) { "/Users/schisamo/.rvm/gems/ruby-1.9.2-p180@chef-0.10/gems/knife-windows-0.5.4/lib/chef/knife/bootstrap/fake-bootstrap-template.erb" }
def configure_chef_config_dir
- Chef::Knife.stub(:chef_config_dir).and_return("/knife/chef/config")
+ allow(Chef::Knife).to receive(:chef_config_dir).and_return("/knife/chef/config")
end
def configure_env_home
@@ -112,13 +119,13 @@ describe Chef::Knife::Bootstrap do
end
def configure_gem_files
- Gem.stub(:find_files).and_return([ gem_files_template_path ])
+ allow(Gem).to receive(:find_files).and_return([ gem_files_template_path ])
end
before(:each) do
@original_home = ENV['HOME']
ENV['HOME'] = nil
- File.should_receive(:exists?).with(bootstrap_template).and_return(false)
+ expect(File).to receive(:exists?).with(bootstrap_template).and_return(false)
end
after(:each) do
@@ -131,11 +138,11 @@ describe Chef::Knife::Bootstrap do
configure_env_home
configure_gem_files
- File.should_receive(:exists?).with(builtin_template_path).and_return(true)
+ expect(File).to receive(:exists?).with(builtin_template_path).and_return(true)
end
it "should load the template from built-in templates" do
- knife.find_template.should eq(builtin_template_path)
+ expect(knife.find_template).to eq(builtin_template_path)
end
end
@@ -145,8 +152,8 @@ describe Chef::Knife::Bootstrap do
configure_env_home
configure_gem_files
- File.should_receive(:exists?).with(builtin_template_path).and_return(false)
- File.should_receive(:exists?).with(chef_config_dir_template_path).and_return(true)
+ expect(File).to receive(:exists?).with(builtin_template_path).and_return(false)
+ expect(File).to receive(:exists?).with(chef_config_dir_template_path).and_return(true)
it "should load the template from chef_config_dir" do
knife.find_template.should eq(chef_config_dir_template_path)
@@ -160,13 +167,13 @@ describe Chef::Knife::Bootstrap do
configure_env_home
configure_gem_files
- File.should_receive(:exists?).with(builtin_template_path).and_return(false)
- File.should_receive(:exists?).with(chef_config_dir_template_path).and_return(false)
- File.should_receive(:exists?).with(env_home_template_path).and_return(true)
+ expect(File).to receive(:exists?).with(builtin_template_path).and_return(false)
+ expect(File).to receive(:exists?).with(chef_config_dir_template_path).and_return(false)
+ expect(File).to receive(:exists?).with(env_home_template_path).and_return(true)
end
it "should load the template from chef_config_dir" do
- knife.find_template.should eq(env_home_template_path)
+ expect(knife.find_template).to eq(env_home_template_path)
end
end
@@ -175,13 +182,13 @@ describe Chef::Knife::Bootstrap do
configure_chef_config_dir
configure_gem_files
- File.should_receive(:exists?).with(builtin_template_path).and_return(false)
- File.should_receive(:exists?).with(chef_config_dir_template_path).and_return(false)
- File.should_receive(:exists?).with(gem_files_template_path).and_return(true)
+ expect(File).to receive(:exists?).with(builtin_template_path).and_return(false)
+ expect(File).to receive(:exists?).with(chef_config_dir_template_path).and_return(false)
+ expect(File).to receive(:exists?).with(gem_files_template_path).and_return(true)
end
it "should load the template from Gem files" do
- knife.find_template.should eq(gem_files_template_path)
+ expect(knife.find_template).to eq(gem_files_template_path)
end
end
end
@@ -192,7 +199,7 @@ describe Chef::Knife::Bootstrap do
it "sets the knife :bootstrap_template config" do
knife.parse_options([t,"blahblah"])
knife.merge_configs
- knife.bootstrap_template.should eq("blahblah")
+ expect(knife.bootstrap_template).to eq("blahblah")
end
end
end
@@ -201,19 +208,19 @@ describe Chef::Knife::Bootstrap do
let(:bootstrap_template) { File.expand_path(File.join(CHEF_SPEC_DATA, "bootstrap", "test.erb")) }
it "should return an empty run_list" do
- knife.render_template.should == '{"run_list":[]}'
+ expect(knife.render_template).to eq('{"run_list":[]}')
end
it "should have role[base] in the run_list" do
knife.parse_options(["-r","role[base]"])
knife.merge_configs
- knife.render_template.should == '{"run_list":["role[base]"]}'
+ expect(knife.render_template).to eq('{"run_list":["role[base]"]}')
end
it "should have role[base] and recipe[cupcakes] in the run_list" do
knife.parse_options(["-r", "role[base],recipe[cupcakes]"])
knife.merge_configs
- knife.render_template.should == '{"run_list":["role[base]","recipe[cupcakes]"]}'
+ expect(knife.render_template).to eq('{"run_list":["role[base]","recipe[cupcakes]"]}')
end
it "should have foo => {bar => baz} in the first_boot" do
@@ -221,7 +228,7 @@ describe Chef::Knife::Bootstrap do
knife.merge_configs
expected_hash = FFI_Yajl::Parser.new.parse('{"foo":{"bar":"baz"},"run_list":[]}')
actual_hash = FFI_Yajl::Parser.new.parse(knife.render_template)
- actual_hash.should == expected_hash
+ expect(actual_hash).to eq(expected_hash)
end
end
@@ -231,14 +238,14 @@ describe Chef::Knife::Bootstrap do
it "should create a hint file when told to" do
knife.parse_options(["--hint", "openstack"])
knife.merge_configs
- knife.render_template.should match /\/etc\/chef\/ohai\/hints\/openstack.json/
+ expect(knife.render_template).to match /\/etc\/chef\/ohai\/hints\/openstack.json/
end
it "should populate a hint file with JSON when given a file to read" do
- ::File.stub(:read).and_return('{ "foo" : "bar" }')
+ allow(::File).to receive(:read).and_return('{ "foo" : "bar" }')
knife.parse_options(["--hint", "openstack=hints/openstack.json"])
knife.merge_configs
- knife.render_template.should match /\{\"foo\":\"bar\"\}/
+ expect(knife.render_template).to match /\{\"foo\":\"bar\"\}/
end
end
@@ -261,7 +268,7 @@ describe Chef::Knife::Bootstrap do
let(:setting) { "api.opscode.com" }
it "renders the client.rb with a single FQDN no_proxy entry" do
- rendered_template.should match(%r{.*no_proxy\s*"api.opscode.com".*})
+ expect(rendered_template).to match(%r{.*no_proxy\s*"api.opscode.com".*})
end
end
@@ -269,7 +276,7 @@ describe Chef::Knife::Bootstrap do
let(:setting) { "api.opscode.com,172.16.10.*" }
it "renders the client.rb with comma-separated FQDN and wildcard IP address no_proxy entries" do
- rendered_template.should match(%r{.*no_proxy\s*"api.opscode.com,172.16.10.\*".*})
+ expect(rendered_template).to match(%r{.*no_proxy\s*"api.opscode.com,172.16.10.\*".*})
end
end
@@ -277,7 +284,7 @@ describe Chef::Knife::Bootstrap do
let(:options) { ["--node-ssl-verify-mode", "none"] }
it "renders the client.rb with ssl_verify_mode set to :verify_none" do
- rendered_template.should match(/ssl_verify_mode :verify_none/)
+ expect(rendered_template).to match(/ssl_verify_mode :verify_none/)
end
end
@@ -285,7 +292,7 @@ describe Chef::Knife::Bootstrap do
let(:options) { ["--node-ssl-verify-mode", "peer"] }
it "renders the client.rb with ssl_verify_mode set to :verify_peer" do
- rendered_template.should match(/ssl_verify_mode :verify_peer/)
+ expect(rendered_template).to match(/ssl_verify_mode :verify_peer/)
end
end
@@ -293,7 +300,7 @@ describe Chef::Knife::Bootstrap do
let(:options) { ["--node-ssl-verify-mode", "all"] }
it "raises error" do
- lambda{ rendered_template }.should raise_error
+ expect{ rendered_template }.to raise_error
end
end
@@ -301,7 +308,7 @@ describe Chef::Knife::Bootstrap do
let(:options) { ["--node-verify-api-cert"] }
it "renders the client.rb with verify_api_cert set to true" do
- rendered_template.should match(/verify_api_cert true/)
+ expect(rendered_template).to match(/verify_api_cert true/)
end
end
@@ -309,7 +316,7 @@ describe Chef::Knife::Bootstrap do
let(:options) { ["--no-node-verify-api-cert"] }
it "renders the client.rb with verify_api_cert set to false" do
- rendered_template.should match(/verify_api_cert false/)
+ expect(rendered_template).to match(/verify_api_cert false/)
end
end
end
@@ -327,13 +334,13 @@ describe Chef::Knife::Bootstrap do
it "creates a secret file" do
expect(knife).to receive(:encryption_secret_provided_ignore_encrypt_flag?).and_return(true)
expect(knife).to receive(:read_secret).and_return(secret)
- rendered_template.should match(%r{#{secret}})
+ expect(rendered_template).to match(%r{#{secret}})
end
it "renders the client.rb with an encrypted_data_bag_secret entry" do
expect(knife).to receive(:encryption_secret_provided_ignore_encrypt_flag?).and_return(true)
expect(knife).to receive(:read_secret).and_return(secret)
- rendered_template.should match(%r{encrypted_data_bag_secret\s*"/etc/chef/encrypted_data_bag_secret"})
+ expect(rendered_template).to match(%r{encrypted_data_bag_secret\s*"/etc/chef/encrypted_data_bag_secret"})
end
end
@@ -348,8 +355,8 @@ describe Chef::Knife::Bootstrap do
before do
Chef::Config[:trusted_certs_dir] = trusted_certs_dir
- IO.stub(:read).and_call_original
- IO.stub(:read).with(File.expand_path(Chef::Config[:validation_key])).and_return("")
+ allow(IO).to receive(:read).and_call_original
+ allow(IO).to receive(:read).with(File.expand_path(Chef::Config[:validation_key])).and_return("")
end
def certificates
@@ -357,22 +364,22 @@ describe Chef::Knife::Bootstrap do
end
it "creates /etc/chef/trusted_certs" do
- rendered_template.should match(%r{mkdir -p /etc/chef/trusted_certs})
+ expect(rendered_template).to match(%r{mkdir -p /etc/chef/trusted_certs})
end
it "copies the certificates in the directory" do
certificates.each do |cert|
- IO.should_receive(:read).with(File.expand_path(cert))
+ expect(IO).to receive(:read).with(File.expand_path(cert))
end
certificates.each do |cert|
- rendered_template.should match(%r{cat > /etc/chef/trusted_certs/#{File.basename(cert)} <<'EOP'})
+ expect(rendered_template).to match(%r{cat > /etc/chef/trusted_certs/#{File.basename(cert)} <<'EOP'})
end
end
it "doesn't create /etc/chef/trusted_certs if :trusted_certs_dir is empty" do
- Dir.should_receive(:glob).with(File.join(trusted_certs_dir, "*.{crt,pem}")).and_return([])
- rendered_template.should_not match(%r{mkdir -p /etc/chef/trusted_certs})
+ expect(Dir).to receive(:glob).with(File.join(trusted_certs_dir, "*.{crt,pem}")).and_return([])
+ expect(rendered_template).not_to match(%r{mkdir -p /etc/chef/trusted_certs})
end
end
@@ -387,57 +394,57 @@ describe Chef::Knife::Bootstrap do
Chef::Config[:knife][:ssh_port] = nil
knife.config[:forward_agent] = true
knife.config[:identity_file] = "~/.ssh/me.rsa"
- knife.stub(:render_template).and_return("")
+ allow(knife).to receive(:render_template).and_return("")
knife.knife_ssh
end
it "configures the hostname" do
- knife_ssh.name_args.first.should == "foo.example.com"
+ expect(knife_ssh.name_args.first).to eq("foo.example.com")
end
it "configures the ssh user" do
- knife_ssh.config[:ssh_user].should == 'rooty'
+ expect(knife_ssh.config[:ssh_user]).to eq('rooty')
end
it "configures the ssh password" do
- knife_ssh.config[:ssh_password].should == 'open_sesame'
+ expect(knife_ssh.config[:ssh_password]).to eq('open_sesame')
end
it "configures the ssh port" do
- knife_ssh.config[:ssh_port].should == '4001'
+ expect(knife_ssh.config[:ssh_port]).to eq('4001')
end
it "configures the ssh agent forwarding" do
- knife_ssh.config[:forward_agent].should == true
+ expect(knife_ssh.config[:forward_agent]).to eq(true)
end
it "configures the ssh identity file" do
- knife_ssh.config[:identity_file].should == '~/.ssh/me.rsa'
+ expect(knife_ssh.config[:identity_file]).to eq('~/.ssh/me.rsa')
end
end
context "validating use_sudo_password" do
before do
knife.config[:ssh_password] = "password"
- knife.stub(:render_template).and_return("")
+ allow(knife).to receive(:render_template).and_return("")
end
it "use_sudo_password contains description and long params for help" do
- knife.options.should have_key(:use_sudo_password) \
- and knife.options[:use_sudo_password][:description].to_s.should_not == ''\
- and knife.options[:use_sudo_password][:long].to_s.should_not == ''
+ expect(knife.options).to have_key(:use_sudo_password) \
+ and expect(knife.options[:use_sudo_password][:description].to_s).not_to eq('')\
+ and expect(knife.options[:use_sudo_password][:long].to_s).not_to eq('')
end
it "uses the password from --ssh-password for sudo when --use-sudo-password is set" do
knife.config[:use_sudo] = true
knife.config[:use_sudo_password] = true
- knife.ssh_command.should include("echo \'#{knife.config[:ssh_password]}\' | sudo -S")
+ expect(knife.ssh_command).to include("echo \'#{knife.config[:ssh_password]}\' | sudo -S")
end
it "should not honor --use-sudo-password when --use-sudo is not set" do
knife.config[:use_sudo] = false
knife.config[:use_sudo_password] = true
- knife.ssh_command.should_not include("echo #{knife.config[:ssh_password]} | sudo -S")
+ expect(knife.ssh_command).not_to include("echo #{knife.config[:ssh_password]} | sudo -S")
end
end
@@ -450,34 +457,34 @@ describe Chef::Knife::Bootstrap do
Chef::Config[:knife][:identity_file] = "~/.ssh/you.rsa"
Chef::Config[:knife][:ssh_gateway] = "towel.blinkenlights.nl"
Chef::Config[:knife][:host_key_verify] = true
- knife.stub(:render_template).and_return("")
+ allow(knife).to receive(:render_template).and_return("")
knife.config = {}
knife.merge_configs
knife.knife_ssh
end
it "configures the ssh user" do
- knife_ssh.config[:ssh_user].should == 'curiosity'
+ expect(knife_ssh.config[:ssh_user]).to eq('curiosity')
end
it "configures the ssh port" do
- knife_ssh.config[:ssh_port].should == '2430'
+ expect(knife_ssh.config[:ssh_port]).to eq('2430')
end
it "configures the ssh agent forwarding" do
- knife_ssh.config[:forward_agent].should == true
+ expect(knife_ssh.config[:forward_agent]).to eq(true)
end
it "configures the ssh identity file" do
- knife_ssh.config[:identity_file].should == '~/.ssh/you.rsa'
+ expect(knife_ssh.config[:identity_file]).to eq('~/.ssh/you.rsa')
end
it "configures the ssh gateway" do
- knife_ssh.config[:ssh_gateway].should == 'towel.blinkenlights.nl'
+ expect(knife_ssh.config[:ssh_gateway]).to eq('towel.blinkenlights.nl')
end
it "configures the host key verify mode" do
- knife_ssh.config[:host_key_verify].should == true
+ expect(knife_ssh.config[:host_key_verify]).to eq(true)
end
end
@@ -486,27 +493,27 @@ describe Chef::Knife::Bootstrap do
knife.name_args = ["foo.example.com"]
knife.config[:ssh_user] = "rooty"
knife.config[:identity_file] = "~/.ssh/me.rsa"
- knife.stub(:render_template).and_return("")
+ allow(knife).to receive(:render_template).and_return("")
k = knife.knife_ssh
- k.stub(:get_password).and_return('typed_in_password')
- knife.stub(:knife_ssh).and_return(k)
+ allow(k).to receive(:get_password).and_return('typed_in_password')
+ allow(knife).to receive(:knife_ssh).and_return(k)
knife.knife_ssh_with_password_auth
end
it "prompts the user for a password " do
- knife_ssh_with_password_auth.config[:ssh_password].should == 'typed_in_password'
+ expect(knife_ssh_with_password_auth.config[:ssh_password]).to eq('typed_in_password')
end
it "configures knife not to use the identity file that didn't work previously" do
- knife_ssh_with_password_auth.config[:identity_file].should be_nil
+ expect(knife_ssh_with_password_auth.config[:identity_file]).to be_nil
end
end
end
it "verifies that a server to bootstrap was given as a command line arg" do
knife.name_args = nil
- lambda { knife.run }.should raise_error(SystemExit)
- stderr.string.should match /ERROR:.+FQDN or ip/
+ expect { knife.run }.to raise_error(SystemExit)
+ expect(stderr.string).to match /ERROR:.+FQDN or ip/
end
describe "when running the bootstrap" do
@@ -514,31 +521,77 @@ describe Chef::Knife::Bootstrap do
knife.name_args = ["foo.example.com"]
knife.config[:ssh_user] = "rooty"
knife.config[:identity_file] = "~/.ssh/me.rsa"
- knife.stub(:render_template).and_return("")
+ allow(knife).to receive(:render_template).and_return("")
knife_ssh = knife.knife_ssh
- knife.stub(:knife_ssh).and_return(knife_ssh)
+ allow(knife).to receive(:knife_ssh).and_return(knife_ssh)
knife_ssh
end
- it "configures the underlying ssh command and then runs it" do
- knife_ssh.should_receive(:run)
- knife.run
- end
+ context "when running with a configured and present validation key" do
+ before do
+ # this tests runs the old code path where we have a validation key, so we need to pass that check
+ allow(File).to receive(:exist?).with(File.expand_path(Chef::Config[:validation_key])).and_return(true)
+ end
- it "falls back to password based auth when auth fails the first time" do
- knife.stub(:puts)
- fallback_knife_ssh = knife_ssh.dup
- knife_ssh.should_receive(:run).and_raise(Net::SSH::AuthenticationFailed.new("no ssh for you"))
- knife.stub(:knife_ssh_with_password_auth).and_return(fallback_knife_ssh)
- fallback_knife_ssh.should_receive(:run)
- knife.run
+ it "configures the underlying ssh command and then runs it" do
+ expect(knife_ssh).to receive(:run)
+ knife.run
+ end
+
+ it "falls back to password based auth when auth fails the first time" do
+ allow(knife).to receive(:puts)
+
+ fallback_knife_ssh = knife_ssh.dup
+ expect(knife_ssh).to receive(:run).and_raise(Net::SSH::AuthenticationFailed.new("no ssh for you"))
+ allow(knife).to receive(:knife_ssh_with_password_auth).and_return(fallback_knife_ssh)
+ expect(fallback_knife_ssh).to receive(:run)
+ knife.run
+ end
+
+ it "raises the exception if config[:ssh_password] is set and an authentication exception is raised" do
+ knife.config[:ssh_password] = "password"
+ expect(knife_ssh).to receive(:run).and_raise(Net::SSH::AuthenticationFailed)
+ expect { knife.run }.to raise_error(Net::SSH::AuthenticationFailed)
+ end
+
+ it "creates the client and adds chef-vault items if vault_list is set" do
+ knife.config[:bootstrap_vault_file] = "/not/our/responsibility/to/check/if/this/exists"
+ expect(knife_ssh).to receive(:run)
+ expect(knife.client_builder).to receive(:run)
+ expect(knife.chef_vault_handler).to receive(:run).with(node_name: knife.config[:chef_node_name])
+ knife.run
+ end
+
+ it "creates the client and adds chef-vault items if vault_items is set" do
+ knife.config[:bootstrap_vault_json] = '{ "vault" => "item" }'
+ expect(knife_ssh).to receive(:run)
+ expect(knife.client_builder).to receive(:run)
+ expect(knife.chef_vault_handler).to receive(:run).with(node_name: knife.config[:chef_node_name])
+ knife.run
+ end
+
+ it "does old-style validation without creating a client key if vault_list+vault_items is not set" do
+ expect(File).to receive(:exist?).with(File.expand_path(Chef::Config[:validation_key])).and_return(true)
+ expect(knife_ssh).to receive(:run)
+ expect(knife.client_builder).not_to receive(:run)
+ expect(knife.chef_vault_handler).not_to receive(:run).with(node_name: knife.config[:chef_node_name])
+ knife.run
+ end
end
- it "raises the exception if config[:ssh_password] is set and an authentication exception is raised" do
- knife.config[:ssh_password] = "password"
- knife_ssh.should_receive(:run).and_raise(Net::SSH::AuthenticationFailed)
- lambda { knife.run }.should raise_error(Net::SSH::AuthenticationFailed)
+ context "when the validation key is not present" do
+ before do
+ # this tests runs the old code path where we have a validation key, so we need to pass that check
+ allow(File).to receive(:exist?).with(File.expand_path(Chef::Config[:validation_key])).and_return(false)
+ end
+
+ it "creates the client (and possibly adds chef-vault items)" do
+ expect(knife_ssh).to receive(:run)
+ expect(knife.client_builder).to receive(:run)
+ expect(knife.chef_vault_handler).to receive(:run).with(node_name: knife.config[:chef_node_name])
+ knife.run
+ end
end
end
diff --git a/spec/unit/knife/client_bulk_delete_spec.rb b/spec/unit/knife/client_bulk_delete_spec.rb
index d5cfda9885..45bb4dd16c 100644
--- a/spec/unit/knife/client_bulk_delete_spec.rb
+++ b/spec/unit/knife/client_bulk_delete_spec.rb
@@ -28,10 +28,10 @@ describe Chef::Knife::ClientBulkDelete do
k = Chef::Knife::ClientBulkDelete.new
k.name_args = name_args
k.config = option_args
- k.ui.stub(:stdout).and_return(stdout_io)
- k.ui.stub(:stderr).and_return(stderr_io)
- k.ui.stub(:confirm).and_return(knife_confirm)
- k.ui.stub(:confirm_without_exit).and_return(knife_confirm)
+ allow(k.ui).to receive(:stdout).and_return(stdout_io)
+ allow(k.ui).to receive(:stderr).and_return(stderr_io)
+ allow(k.ui).to receive(:confirm).and_return(knife_confirm)
+ allow(k.ui).to receive(:confirm_without_exit).and_return(knife_confirm)
k
}
@@ -47,7 +47,7 @@ describe Chef::Knife::ClientBulkDelete do
nonvalidator_client_names.each do |client_name|
client = Chef::ApiClient.new()
client.name(client_name)
- client.stub(:destroy).and_return(true)
+ allow(client).to receive(:destroy).and_return(true)
clients[client_name] = client
end
@@ -61,8 +61,8 @@ describe Chef::Knife::ClientBulkDelete do
validator_client_names.each do |validator_client_name|
validator_client = Chef::ApiClient.new()
validator_client.name(validator_client_name)
- validator_client.stub(:validator).and_return(true)
- validator_client.stub(:destroy).and_return(true)
+ allow(validator_client).to receive(:validator).and_return(true)
+ allow(validator_client).to receive(:destroy).and_return(true)
clients[validator_client_name] = validator_client
end
@@ -75,7 +75,7 @@ describe Chef::Knife::ClientBulkDelete do
}
before(:each) do
- Chef::ApiClient.stub(:list).and_return(clients)
+ allow(Chef::ApiClient).to receive(:list).and_return(clients)
end
describe "run" do
@@ -83,44 +83,44 @@ describe Chef::Knife::ClientBulkDelete do
let(:name_args) { [ ] }
it "should exit if the regex is not provided" do
- lambda { knife.run }.should raise_error(SystemExit)
+ expect { knife.run }.to raise_error(SystemExit)
end
end
describe "with any clients" do
it "should get the list of the clients" do
- Chef::ApiClient.should_receive(:list)
+ expect(Chef::ApiClient).to receive(:list)
knife.run
end
it "should print the name of the clients" do
knife.run
client_names.each do |client_name|
- stdout.should include(client_name)
+ expect(stdout).to include(client_name)
end
end
it "should confirm you really want to delete them" do
- knife.ui.should_receive(:confirm)
+ expect(knife.ui).to receive(:confirm)
knife.run
end
describe "without --delete-validators" do
it "should mention that validator clients wont be deleted" do
knife.run
- stdout.should include("Following clients are validators and will not be deleted.")
+ expect(stdout).to include("Following clients are validators and will not be deleted.")
info = stdout.index "Following clients are validators and will not be deleted."
val = stdout.index "myorg-validator"
- (val > info).should be_true
+ expect(val > info).to be_truthy
end
it "should only delete nonvalidator clients" do
nonvalidator_clients.each_value do |c|
- c.should_receive(:destroy)
+ expect(c).to receive(:destroy)
end
validator_clients.each_value do |c|
- c.should_not_receive(:destroy)
+ expect(c).not_to receive(:destroy)
end
knife.run
@@ -132,18 +132,18 @@ describe Chef::Knife::ClientBulkDelete do
it "should mention that validator clients will be deleted" do
knife.run
- stdout.should include("The following validators will be deleted")
+ expect(stdout).to include("The following validators will be deleted")
end
it "should confirm twice" do
- knife.ui.should_receive(:confirm).once
- knife.ui.should_receive(:confirm_without_exit).once
+ expect(knife.ui).to receive(:confirm).once
+ expect(knife.ui).to receive(:confirm_without_exit).once
knife.run
end
it "should delete all clients" do
clients.each_value do |c|
- c.should_receive(:destroy)
+ expect(c).to receive(:destroy)
end
knife.run
@@ -155,10 +155,10 @@ describe Chef::Knife::ClientBulkDelete do
let(:name_args) { [ "^ti" ] }
it "should only delete clients that match the regex" do
- clients["tim"].should_receive(:destroy)
- clients["stephen"].should_not_receive(:destroy)
- clients["dan"].should_not_receive(:destroy)
- clients["myorg-validator"].should_not_receive(:destroy)
+ expect(clients["tim"]).to receive(:destroy)
+ expect(clients["stephen"]).not_to receive(:destroy)
+ expect(clients["dan"]).not_to receive(:destroy)
+ expect(clients["myorg-validator"]).not_to receive(:destroy)
knife.run
end
end
diff --git a/spec/unit/knife/client_create_spec.rb b/spec/unit/knife/client_create_spec.rb
index 59238d69ec..10d386b5ff 100644
--- a/spec/unit/knife/client_create_spec.rb
+++ b/spec/unit/knife/client_create_spec.rb
@@ -21,82 +21,96 @@ require 'spec_helper'
Chef::Knife::ClientCreate.load_deps
describe Chef::Knife::ClientCreate do
+ let(:stderr) { StringIO.new }
+
+ let(:default_client_hash) do
+ {
+ "name" => "adam",
+ "validator" => false,
+ "admin" => false
+ }
+ end
+
+ let(:client) do
+ c = double("Chef::ApiClient")
+ allow(c).to receive(:save).and_return({"private_key" => ""})
+ allow(c).to receive(:to_s).and_return("client[adam]")
+ c
+ end
+
+ let(:knife) do
+ k = Chef::Knife::ClientCreate.new
+ k.name_args = [ "adam" ]
+ k.ui.config[:disable_editing] = true
+ allow(k.ui).to receive(:stderr).and_return(stderr)
+ allow(k.ui).to receive(:stdout).and_return(stderr)
+ k
+ end
+
before(:each) do
Chef::Config[:node_name] = "webmonkey.example.com"
- @knife = Chef::Knife::ClientCreate.new
- @knife.config = {
- :file => nil,
- :admin => false,
- :validator => false
- }
- @knife.name_args = [ "adam" ]
- @client = Chef::ApiClient.new
- @client.stub(:save).and_return({ 'private_key' => '' })
- @knife.stub(:edit_data).and_return(@client)
- @knife.stub(:puts)
- Chef::ApiClient.stub(:new).and_return(@client)
- @stderr = StringIO.new
- @knife.ui.stub(:stderr).and_return(@stderr)
end
describe "run" do
- it "should create a new Client" do
- Chef::ApiClient.should_receive(:new).and_return(@client)
- @knife.run
- @stderr.string.should match /created client.+adam/i
+ it "should create and save the ApiClient" do
+ expect(Chef::ApiClient).to receive(:from_hash).and_return(client)
+ expect(client).to receive(:save)
+ knife.run
+ end
+
+ it "should print a message upon creation" do
+ expect(Chef::ApiClient).to receive(:from_hash).and_return(client)
+ expect(client).to receive(:save)
+ knife.run
+ expect(stderr.string).to match /Created client.*adam/i
end
it "should set the Client name" do
- @client.should_receive(:name).with("adam")
- @knife.run
+ expect(Chef::ApiClient).to receive(:from_hash).with(hash_including("name" => "adam")).and_return(client)
+ knife.run
end
it "by default it is not an admin" do
- @client.should_receive(:admin).with(false)
- @knife.run
+ expect(Chef::ApiClient).to receive(:from_hash).with(hash_including("admin" => false)).and_return(client)
+ knife.run
end
it "by default it is not a validator" do
- @client.should_receive(:validator).with(false)
- @knife.run
+ expect(Chef::ApiClient).to receive(:from_hash).with(hash_including("validator" => false)).and_return(client)
+ knife.run
end
it "should allow you to edit the data" do
- @knife.should_receive(:edit_data).with(@client)
- @knife.run
- end
-
- it "should save the Client" do
- @client.should_receive(:save)
- @knife.run
+ expect(knife).to receive(:edit_hash).with(default_client_hash).and_return(default_client_hash)
+ allow(Chef::ApiClient).to receive(:from_hash).and_return(client)
+ knife.run
end
describe "with -f or --file" do
it "should write the private key to a file" do
- @knife.config[:file] = "/tmp/monkeypants"
- @client.stub(:save).and_return({ 'private_key' => "woot" })
+ knife.config[:file] = "/tmp/monkeypants"
+ allow_any_instance_of(Chef::ApiClient).to receive(:save).and_return({ 'private_key' => "woot" })
filehandle = double("Filehandle")
- filehandle.should_receive(:print).with('woot')
- File.should_receive(:open).with("/tmp/monkeypants", "w").and_yield(filehandle)
- @knife.run
+ expect(filehandle).to receive(:print).with('woot')
+ expect(File).to receive(:open).with("/tmp/monkeypants", "w").and_yield(filehandle)
+ knife.run
end
end
describe "with -a or --admin" do
it "should create an admin client" do
- @knife.config[:admin] = true
- @client.should_receive(:admin).with(true)
- @knife.run
+ knife.config[:admin] = true
+ expect(Chef::ApiClient).to receive(:from_hash).with(hash_including("admin" => true)).and_return(client)
+ knife.run
end
end
describe "with --validator" do
it "should create an validator client" do
- @knife.config[:validator] = true
- @client.should_receive(:validator).with(true)
- @knife.run
+ knife.config[:validator] = true
+ expect(Chef::ApiClient).to receive(:from_hash).with(hash_including("validator" => true)).and_return(client)
+ knife.run
end
end
-
end
end
diff --git a/spec/unit/knife/client_delete_spec.rb b/spec/unit/knife/client_delete_spec.rb
index c7908a0934..0fb5e0bab7 100644
--- a/spec/unit/knife/client_delete_spec.rb
+++ b/spec/unit/knife/client_delete_spec.rb
@@ -30,52 +30,52 @@ describe Chef::Knife::ClientDelete do
describe 'run' do
it 'should delete the client' do
- @knife.should_receive(:delete_object).with(Chef::ApiClient, 'adam', 'client')
+ expect(@knife).to receive(:delete_object).with(Chef::ApiClient, 'adam', 'client')
@knife.run
end
it 'should print usage and exit when a client name is not provided' do
@knife.name_args = []
- @knife.should_receive(:show_usage)
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:show_usage)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
describe 'with a validator' do
before(:each) do
- Chef::Knife::UI.stub(:confirm).and_return(true)
- @knife.stub(:confirm).and_return(true)
+ allow(Chef::Knife::UI).to receive(:confirm).and_return(true)
+ allow(@knife).to receive(:confirm).and_return(true)
@client = Chef::ApiClient.new
- Chef::ApiClient.should_receive(:load).and_return(@client)
+ expect(Chef::ApiClient).to receive(:load).and_return(@client)
end
it 'should delete non-validator client if --delete-validators is not set' do
@knife.config[:delete_validators] = false
- @client.should_receive(:destroy).and_return(@client)
- @knife.should_receive(:msg)
+ expect(@client).to receive(:destroy).and_return(@client)
+ expect(@knife).to receive(:msg)
@knife.run
end
it 'should delete non-validator client if --delete-validators is set' do
@knife.config[:delete_validators] = true
- @client.should_receive(:destroy).and_return(@client)
- @knife.should_receive(:msg)
+ expect(@client).to receive(:destroy).and_return(@client)
+ expect(@knife).to receive(:msg)
@knife.run
end
it 'should not delete validator client if --delete-validators is not set' do
@client.validator(true)
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run}.should raise_error(SystemExit)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run}.to raise_error(SystemExit)
end
it 'should delete validator client if --delete-validators is set' do
@knife.config[:delete_validators] = true
- @client.should_receive(:destroy).and_return(@client)
- @knife.should_receive(:msg)
+ expect(@client).to receive(:destroy).and_return(@client)
+ expect(@knife).to receive(:msg)
@knife.run
end
diff --git a/spec/unit/knife/client_edit_spec.rb b/spec/unit/knife/client_edit_spec.rb
index 1d7049be30..c040c5e2f2 100644
--- a/spec/unit/knife/client_edit_spec.rb
+++ b/spec/unit/knife/client_edit_spec.rb
@@ -26,15 +26,15 @@ describe Chef::Knife::ClientEdit do
describe 'run' do
it 'should edit the client' do
- @knife.should_receive(:edit_object).with(Chef::ApiClient, 'adam')
+ expect(@knife).to receive(:edit_object).with(Chef::ApiClient, 'adam')
@knife.run
end
it 'should print usage and exit when a client name is not provided' do
@knife.name_args = []
- @knife.should_receive(:show_usage)
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:show_usage)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
end
diff --git a/spec/unit/knife/client_list_spec.rb b/spec/unit/knife/client_list_spec.rb
index c4834ad8d1..eff01da4e9 100644
--- a/spec/unit/knife/client_list_spec.rb
+++ b/spec/unit/knife/client_list_spec.rb
@@ -26,8 +26,8 @@ describe Chef::Knife::ClientList do
describe 'run' do
it 'should list the clients' do
- Chef::ApiClient.should_receive(:list)
- @knife.should_receive(:format_list_for_display)
+ expect(Chef::ApiClient).to receive(:list)
+ expect(@knife).to receive(:format_list_for_display)
@knife.run
end
end
diff --git a/spec/unit/knife/client_reregister_spec.rb b/spec/unit/knife/client_reregister_spec.rb
index daf18d5d25..f1be4ed570 100644
--- a/spec/unit/knife/client_reregister_spec.rb
+++ b/spec/unit/knife/client_reregister_spec.rb
@@ -24,7 +24,7 @@ describe Chef::Knife::ClientReregister do
@knife.name_args = [ 'adam' ]
@client_mock = double('client_mock', :private_key => "foo_key")
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
context "when no client name is given on the command line" do
@@ -33,29 +33,29 @@ describe Chef::Knife::ClientReregister do
end
it 'should print usage and exit when a client name is not provided' do
- @knife.should_receive(:show_usage)
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:show_usage)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
context 'when not configured for file output' do
it 'reregisters the client and prints the key' do
- Chef::ApiClient.should_receive(:reregister).with('adam').and_return(@client_mock)
+ expect(Chef::ApiClient).to receive(:reregister).with('adam').and_return(@client_mock)
@knife.run
- @stdout.string.should match( /foo_key/ )
+ expect(@stdout.string).to match( /foo_key/ )
end
end
context 'when configured for file output' do
it 'should write the private key to a file' do
- Chef::ApiClient.should_receive(:reregister).with('adam').and_return(@client_mock)
+ expect(Chef::ApiClient).to receive(:reregister).with('adam').and_return(@client_mock)
@knife.config[:file] = '/tmp/monkeypants'
filehandle = StringIO.new
- File.should_receive(:open).with('/tmp/monkeypants', 'w').and_yield(filehandle)
+ expect(File).to receive(:open).with('/tmp/monkeypants', 'w').and_yield(filehandle)
@knife.run
- filehandle.string.should == "foo_key"
+ expect(filehandle.string).to eq("foo_key")
end
end
diff --git a/spec/unit/knife/configure_client_spec.rb b/spec/unit/knife/configure_client_spec.rb
index de2a5a41e5..363743f8cc 100644
--- a/spec/unit/knife/configure_client_spec.rb
+++ b/spec/unit/knife/configure_client_spec.rb
@@ -26,16 +26,16 @@ describe Chef::Knife::ConfigureClient do
Chef::Config[:validation_key] = '/etc/chef/validation.pem'
@stderr = StringIO.new
- @knife.ui.stub(:stderr).and_return(@stderr)
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
end
describe 'run' do
it 'should print usage and exit when a directory is not provided' do
- @knife.should_receive(:show_usage)
- @knife.ui.should_receive(:fatal).with(/must provide the directory/)
- lambda {
+ expect(@knife).to receive(:show_usage)
+ expect(@knife.ui).to receive(:fatal).with(/must provide the directory/)
+ expect {
@knife.run
- }.should raise_error SystemExit
+ }.to raise_error SystemExit
end
describe 'when specifing a directory' do
@@ -43,39 +43,39 @@ describe Chef::Knife::ConfigureClient do
@knife.name_args = ['/home/bob/.chef']
@client_file = StringIO.new
@validation_file = StringIO.new
- File.should_receive(:open).with('/home/bob/.chef/client.rb', 'w').
+ expect(File).to receive(:open).with('/home/bob/.chef/client.rb', 'w').
and_yield(@client_file)
- File.should_receive(:open).with('/home/bob/.chef/validation.pem', 'w').
+ expect(File).to receive(:open).with('/home/bob/.chef/validation.pem', 'w').
and_yield(@validation_file)
- IO.should_receive(:read).and_return('foo_bar_baz')
+ expect(IO).to receive(:read).and_return('foo_bar_baz')
end
it 'should recursively create the directory' do
- FileUtils.should_receive(:mkdir_p).with('/home/bob/.chef')
+ expect(FileUtils).to receive(:mkdir_p).with('/home/bob/.chef')
@knife.run
end
it 'should write out the config file' do
- FileUtils.stub(:mkdir_p)
+ allow(FileUtils).to receive(:mkdir_p)
@knife.run
- @client_file.string.should match /log_level\s+\:info/
- @client_file.string.should match /log_location\s+STDOUT/
- @client_file.string.should match /chef_server_url\s+'https\:\/\/chef\.example\.com'/
- @client_file.string.should match /validation_client_name\s+'chef-validator'/
+ expect(@client_file.string).to match /log_level\s+\:info/
+ expect(@client_file.string).to match /log_location\s+STDOUT/
+ expect(@client_file.string).to match /chef_server_url\s+'https\:\/\/chef\.example\.com'/
+ expect(@client_file.string).to match /validation_client_name\s+'chef-validator'/
end
it 'should write out the validation.pem file' do
- FileUtils.stub(:mkdir_p)
+ allow(FileUtils).to receive(:mkdir_p)
@knife.run
- @validation_file.string.should match /foo_bar_baz/
+ expect(@validation_file.string).to match /foo_bar_baz/
end
it 'should print information on what is being configured' do
- FileUtils.stub(:mkdir_p)
+ allow(FileUtils).to receive(:mkdir_p)
@knife.run
- @stderr.string.should match /creating client configuration/i
- @stderr.string.should match /writing client\.rb/i
- @stderr.string.should match /writing validation\.pem/i
+ expect(@stderr.string).to match /creating client configuration/i
+ expect(@stderr.string).to match /writing client\.rb/i
+ expect(@stderr.string).to match /writing validation\.pem/i
end
end
end
diff --git a/spec/unit/knife/configure_spec.rb b/spec/unit/knife/configure_spec.rb
index c16019dcf7..e3ea1f052c 100644
--- a/spec/unit/knife/configure_spec.rb
+++ b/spec/unit/knife/configure_spec.rb
@@ -7,19 +7,19 @@ describe Chef::Knife::Configure do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::Configure.new
@rest_client = double("null rest client", :post_rest => { :result => :true })
- @knife.stub(:rest).and_return(@rest_client)
+ allow(@knife).to receive(:rest).and_return(@rest_client)
@out = StringIO.new
- @knife.ui.stub(:stdout).and_return(@out)
+ allow(@knife.ui).to receive(:stdout).and_return(@out)
@knife.config[:config_file] = '/home/you/.chef/knife.rb'
@in = StringIO.new("\n" * 7)
- @knife.ui.stub(:stdin).and_return(@in)
+ allow(@knife.ui).to receive(:stdin).and_return(@in)
@err = StringIO.new
- @knife.ui.stub(:stderr).and_return(@err)
+ allow(@knife.ui).to receive(:stderr).and_return(@err)
- Ohai::System.stub(:new).and_return(ohai)
+ allow(Ohai::System).to receive(:new).and_return(ohai)
end
@@ -27,8 +27,8 @@ describe Chef::Knife::Configure do
let(:ohai) do
o = {}
- o.stub(:require_plugin)
- o.stub(:load_plugins)
+ allow(o).to receive(:require_plugin)
+ allow(o).to receive(:load_plugins)
o[:fqdn] = fqdn
o
end
@@ -44,63 +44,63 @@ describe Chef::Knife::Configure do
it "asks the user for the URL of the chef server" do
@knife.ask_user_for_config
- @out.string.should match(Regexp.escape("Please enter the chef server URL: [#{default_server_url}]"))
- @knife.chef_server.should == default_server_url
+ expect(@out.string).to match(Regexp.escape("Please enter the chef server URL: [#{default_server_url}]"))
+ expect(@knife.chef_server).to eq(default_server_url)
end
it "asks the user for the clientname they want for the new client if -i is specified" do
@knife.config[:initial] = true
- Etc.stub(:getlogin).and_return("a-new-user")
+ allow(Etc).to receive(:getlogin).and_return("a-new-user")
@knife.ask_user_for_config
- @out.string.should match(Regexp.escape("Please enter a name for the new user: [a-new-user]"))
- @knife.new_client_name.should == Etc.getlogin
+ expect(@out.string).to match(Regexp.escape("Please enter a name for the new user: [a-new-user]"))
+ expect(@knife.new_client_name).to eq(Etc.getlogin)
end
it "should not ask the user for the clientname they want for the new client if -i and --node_name are specified" do
@knife.config[:initial] = true
@knife.config[:node_name] = 'testnode'
- Etc.stub(:getlogin).and_return("a-new-user")
+ allow(Etc).to receive(:getlogin).and_return("a-new-user")
@knife.ask_user_for_config
- @out.string.should_not match(Regexp.escape("Please enter a name for the new user"))
- @knife.new_client_name.should == 'testnode'
+ expect(@out.string).not_to match(Regexp.escape("Please enter a name for the new user"))
+ expect(@knife.new_client_name).to eq('testnode')
end
it "asks the user for the existing API username or clientname if -i is not specified" do
- Etc.stub(:getlogin).and_return("a-new-user")
+ allow(Etc).to receive(:getlogin).and_return("a-new-user")
@knife.ask_user_for_config
- @out.string.should match(Regexp.escape("Please enter an existing username or clientname for the API: [a-new-user]"))
- @knife.new_client_name.should == Etc.getlogin
+ expect(@out.string).to match(Regexp.escape("Please enter an existing username or clientname for the API: [a-new-user]"))
+ expect(@knife.new_client_name).to eq(Etc.getlogin)
end
it "asks the user for the existing admin client's name if -i is specified" do
@knife.config[:initial] = true
@knife.ask_user_for_config
- @out.string.should match(Regexp.escape("Please enter the existing admin name: [admin]"))
- @knife.admin_client_name.should == 'admin'
+ expect(@out.string).to match(Regexp.escape("Please enter the existing admin name: [admin]"))
+ expect(@knife.admin_client_name).to eq('admin')
end
it "should not ask the user for the existing admin client's name if -i and --admin-client_name are specified" do
@knife.config[:initial] = true
@knife.config[:admin_client_name] = 'my-webui'
@knife.ask_user_for_config
- @out.string.should_not match(Regexp.escape("Please enter the existing admin:"))
- @knife.admin_client_name.should == 'my-webui'
+ expect(@out.string).not_to match(Regexp.escape("Please enter the existing admin:"))
+ expect(@knife.admin_client_name).to eq('my-webui')
end
it "should not ask the user for the existing admin client's name if -i is not specified" do
@knife.ask_user_for_config
- @out.string.should_not match(Regexp.escape("Please enter the existing admin: [admin]"))
- @knife.admin_client_name.should_not == 'admin'
+ expect(@out.string).not_to match(Regexp.escape("Please enter the existing admin: [admin]"))
+ expect(@knife.admin_client_name).not_to eq('admin')
end
it "asks the user for the location of the existing admin key if -i is specified" do
@knife.config[:initial] = true
@knife.ask_user_for_config
- @out.string.should match(Regexp.escape("Please enter the location of the existing admin's private key: [#{default_admin_key}]"))
+ expect(@out.string).to match(Regexp.escape("Please enter the location of the existing admin's private key: [#{default_admin_key}]"))
if windows?
- @knife.admin_client_key.capitalize.should == default_admin_key_win32.capitalize
+ expect(@knife.admin_client_key.capitalize).to eq(default_admin_key_win32.capitalize)
else
- @knife.admin_client_key.should == default_admin_key
+ expect(@knife.admin_client_key).to eq(default_admin_key)
end
end
@@ -108,61 +108,61 @@ describe Chef::Knife::Configure do
@knife.config[:initial] = true
@knife.config[:admin_client_key] = '/home/you/.chef/my-webui.pem'
@knife.ask_user_for_config
- @out.string.should_not match(Regexp.escape("Please enter the location of the existing admin client's private key:"))
+ expect(@out.string).not_to match(Regexp.escape("Please enter the location of the existing admin client's private key:"))
if windows?
- @knife.admin_client_key.should match %r{^[A-Za-z]:/home/you/\.chef/my-webui\.pem$}
+ expect(@knife.admin_client_key).to match %r{^[A-Za-z]:/home/you/\.chef/my-webui\.pem$}
else
- @knife.admin_client_key.should == '/home/you/.chef/my-webui.pem'
+ expect(@knife.admin_client_key).to eq('/home/you/.chef/my-webui.pem')
end
end
it "should not ask the user for the location of the existing admin key if -i is not specified" do
@knife.ask_user_for_config
- @out.string.should_not match(Regexp.escape("Please enter the location of the existing admin client's private key: [#{default_admin_key}]"))
+ expect(@out.string).not_to match(Regexp.escape("Please enter the location of the existing admin client's private key: [#{default_admin_key}]"))
if windows?
- @knife.admin_client_key.should_not == default_admin_key_win32
+ expect(@knife.admin_client_key).not_to eq(default_admin_key_win32)
else
- @knife.admin_client_key.should_not == default_admin_key
+ expect(@knife.admin_client_key).not_to eq(default_admin_key)
end
end
it "asks the user for the location of a chef repo" do
@knife.ask_user_for_config
- @out.string.should match(Regexp.escape("Please enter the path to a chef repository (or leave blank):"))
- @knife.chef_repo.should == ''
+ expect(@out.string).to match(Regexp.escape("Please enter the path to a chef repository (or leave blank):"))
+ expect(@knife.chef_repo).to eq('')
end
it "asks the users for the name of the validation client" do
@knife.ask_user_for_config
- @out.string.should match(Regexp.escape("Please enter the validation clientname: [chef-validator]"))
- @knife.validation_client_name.should == 'chef-validator'
+ expect(@out.string).to match(Regexp.escape("Please enter the validation clientname: [chef-validator]"))
+ expect(@knife.validation_client_name).to eq('chef-validator')
end
it "should not ask the users for the name of the validation client if --validation_client_name is specified" do
@knife.config[:validation_client_name] = 'my-validator'
@knife.ask_user_for_config
- @out.string.should_not match(Regexp.escape("Please enter the validation clientname:"))
- @knife.validation_client_name.should == 'my-validator'
+ expect(@out.string).not_to match(Regexp.escape("Please enter the validation clientname:"))
+ expect(@knife.validation_client_name).to eq('my-validator')
end
it "asks the users for the location of the validation key" do
@knife.ask_user_for_config
- @out.string.should match(Regexp.escape("Please enter the location of the validation key: [#{default_validator_key}]"))
+ expect(@out.string).to match(Regexp.escape("Please enter the location of the validation key: [#{default_validator_key}]"))
if windows?
- @knife.validation_key.capitalize.should == default_validator_key_win32.capitalize
+ expect(@knife.validation_key.capitalize).to eq(default_validator_key_win32.capitalize)
else
- @knife.validation_key.should == default_validator_key
+ expect(@knife.validation_key).to eq(default_validator_key)
end
end
it "should not ask the users for the location of the validation key if --validation_key is specified" do
@knife.config[:validation_key] = '/home/you/.chef/my-validation.pem'
@knife.ask_user_for_config
- @out.string.should_not match(Regexp.escape("Please enter the location of the validation key:"))
+ expect(@out.string).not_to match(Regexp.escape("Please enter the location of the validation key:"))
if windows?
- @knife.validation_key.should match %r{^[A-Za-z]:/home/you/\.chef/my-validation\.pem$}
+ expect(@knife.validation_key).to match %r{^[A-Za-z]:/home/you/\.chef/my-validation\.pem$}
else
- @knife.validation_key.should == '/home/you/.chef/my-validation.pem'
+ expect(@knife.validation_key).to eq('/home/you/.chef/my-validation.pem')
end
end
@@ -176,68 +176,68 @@ describe Chef::Knife::Configure do
@knife.config[:validation_key] = '/home/you/.chef/my-validation.pem'
@knife.config[:repository] = ''
@knife.config[:client_key] = '/home/you/a-new-user.pem'
- Etc.stub(:getlogin).and_return('a-new-user')
+ allow(Etc).to receive(:getlogin).and_return('a-new-user')
@knife.ask_user_for_config
- @out.string.should match(/\s*/)
+ expect(@out.string).to match(/\s*/)
- @knife.new_client_name.should == 'testnode'
- @knife.chef_server.should == 'http://localhost:5000'
- @knife.admin_client_name.should == 'my-webui'
+ expect(@knife.new_client_name).to eq('testnode')
+ expect(@knife.chef_server).to eq('http://localhost:5000')
+ expect(@knife.admin_client_name).to eq('my-webui')
if windows?
- @knife.admin_client_key.should match %r{^[A-Za-z]:/home/you/\.chef/my-webui\.pem$}
- @knife.validation_key.should match %r{^[A-Za-z]:/home/you/\.chef/my-validation\.pem$}
- @knife.new_client_key.should match %r{^[A-Za-z]:/home/you/a-new-user\.pem$}
+ expect(@knife.admin_client_key).to match %r{^[A-Za-z]:/home/you/\.chef/my-webui\.pem$}
+ expect(@knife.validation_key).to match %r{^[A-Za-z]:/home/you/\.chef/my-validation\.pem$}
+ expect(@knife.new_client_key).to match %r{^[A-Za-z]:/home/you/a-new-user\.pem$}
else
- @knife.admin_client_key.should == '/home/you/.chef/my-webui.pem'
- @knife.validation_key.should == '/home/you/.chef/my-validation.pem'
- @knife.new_client_key.should == '/home/you/a-new-user.pem'
+ expect(@knife.admin_client_key).to eq('/home/you/.chef/my-webui.pem')
+ expect(@knife.validation_key).to eq('/home/you/.chef/my-validation.pem')
+ expect(@knife.new_client_key).to eq('/home/you/a-new-user.pem')
end
- @knife.validation_client_name.should == 'my-validator'
- @knife.chef_repo.should == ''
+ expect(@knife.validation_client_name).to eq('my-validator')
+ expect(@knife.chef_repo).to eq('')
end
it "writes the new data to a config file" do
- File.stub(:expand_path).with("/home/you/.chef/knife.rb").and_return("/home/you/.chef/knife.rb")
- File.stub(:expand_path).with("/home/you/.chef/#{Etc.getlogin}.pem").and_return("/home/you/.chef/#{Etc.getlogin}.pem")
- File.stub(:expand_path).with(default_validator_key).and_return(default_validator_key)
- File.stub(:expand_path).with(default_admin_key).and_return(default_admin_key)
- FileUtils.should_receive(:mkdir_p).with("/home/you/.chef")
+ allow(File).to receive(:expand_path).with("/home/you/.chef/knife.rb").and_return("/home/you/.chef/knife.rb")
+ allow(File).to receive(:expand_path).with("/home/you/.chef/#{Etc.getlogin}.pem").and_return("/home/you/.chef/#{Etc.getlogin}.pem")
+ allow(File).to receive(:expand_path).with(default_validator_key).and_return(default_validator_key)
+ allow(File).to receive(:expand_path).with(default_admin_key).and_return(default_admin_key)
+ expect(FileUtils).to receive(:mkdir_p).with("/home/you/.chef")
config_file = StringIO.new
- ::File.should_receive(:open).with("/home/you/.chef/knife.rb", "w").and_yield config_file
+ expect(::File).to receive(:open).with("/home/you/.chef/knife.rb", "w").and_yield config_file
@knife.config[:repository] = '/home/you/chef-repo'
@knife.run
- config_file.string.should match(/^node_name[\s]+'#{Etc.getlogin}'$/)
- config_file.string.should match(%r{^client_key[\s]+'/home/you/.chef/#{Etc.getlogin}.pem'$})
- config_file.string.should match(/^validation_client_name\s+'chef-validator'$/)
- config_file.string.should match(%r{^validation_key\s+'#{default_validator_key}'$})
- config_file.string.should match(%r{^chef_server_url\s+'#{default_server_url}'$})
- config_file.string.should match(%r{cookbook_path\s+\[ '/home/you/chef-repo/cookbooks' \]})
+ expect(config_file.string).to match(/^node_name[\s]+'#{Etc.getlogin}'$/)
+ expect(config_file.string).to match(%r{^client_key[\s]+'/home/you/.chef/#{Etc.getlogin}.pem'$})
+ expect(config_file.string).to match(/^validation_client_name\s+'chef-validator'$/)
+ expect(config_file.string).to match(%r{^validation_key\s+'#{default_validator_key}'$})
+ expect(config_file.string).to match(%r{^chef_server_url\s+'#{default_server_url}'$})
+ expect(config_file.string).to match(%r{cookbook_path\s+\[ '/home/you/chef-repo/cookbooks' \]})
end
it "creates a new client when given the --initial option" do
- File.should_receive(:expand_path).with("/home/you/.chef/knife.rb").and_return("/home/you/.chef/knife.rb")
- File.should_receive(:expand_path).with("/home/you/.chef/a-new-user.pem").and_return("/home/you/.chef/a-new-user.pem")
- File.should_receive(:expand_path).with(default_validator_key).and_return(default_validator_key)
- File.should_receive(:expand_path).with(default_admin_key).and_return(default_admin_key)
+ expect(File).to receive(:expand_path).with("/home/you/.chef/knife.rb").and_return("/home/you/.chef/knife.rb")
+ expect(File).to receive(:expand_path).with("/home/you/.chef/a-new-user.pem").and_return("/home/you/.chef/a-new-user.pem")
+ expect(File).to receive(:expand_path).with(default_validator_key).and_return(default_validator_key)
+ expect(File).to receive(:expand_path).with(default_admin_key).and_return(default_admin_key)
Chef::Config[:node_name] = "webmonkey.example.com"
user_command = Chef::Knife::UserCreate.new
- user_command.should_receive(:run)
+ expect(user_command).to receive(:run)
- Etc.stub(:getlogin).and_return("a-new-user")
+ allow(Etc).to receive(:getlogin).and_return("a-new-user")
- Chef::Knife::UserCreate.stub(:new).and_return(user_command)
- FileUtils.should_receive(:mkdir_p).with("/home/you/.chef")
- ::File.should_receive(:open).with("/home/you/.chef/knife.rb", "w")
+ allow(Chef::Knife::UserCreate).to receive(:new).and_return(user_command)
+ expect(FileUtils).to receive(:mkdir_p).with("/home/you/.chef")
+ expect(::File).to receive(:open).with("/home/you/.chef/knife.rb", "w")
@knife.config[:initial] = true
@knife.config[:user_password] = "blah"
@knife.run
- user_command.name_args.should == Array("a-new-user")
- user_command.config[:user_password].should == "blah"
- user_command.config[:admin].should be_true
- user_command.config[:file].should == "/home/you/.chef/a-new-user.pem"
- user_command.config[:yes].should be_true
- user_command.config[:disable_editing].should be_true
+ expect(user_command.name_args).to eq(Array("a-new-user"))
+ expect(user_command.config[:user_password]).to eq("blah")
+ expect(user_command.config[:admin]).to be_truthy
+ expect(user_command.config[:file]).to eq("/home/you/.chef/a-new-user.pem")
+ expect(user_command.config[:yes]).to be_truthy
+ expect(user_command.config[:disable_editing]).to be_truthy
end
end
diff --git a/spec/unit/knife/cookbook_bulk_delete_spec.rb b/spec/unit/knife/cookbook_bulk_delete_spec.rb
index fb4b1d1484..98cd06bbbc 100644
--- a/spec/unit/knife/cookbook_bulk_delete_spec.rb
+++ b/spec/unit/knife/cookbook_bulk_delete_spec.rb
@@ -28,19 +28,19 @@ describe Chef::Knife::CookbookBulkDelete do
@knife.name_args = ["."]
@stdout = StringIO.new
@stderr = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
- @knife.ui.stub(:stderr).and_return(@stderr)
- @knife.ui.stub(:confirm).and_return(true)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
+ allow(@knife.ui).to receive(:confirm).and_return(true)
@cookbooks = Hash.new
%w{cheezburger pizza lasagna}.each do |cookbook_name|
cookbook = Chef::CookbookVersion.new(cookbook_name)
@cookbooks[cookbook_name] = cookbook
end
@rest = double("Chef::REST")
- @rest.stub(:get_rest).and_return(@cookbooks)
- @rest.stub(:delete_rest).and_return(true)
- @knife.stub(:rest).and_return(@rest)
- Chef::CookbookVersion.stub(:list).and_return(@cookbooks)
+ allow(@rest).to receive(:get_rest).and_return(@cookbooks)
+ allow(@rest).to receive(:delete_rest).and_return(true)
+ allow(@knife).to receive(:rest).and_return(@rest)
+ allow(Chef::CookbookVersion).to receive(:list).and_return(@cookbooks)
end
@@ -49,41 +49,41 @@ describe Chef::Knife::CookbookBulkDelete do
describe "when there are several cookbooks on the server" do
before do
@cheezburger = {'cheezburger' => {"url" => "file:///dev/null", "versions" => [{"url" => "file:///dev/null-cheez", "version" => "1.0.0"}]}}
- @rest.stub(:get_rest).with('cookbooks/cheezburger').and_return(@cheezburger)
+ allow(@rest).to receive(:get_rest).with('cookbooks/cheezburger').and_return(@cheezburger)
@pizza = {'pizza' => {"url" => "file:///dev/null", "versions" => [{"url" => "file:///dev/null-pizza", "version" => "2.0.0"}]}}
- @rest.stub(:get_rest).with('cookbooks/pizza').and_return(@pizza)
+ allow(@rest).to receive(:get_rest).with('cookbooks/pizza').and_return(@pizza)
@lasagna = {'lasagna' => {"url" => "file:///dev/null", "versions" => [{"url" => "file:///dev/null-lasagna", "version" => "3.0.0"}]}}
- @rest.stub(:get_rest).with('cookbooks/lasagna').and_return(@lasagna)
+ allow(@rest).to receive(:get_rest).with('cookbooks/lasagna').and_return(@lasagna)
end
it "should print the cookbooks you are about to delete" do
expected = @knife.ui.list(@cookbooks.keys.sort, :columns_down)
@knife.run
- @stdout.string.should match(/#{expected}/)
+ expect(@stdout.string).to match(/#{expected}/)
end
it "should confirm you really want to delete them" do
- @knife.ui.should_receive(:confirm)
+ expect(@knife.ui).to receive(:confirm)
@knife.run
end
it "should delete each cookbook" do
{"cheezburger" => "1.0.0", "pizza" => "2.0.0", "lasagna" => '3.0.0'}.each do |cookbook_name, version|
- @rest.should_receive(:delete_rest).with("cookbooks/#{cookbook_name}/#{version}")
+ expect(@rest).to receive(:delete_rest).with("cookbooks/#{cookbook_name}/#{version}")
end
@knife.run
end
it "should only delete cookbooks that match the regex" do
@knife.name_args = ["cheezburger"]
- @rest.should_receive(:delete_rest).with('cookbooks/cheezburger/1.0.0')
+ expect(@rest).to receive(:delete_rest).with('cookbooks/cheezburger/1.0.0')
@knife.run
end
end
it "should exit if the regex is not provided" do
@knife.name_args = []
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
diff --git a/spec/unit/knife/cookbook_create_spec.rb b/spec/unit/knife/cookbook_create_spec.rb
index 06475d3ac9..3354432d39 100644
--- a/spec/unit/knife/cookbook_create_spec.rb
+++ b/spec/unit/knife/cookbook_create_spec.rb
@@ -26,29 +26,29 @@ describe Chef::Knife::CookbookCreate do
@knife.config = {}
@knife.name_args = ["foobar"]
@stdout = StringIO.new
- @knife.stub(:stdout).and_return(@stdout)
+ allow(@knife).to receive(:stdout).and_return(@stdout)
end
describe "run" do
# Fixes CHEF-2579
it "should expand the path of the cookbook directory" do
- File.should_receive(:expand_path).with("~/tmp/monkeypants")
+ expect(File).to receive(:expand_path).with("~/tmp/monkeypants")
@knife.config = {:cookbook_path => "~/tmp/monkeypants"}
- @knife.stub(:create_cookbook)
- @knife.stub(:create_readme)
- @knife.stub(:create_changelog)
- @knife.stub(:create_metadata)
+ allow(@knife).to receive(:create_cookbook)
+ allow(@knife).to receive(:create_readme)
+ allow(@knife).to receive(:create_changelog)
+ allow(@knife).to receive(:create_metadata)
@knife.run
end
it "should create a new cookbook with default values to copyright name, email, readme format and license if those are not supplied" do
@dir = Dir.tmpdir
@knife.config = {:cookbook_path => @dir}
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "YOUR_COMPANY_NAME", "none")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "md")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "YOUR_COMPANY_NAME", "YOUR_EMAIL", "none", "md")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "YOUR_COMPANY_NAME", "none")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "md")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "YOUR_COMPANY_NAME", "YOUR_EMAIL", "none", "md")
@knife.run
end
@@ -59,10 +59,10 @@ describe Chef::Knife::CookbookCreate do
:cookbook_copyright => "Opscode, Inc"
}
@knife.name_args=["foobar"]
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "none")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "md")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "YOUR_EMAIL", "none", "md")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "none")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "md")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "YOUR_EMAIL", "none", "md")
@knife.run
end
@@ -74,10 +74,10 @@ describe Chef::Knife::CookbookCreate do
:cookbook_email => "nuo@opscode.com"
}
@knife.name_args=["foobar"]
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "none")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "md")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "none", "md")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "none")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "md")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "none", "md")
@knife.run
end
@@ -90,10 +90,10 @@ describe Chef::Knife::CookbookCreate do
:cookbook_license => "apachev2"
}
@knife.name_args=["foobar"]
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "apachev2")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "md")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "apachev2", "md")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "apachev2")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "md")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "apachev2", "md")
@knife.run
end
@@ -106,10 +106,10 @@ describe Chef::Knife::CookbookCreate do
:cookbook_license => false
}
@knife.name_args=["foobar"]
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "none")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "md")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "none", "md")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "none")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "md")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "none", "md")
@knife.run
end
@@ -122,10 +122,10 @@ describe Chef::Knife::CookbookCreate do
:cookbook_license => "false"
}
@knife.name_args=["foobar"]
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "none")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "md")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "none", "md")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "none")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "md")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "none", "md")
@knife.run
end
@@ -138,10 +138,10 @@ describe Chef::Knife::CookbookCreate do
:cookbook_license => "gplv2"
}
@knife.name_args=["foobar"]
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "gplv2")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "md")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "gplv2", "md")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "gplv2")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "md")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "gplv2", "md")
@knife.run
end
@@ -154,10 +154,10 @@ describe Chef::Knife::CookbookCreate do
:cookbook_license => "gplv3"
}
@knife.name_args=["foobar"]
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "gplv3")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "md")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "gplv3", "md")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "gplv3")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "md")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "gplv3", "md")
@knife.run
end
@@ -170,10 +170,10 @@ describe Chef::Knife::CookbookCreate do
:cookbook_license => "mit"
}
@knife.name_args=["foobar"]
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "mit")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "md")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "mit", "md")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "mit")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "md")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "mit", "md")
@knife.run
end
@@ -187,10 +187,10 @@ describe Chef::Knife::CookbookCreate do
:readme_format => "rdoc"
}
@knife.name_args=["foobar"]
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "mit")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "rdoc")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "mit", "rdoc")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "mit")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "rdoc")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "mit", "rdoc")
@knife.run
end
@@ -204,10 +204,10 @@ describe Chef::Knife::CookbookCreate do
:readme_format => "mkd"
}
@knife.name_args=["foobar"]
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "mit")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "mkd")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "mit", "mkd")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "mit")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "mkd")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "mit", "mkd")
@knife.run
end
@@ -221,10 +221,10 @@ describe Chef::Knife::CookbookCreate do
:readme_format => "txt"
}
@knife.name_args=["foobar"]
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "mit")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "txt")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "mit", "txt")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "mit")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "txt")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "mit", "txt")
@knife.run
end
@@ -238,10 +238,10 @@ describe Chef::Knife::CookbookCreate do
:readme_format => "foo"
}
@knife.name_args=["foobar"]
- @knife.should_receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "mit")
- @knife.should_receive(:create_readme).with(@dir, @knife.name_args.first, "foo")
- @knife.should_receive(:create_changelog).with(@dir, @knife.name_args.first)
- @knife.should_receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "mit", "foo")
+ expect(@knife).to receive(:create_cookbook).with(@dir, @knife.name_args.first, "Opscode, Inc", "mit")
+ expect(@knife).to receive(:create_readme).with(@dir, @knife.name_args.first, "foo")
+ expect(@knife).to receive(:create_changelog).with(@dir, @knife.name_args.first)
+ expect(@knife).to receive(:create_metadata).with(@dir, @knife.name_args.first, "Opscode, Inc", "nuo@opscode.com", "mit", "foo")
@knife.run
end
@@ -252,7 +252,7 @@ describe Chef::Knife::CookbookCreate do
it "should throw an argument error" do
@dir = Dir.tmpdir
- lambda{@knife.run}.should raise_error(ArgumentError)
+ expect{@knife.run}.to raise_error(ArgumentError)
end
end
diff --git a/spec/unit/knife/cookbook_delete_spec.rb b/spec/unit/knife/cookbook_delete_spec.rb
index 53b120be71..4e75a689e3 100644
--- a/spec/unit/knife/cookbook_delete_spec.rb
+++ b/spec/unit/knife/cookbook_delete_spec.rb
@@ -24,29 +24,29 @@ describe Chef::Knife::CookbookDelete do
@knife.name_args = ['foobar']
@knife.cookbook_name = 'foobar'
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
@stderr = StringIO.new
- @knife.ui.stub(:stderr).and_return(@stderr)
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
end
describe 'run' do
it 'should print usage and exit when a cookbook name is not provided' do
@knife.name_args = []
- @knife.should_receive(:show_usage)
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:show_usage)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
describe 'when specifying a cookbook name' do
it 'should delete the cookbook without a specific version' do
- @knife.should_receive(:delete_without_explicit_version)
+ expect(@knife).to receive(:delete_without_explicit_version)
@knife.run
end
describe 'and a version' do
it 'should delete the specific version of the cookbook' do
@knife.name_args << '1.0.0'
- @knife.should_receive(:delete_explicit_version)
+ expect(@knife).to receive(:delete_explicit_version)
@knife.run
end
end
@@ -54,7 +54,7 @@ describe Chef::Knife::CookbookDelete do
describe 'with -a or --all' do
it 'should delete all versions of the cookbook' do
@knife.config[:all] = true
- @knife.should_receive(:delete_all_versions)
+ expect(@knife).to receive(:delete_all_versions)
@knife.run
end
end
@@ -62,9 +62,9 @@ describe Chef::Knife::CookbookDelete do
describe 'with -p or --purge' do
it 'should prompt to purge the files' do
@knife.config[:purge] = true
- @knife.should_receive(:confirm).
+ expect(@knife).to receive(:confirm).
with(/.+Are you sure you want to purge files.+/)
- @knife.should_receive(:delete_without_explicit_version)
+ expect(@knife).to receive(:delete_without_explicit_version)
@knife.run
end
end
@@ -75,10 +75,10 @@ describe Chef::Knife::CookbookDelete do
it 'should delete the specific cookbook version' do
@knife.cookbook_name = 'foobar'
@knife.version = '1.0.0'
- @knife.should_receive(:delete_object).with(Chef::CookbookVersion,
+ expect(@knife).to receive(:delete_object).with(Chef::CookbookVersion,
'foobar version 1.0.0',
'cookbook').and_yield()
- @knife.should_receive(:delete_request).with('cookbooks/foobar/1.0.0')
+ expect(@knife).to receive(:delete_request).with('cookbooks/foobar/1.0.0')
@knife.delete_explicit_version
end
end
@@ -86,8 +86,8 @@ describe Chef::Knife::CookbookDelete do
describe 'delete_all_versions' do
it 'should prompt to delete all versions of the cookbook' do
@knife.cookbook_name = 'foobar'
- @knife.should_receive(:confirm).with('Do you really want to delete all versions of foobar')
- @knife.should_receive(:delete_all_without_confirmation)
+ expect(@knife).to receive(:confirm).with('Do you really want to delete all versions of foobar')
+ expect(@knife).to receive(:delete_all_without_confirmation)
@knife.delete_all_versions
end
end
@@ -95,9 +95,9 @@ describe Chef::Knife::CookbookDelete do
describe 'delete_all_without_confirmation' do
it 'should delete all versions without confirmation' do
versions = ['1.0.0', '1.1.0']
- @knife.should_receive(:available_versions).and_return(versions)
+ expect(@knife).to receive(:available_versions).and_return(versions)
versions.each do |v|
- @knife.should_receive(:delete_version_without_confirmation).with(v)
+ expect(@knife).to receive(:delete_version_without_confirmation).with(v)
end
@knife.delete_all_without_confirmation
end
@@ -105,20 +105,20 @@ describe Chef::Knife::CookbookDelete do
describe 'delete_without_explicit_version' do
it 'should exit if there are no available versions' do
- @knife.should_receive(:available_versions).and_return(nil)
- lambda { @knife.delete_without_explicit_version }.should raise_error(SystemExit)
+ expect(@knife).to receive(:available_versions).and_return(nil)
+ expect { @knife.delete_without_explicit_version }.to raise_error(SystemExit)
end
it 'should delete the version if only one is found' do
- @knife.should_receive(:available_versions).at_least(:once).and_return(['1.0.0'])
- @knife.should_receive(:delete_explicit_version)
+ expect(@knife).to receive(:available_versions).at_least(:once).and_return(['1.0.0'])
+ expect(@knife).to receive(:delete_explicit_version)
@knife.delete_without_explicit_version
end
it 'should ask which version(s) to delete if multiple are found' do
- @knife.should_receive(:available_versions).at_least(:once).and_return(['1.0.0', '1.1.0'])
- @knife.should_receive(:ask_which_versions_to_delete).and_return(['1.0.0', '1.1.0'])
- @knife.should_receive(:delete_versions_without_confirmation).with(['1.0.0', '1.1.0'])
+ expect(@knife).to receive(:available_versions).at_least(:once).and_return(['1.0.0', '1.1.0'])
+ expect(@knife).to receive(:ask_which_versions_to_delete).and_return(['1.0.0', '1.1.0'])
+ expect(@knife).to receive(:delete_versions_without_confirmation).with(['1.0.0', '1.1.0'])
@knife.delete_without_explicit_version
end
end
@@ -126,7 +126,7 @@ describe Chef::Knife::CookbookDelete do
describe 'available_versions' do
before(:each) do
@rest_mock = double('rest')
- @knife.should_receive(:rest).and_return(@rest_mock)
+ expect(@knife).to receive(:rest).and_return(@rest_mock)
@cookbook_data = { 'foobar' => { 'versions' => [{'version' => '1.0.0'},
{'version' => '1.1.0'},
{'version' => '2.0.0'} ]}
@@ -134,85 +134,85 @@ describe Chef::Knife::CookbookDelete do
end
it 'should return the list of versions of the cookbook' do
- @rest_mock.should_receive(:get_rest).with('cookbooks/foobar').and_return(@cookbook_data)
- @knife.available_versions.should == ['1.0.0', '1.1.0', '2.0.0']
+ expect(@rest_mock).to receive(:get_rest).with('cookbooks/foobar').and_return(@cookbook_data)
+ expect(@knife.available_versions).to eq(['1.0.0', '1.1.0', '2.0.0'])
end
it 'should raise if an error other than HTTP 404 is returned' do
exception = Net::HTTPServerException.new('500 Internal Server Error', '500')
- @rest_mock.should_receive(:get_rest).and_raise(exception)
- lambda { @knife.available_versions }.should raise_error Net::HTTPServerException
+ expect(@rest_mock).to receive(:get_rest).and_raise(exception)
+ expect { @knife.available_versions }.to raise_error Net::HTTPServerException
end
describe "if the cookbook can't be found" do
before(:each) do
- @rest_mock.should_receive(:get_rest).
+ expect(@rest_mock).to receive(:get_rest).
and_raise(Net::HTTPServerException.new('404 Not Found', '404'))
end
it 'should print an error' do
@knife.available_versions
- @stderr.string.should match /error.+cannot find a cookbook named foobar/i
+ expect(@stderr.string).to match /error.+cannot find a cookbook named foobar/i
end
it 'should return nil' do
- @knife.available_versions.should == nil
+ expect(@knife.available_versions).to eq(nil)
end
end
end
describe 'ask_which_version_to_delete' do
before(:each) do
- @knife.stub(:available_versions).and_return(['1.0.0', '1.1.0', '2.0.0'])
+ allow(@knife).to receive(:available_versions).and_return(['1.0.0', '1.1.0', '2.0.0'])
end
it 'should prompt the user to select a version' do
prompt = /Which version\(s\) do you want to delete\?.+1\. foobar 1\.0\.0.+2\. foobar 1\.1\.0.+3\. foobar 2\.0\.0.+4\. All versions.+/m
- @knife.should_receive(:ask_question).with(prompt).and_return('1')
+ expect(@knife).to receive(:ask_question).with(prompt).and_return('1')
@knife.ask_which_versions_to_delete
end
it "should print an error and exit if a version wasn't specified" do
- @knife.should_receive(:ask_question).and_return('')
- @knife.ui.should_receive(:error).with(/no versions specified/i)
- lambda { @knife.ask_which_versions_to_delete }.should raise_error(SystemExit)
+ expect(@knife).to receive(:ask_question).and_return('')
+ expect(@knife.ui).to receive(:error).with(/no versions specified/i)
+ expect { @knife.ask_which_versions_to_delete }.to raise_error(SystemExit)
end
it 'should print an error if an invalid choice was selected' do
- @knife.should_receive(:ask_question).and_return('100')
- @knife.ui.should_receive(:error).with(/100 is not a valid choice/i)
+ expect(@knife).to receive(:ask_question).and_return('100')
+ expect(@knife.ui).to receive(:error).with(/100 is not a valid choice/i)
@knife.ask_which_versions_to_delete
end
it 'should return the selected versions' do
- @knife.should_receive(:ask_question).and_return('1, 3')
- @knife.ask_which_versions_to_delete.should == ['1.0.0', '2.0.0']
+ expect(@knife).to receive(:ask_question).and_return('1, 3')
+ expect(@knife.ask_which_versions_to_delete).to eq(['1.0.0', '2.0.0'])
end
it "should return all of the versions if 'all' was selected" do
- @knife.should_receive(:ask_question).and_return('4')
- @knife.ask_which_versions_to_delete.should == [:all]
+ expect(@knife).to receive(:ask_question).and_return('4')
+ expect(@knife.ask_which_versions_to_delete).to eq([:all])
end
end
describe 'delete_version_without_confirmation' do
it 'should delete the cookbook version' do
- @knife.should_receive(:delete_request).with('cookbooks/foobar/1.0.0')
+ expect(@knife).to receive(:delete_request).with('cookbooks/foobar/1.0.0')
@knife.delete_version_without_confirmation('1.0.0')
end
it 'should output that the cookbook was deleted' do
- @knife.stub(:delete_request)
+ allow(@knife).to receive(:delete_request)
@knife.delete_version_without_confirmation('1.0.0')
- @stderr.string.should match /deleted cookbook\[foobar\]\[1.0.0\]/im
+ expect(@stderr.string).to match /deleted cookbook\[foobar\]\[1.0.0\]/im
end
describe 'with --print-after' do
it 'should display the cookbook data' do
object = ''
@knife.config[:print_after] = true
- @knife.stub(:delete_request).and_return(object)
- @knife.should_receive(:format_for_display).with(object)
+ allow(@knife).to receive(:delete_request).and_return(object)
+ expect(@knife).to receive(:format_for_display).with(object)
@knife.delete_version_without_confirmation('1.0.0')
end
end
@@ -222,7 +222,7 @@ describe Chef::Knife::CookbookDelete do
it 'should delete each version without confirmation' do
versions = ['1.0.0', '1.1.0']
versions.each do |v|
- @knife.should_receive(:delete_version_without_confirmation).with(v)
+ expect(@knife).to receive(:delete_version_without_confirmation).with(v)
end
@knife.delete_versions_without_confirmation(versions)
end
@@ -230,7 +230,7 @@ describe Chef::Knife::CookbookDelete do
describe 'with -a or --all' do
it 'should delete all versions without confirmation' do
versions = [:all]
- @knife.should_receive(:delete_all_without_confirmation)
+ expect(@knife).to receive(:delete_all_without_confirmation)
@knife.delete_versions_without_confirmation(versions)
end
end
diff --git a/spec/unit/knife/cookbook_download_spec.rb b/spec/unit/knife/cookbook_download_spec.rb
index 6f40a3396b..7ca1adfcb5 100644
--- a/spec/unit/knife/cookbook_download_spec.rb
+++ b/spec/unit/knife/cookbook_download_spec.rb
@@ -22,22 +22,22 @@ describe Chef::Knife::CookbookDownload do
before(:each) do
@knife = Chef::Knife::CookbookDownload.new
@stderr = StringIO.new
- @knife.ui.stub(:stderr).and_return(@stderr)
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
end
describe 'run' do
it 'should print usage and exit when a cookbook name is not provided' do
@knife.name_args = []
- @knife.should_receive(:show_usage)
- @knife.ui.should_receive(:fatal).with(/must specify a cookbook name/)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:show_usage)
+ expect(@knife.ui).to receive(:fatal).with(/must specify a cookbook name/)
+ expect { @knife.run }.to raise_error(SystemExit)
end
it 'should exit with a fatal error when there is no cookbook on the server' do
@knife.name_args = ['foobar', nil]
- @knife.should_receive(:determine_version).and_return(nil)
- @knife.ui.should_receive(:fatal).with('No such cookbook found')
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:determine_version).and_return(nil)
+ expect(@knife.ui).to receive(:fatal).with('No such cookbook found')
+ expect { @knife.run }.to raise_error(SystemExit)
end
describe 'with a cookbook name' do
@@ -45,7 +45,7 @@ describe Chef::Knife::CookbookDownload do
@knife.name_args = ['foobar']
@knife.config[:download_directory] = '/var/tmp/chef'
@rest_mock = double('rest')
- @knife.stub(:rest).and_return(@rest_mock)
+ allow(@knife).to receive(:rest).and_return(@rest_mock)
@manifest_data = {
:recipes => [
@@ -67,17 +67,17 @@ describe Chef::Knife::CookbookDownload do
}
@cookbook_mock = double('cookbook')
- @cookbook_mock.stub(:version).and_return('1.0.0')
- @cookbook_mock.stub(:manifest).and_return(@manifest_data)
- @rest_mock.should_receive(:get_rest).with('cookbooks/foobar/1.0.0').
+ allow(@cookbook_mock).to receive(:version).and_return('1.0.0')
+ allow(@cookbook_mock).to receive(:manifest).and_return(@manifest_data)
+ expect(@rest_mock).to receive(:get_rest).with('cookbooks/foobar/1.0.0').
and_return(@cookbook_mock)
end
it 'should determine which version if one was not explicitly specified'do
- @cookbook_mock.stub(:manifest).and_return({})
- @knife.should_receive(:determine_version).and_return('1.0.0')
- File.should_receive(:exists?).with('/var/tmp/chef/foobar-1.0.0').and_return(false)
- Chef::CookbookVersion.stub(:COOKBOOK_SEGEMENTS).and_return([])
+ allow(@cookbook_mock).to receive(:manifest).and_return({})
+ expect(@knife).to receive(:determine_version).and_return('1.0.0')
+ expect(File).to receive(:exists?).with('/var/tmp/chef/foobar-1.0.0').and_return(false)
+ allow(Chef::CookbookVersion).to receive(:COOKBOOK_SEGEMENTS).and_return([])
@knife.run
end
@@ -88,50 +88,50 @@ describe Chef::Knife::CookbookDownload do
@files_mocks = {}
@files.map { |f| File.basename(f) }.flatten.uniq.each do |f|
@files_mocks[f] = double("#{f}_mock")
- @files_mocks[f].stub(:path).and_return("/var/tmp/#{f}")
+ allow(@files_mocks[f]).to receive(:path).and_return("/var/tmp/#{f}")
end
end
it 'should print an error and exit if the cookbook download directory already exists' do
- File.should_receive(:exists?).with('/var/tmp/chef/foobar-1.0.0').and_return(true)
- @knife.ui.should_receive(:fatal).with(/\/var\/tmp\/chef\/foobar-1\.0\.0 exists/i)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(File).to receive(:exists?).with('/var/tmp/chef/foobar-1.0.0').and_return(true)
+ expect(@knife.ui).to receive(:fatal).with(/\/var\/tmp\/chef\/foobar-1\.0\.0 exists/i)
+ expect { @knife.run }.to raise_error(SystemExit)
end
describe 'when downloading the cookbook' do
before(:each) do
@files.map { |f| File.dirname(f) }.flatten.uniq.each do |dir|
- FileUtils.should_receive(:mkdir_p).with("/var/tmp/chef/foobar-1.0.0/#{dir}").
+ expect(FileUtils).to receive(:mkdir_p).with("/var/tmp/chef/foobar-1.0.0/#{dir}").
at_least(:once)
end
@files_mocks.each_pair do |file, mock|
- @rest_mock.should_receive(:get_rest).with("http://example.org/files/#{file}", true).
+ expect(@rest_mock).to receive(:get_rest).with("http://example.org/files/#{file}", true).
and_return(mock)
end
- @rest_mock.should_receive(:sign_on_redirect=).with(false).at_least(:once)
+ expect(@rest_mock).to receive(:sign_on_redirect=).with(false).at_least(:once)
@files.each do |f|
- FileUtils.should_receive(:mv).
+ expect(FileUtils).to receive(:mv).
with("/var/tmp/#{File.basename(f)}", "/var/tmp/chef/foobar-1.0.0/#{f}")
end
end
it "should download the cookbook when the cookbook download directory doesn't exist" do
- File.should_receive(:exists?).with('/var/tmp/chef/foobar-1.0.0').and_return(false)
+ expect(File).to receive(:exists?).with('/var/tmp/chef/foobar-1.0.0').and_return(false)
@knife.run
['attributes', 'recipes', 'templates'].each do |segment|
- @stderr.string.should match /downloading #{segment}/im
+ expect(@stderr.string).to match /downloading #{segment}/im
end
- @stderr.string.should match /downloading foobar cookbook version 1\.0\.0/im
- @stderr.string.should match /cookbook downloaded to \/var\/tmp\/chef\/foobar-1\.0\.0/im
+ expect(@stderr.string).to match /downloading foobar cookbook version 1\.0\.0/im
+ expect(@stderr.string).to match /cookbook downloaded to \/var\/tmp\/chef\/foobar-1\.0\.0/im
end
describe 'with -f or --force' do
it 'should remove the existing the cookbook download directory if it exists' do
@knife.config[:force] = true
- File.should_receive(:exists?).with('/var/tmp/chef/foobar-1.0.0').and_return(true)
- FileUtils.should_receive(:rm_rf).with('/var/tmp/chef/foobar-1.0.0')
+ expect(File).to receive(:exists?).with('/var/tmp/chef/foobar-1.0.0').and_return(true)
+ expect(FileUtils).to receive(:rm_rf).with('/var/tmp/chef/foobar-1.0.0')
@knife.run
end
end
@@ -145,30 +145,30 @@ describe Chef::Knife::CookbookDownload do
describe 'determine_version' do
it 'should return nil if there are no versions' do
- @knife.should_receive(:available_versions).and_return(nil)
- @knife.determine_version.should == nil
- @knife.version.should == nil
+ expect(@knife).to receive(:available_versions).and_return(nil)
+ expect(@knife.determine_version).to eq(nil)
+ expect(@knife.version).to eq(nil)
end
it 'should return and set the version if there is only one version' do
- @knife.should_receive(:available_versions).at_least(:once).and_return(['1.0.0'])
- @knife.determine_version.should == '1.0.0'
- @knife.version.should == '1.0.0'
+ expect(@knife).to receive(:available_versions).at_least(:once).and_return(['1.0.0'])
+ expect(@knife.determine_version).to eq('1.0.0')
+ expect(@knife.version).to eq('1.0.0')
end
it 'should ask which version to download and return it if there is more than one' do
- @knife.should_receive(:available_versions).at_least(:once).and_return(['1.0.0', '2.0.0'])
- @knife.should_receive(:ask_which_version).and_return('1.0.0')
- @knife.determine_version.should == '1.0.0'
+ expect(@knife).to receive(:available_versions).at_least(:once).and_return(['1.0.0', '2.0.0'])
+ expect(@knife).to receive(:ask_which_version).and_return('1.0.0')
+ expect(@knife.determine_version).to eq('1.0.0')
end
describe 'with -N or --latest' do
it 'should return and set the version to the latest version' do
@knife.config[:latest] = true
- @knife.should_receive(:available_versions).at_least(:once).
+ expect(@knife).to receive(:available_versions).at_least(:once).
and_return(['1.0.0', '1.1.0', '2.0.0'])
@knife.determine_version
- @knife.version.to_s.should == '2.0.0'
+ expect(@knife.version.to_s).to eq('2.0.0')
end
end
end
@@ -179,23 +179,23 @@ describe Chef::Knife::CookbookDownload do
end
it 'should return nil if there are no versions' do
- Chef::CookbookVersion.should_receive(:available_versions).
+ expect(Chef::CookbookVersion).to receive(:available_versions).
with('foobar').
and_return(nil)
- @knife.available_versions.should == nil
+ expect(@knife.available_versions).to eq(nil)
end
it 'should return the available versions' do
- Chef::CookbookVersion.should_receive(:available_versions).
+ expect(Chef::CookbookVersion).to receive(:available_versions).
with('foobar').
and_return(['1.1.0', '2.0.0', '1.0.0'])
- @knife.available_versions.should == [Chef::Version.new('1.0.0'),
+ expect(@knife.available_versions).to eq([Chef::Version.new('1.0.0'),
Chef::Version.new('1.1.0'),
- Chef::Version.new('2.0.0')]
+ Chef::Version.new('2.0.0')])
end
it 'should avoid multiple API calls to the server' do
- Chef::CookbookVersion.should_receive(:available_versions).
+ expect(Chef::CookbookVersion).to receive(:available_versions).
once.
with('foobar').
and_return(['1.1.0', '2.0.0', '1.0.0'])
@@ -207,31 +207,31 @@ describe Chef::Knife::CookbookDownload do
describe 'ask_which_version' do
before(:each) do
@knife.cookbook_name = 'foobar'
- @knife.stub(:available_versions).and_return(['1.0.0', '1.1.0', '2.0.0'])
+ allow(@knife).to receive(:available_versions).and_return(['1.0.0', '1.1.0', '2.0.0'])
end
it 'should prompt the user to select a version' do
prompt = /Which version do you want to download\?.+1\. foobar 1\.0\.0.+2\. foobar 1\.1\.0.+3\. foobar 2\.0\.0.+/m
- @knife.should_receive(:ask_question).with(prompt).and_return('1')
+ expect(@knife).to receive(:ask_question).with(prompt).and_return('1')
@knife.ask_which_version
end
it "should set the version to the user's selection" do
- @knife.should_receive(:ask_question).and_return('1')
+ expect(@knife).to receive(:ask_question).and_return('1')
@knife.ask_which_version
- @knife.version.should == '1.0.0'
+ expect(@knife.version).to eq('1.0.0')
end
it "should print an error and exit if a version wasn't specified" do
- @knife.should_receive(:ask_question).and_return('')
- @knife.ui.should_receive(:error).with(/is not a valid value/i)
- lambda { @knife.ask_which_version }.should raise_error(SystemExit)
+ expect(@knife).to receive(:ask_question).and_return('')
+ expect(@knife.ui).to receive(:error).with(/is not a valid value/i)
+ expect { @knife.ask_which_version }.to raise_error(SystemExit)
end
it 'should print an error if an invalid choice was selected' do
- @knife.should_receive(:ask_question).and_return('100')
- @knife.ui.should_receive(:error).with(/'100' is not a valid value/i)
- lambda { @knife.ask_which_version }.should raise_error(SystemExit)
+ expect(@knife).to receive(:ask_question).and_return('100')
+ expect(@knife.ui).to receive(:error).with(/'100' is not a valid value/i)
+ expect { @knife.ask_which_version }.to raise_error(SystemExit)
end
end
diff --git a/spec/unit/knife/cookbook_list_spec.rb b/spec/unit/knife/cookbook_list_spec.rb
index 9ff16edb37..559f700bb4 100644
--- a/spec/unit/knife/cookbook_list_spec.rb
+++ b/spec/unit/knife/cookbook_list_spec.rb
@@ -22,7 +22,7 @@ describe Chef::Knife::CookbookList do
before do
@knife = Chef::Knife::CookbookList.new
@rest_mock = double('rest')
- @knife.stub(:rest).and_return(@rest_mock)
+ allow(@knife).to receive(:rest).and_return(@rest_mock)
@cookbook_names = ['apache2', 'mysql']
@base_url = 'https://server.example.com/cookbooks'
@cookbook_data = {}
@@ -32,22 +32,22 @@ describe Chef::Knife::CookbookList do
'url' => "#{@base_url}/#{item}/1.0.1"}]}
end
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
describe 'run' do
it 'should display the latest version of the cookbooks' do
- @rest_mock.should_receive(:get_rest).with('/cookbooks?num_versions=1').
+ expect(@rest_mock).to receive(:get_rest).with('/cookbooks?num_versions=1').
and_return(@cookbook_data)
@knife.run
@cookbook_names.each do |item|
- @stdout.string.should match /#{item}\s+1\.0\.1/
+ expect(@stdout.string).to match /#{item}\s+1\.0\.1/
end
end
it 'should query cookbooks for the configured environment' do
@knife.config[:environment] = 'production'
- @rest_mock.should_receive(:get_rest).
+ expect(@rest_mock).to receive(:get_rest).
with('/environments/production/cookbooks?num_versions=1').
and_return(@cookbook_data)
@knife.run
@@ -56,11 +56,11 @@ describe Chef::Knife::CookbookList do
describe 'with -w or --with-uri' do
it 'should display the cookbook uris' do
@knife.config[:with_uri] = true
- @rest_mock.stub(:get_rest).and_return(@cookbook_data)
+ allow(@rest_mock).to receive(:get_rest).and_return(@cookbook_data)
@knife.run
@cookbook_names.each do |item|
pattern = /#{Regexp.escape(@cookbook_data[item]['versions'].first['url'])}/
- @stdout.string.should match pattern
+ expect(@stdout.string).to match pattern
end
end
end
@@ -75,11 +75,11 @@ describe Chef::Knife::CookbookList do
it 'should display all versions of the cookbooks' do
@knife.config[:all_versions] = true
- @rest_mock.should_receive(:get_rest).with('/cookbooks?num_versions=all').
+ expect(@rest_mock).to receive(:get_rest).with('/cookbooks?num_versions=all').
and_return(@cookbook_data)
@knife.run
@cookbook_names.each do |item|
- @stdout.string.should match /#{item}\s+1\.0\.1\s+1\.0\.0/
+ expect(@stdout.string).to match /#{item}\s+1\.0\.1\s+1\.0\.0/
end
end
end
diff --git a/spec/unit/knife/cookbook_metadata_from_file_spec.rb b/spec/unit/knife/cookbook_metadata_from_file_spec.rb
index 68ab6740ab..456e378ca2 100644
--- a/spec/unit/knife/cookbook_metadata_from_file_spec.rb
+++ b/spec/unit/knife/cookbook_metadata_from_file_spec.rb
@@ -27,10 +27,10 @@ describe Chef::Knife::CookbookMetadataFromFile do
@tgt = File.expand_path(File.join(CHEF_SPEC_DATA, "metadata", "quick_start", "metadata.json"))
@knife = Chef::Knife::CookbookMetadataFromFile.new
@knife.name_args = [ @src ]
- @knife.stub(:to_json_pretty).and_return(true)
+ allow(@knife).to receive(:to_json_pretty).and_return(true)
@md = Chef::Cookbook::Metadata.new
- Chef::Cookbook::Metadata.stub(:new).and_return(@md)
- $stdout.stub(:write)
+ allow(Chef::Cookbook::Metadata).to receive(:new).and_return(@md)
+ allow($stdout).to receive(:write)
end
after do
@@ -41,23 +41,23 @@ describe Chef::Knife::CookbookMetadataFromFile do
describe "run" do
it "should determine cookbook name from path" do
- @md.should_receive(:name).with()
- @md.should_receive(:name).with("quick_start")
+ expect(@md).to receive(:name).with(no_args)
+ expect(@md).to receive(:name).with("quick_start")
@knife.run
end
it "should load the metadata source" do
- @md.should_receive(:from_file).with(@src)
+ expect(@md).to receive(:from_file).with(@src)
@knife.run
end
it "should write out the metadata to the correct location" do
- File.should_receive(:open).with(@tgt, "w")
+ expect(File).to receive(:open).with(@tgt, "w")
@knife.run
end
it "should generate json from the metadata" do
- Chef::JSONCompat.should_receive(:to_json_pretty).with(@md)
+ expect(Chef::JSONCompat).to receive(:to_json_pretty).with(@md)
@knife.run
end
diff --git a/spec/unit/knife/cookbook_metadata_spec.rb b/spec/unit/knife/cookbook_metadata_spec.rb
index 1d6568739c..861d85f1f7 100644
--- a/spec/unit/knife/cookbook_metadata_spec.rb
+++ b/spec/unit/knife/cookbook_metadata_spec.rb
@@ -26,25 +26,25 @@ describe Chef::Knife::CookbookMetadata do
@json_data = '{ "version": "1.0.0" }'
@stdout = StringIO.new
@stderr = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
- @knife.ui.stub(:stderr).and_return(@stderr)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
end
describe 'run' do
it 'should print an error and exit if a cookbook name was not provided' do
@knife.name_args = []
- @knife.ui.should_receive(:error).with(/you must specify the cookbook.+use the --all/i)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife.ui).to receive(:error).with(/you must specify the cookbook.+use the --all/i)
+ expect { @knife.run }.to raise_error(SystemExit)
end
it 'should print an error and exit if an empty cookbook name was provided' do
@knife.name_args = ['']
- @knife.ui.should_receive(:error).with(/you must specify the cookbook.+use the --all/i)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife.ui).to receive(:error).with(/you must specify the cookbook.+use the --all/i)
+ expect { @knife.run }.to raise_error(SystemExit)
end
it 'should generate the metadata for the cookbook' do
- @knife.should_receive(:generate_metadata).with('foobar')
+ expect(@knife).to receive(:generate_metadata).with('foobar')
@knife.run
end
@@ -59,21 +59,21 @@ describe Chef::Knife::CookbookMetadata do
"foo" => @foo,
"bar" => @bar
}
- @cookbook_loader.should_receive(:load_cookbooks).and_return(@cookbook_loader)
- @knife.should_receive(:generate_metadata).with('foo')
- @knife.should_receive(:generate_metadata).with('bar')
+ expect(@cookbook_loader).to receive(:load_cookbooks).and_return(@cookbook_loader)
+ expect(@knife).to receive(:generate_metadata).with('foo')
+ expect(@knife).to receive(:generate_metadata).with('bar')
end
it 'should generate the metadata for each cookbook' do
Chef::Config[:cookbook_path] = @cookbook_dir
- Chef::CookbookLoader.should_receive(:new).with(@cookbook_dir).and_return(@cookbook_loader)
+ expect(Chef::CookbookLoader).to receive(:new).with(@cookbook_dir).and_return(@cookbook_loader)
@knife.run
end
describe 'and with -o or --cookbook-path' do
it 'should look in the provided path and generate cookbook metadata' do
@knife.config[:cookbook_path] = '/opt/chef/cookbooks'
- Chef::CookbookLoader.should_receive(:new).with('/opt/chef/cookbooks').and_return(@cookbook_loader)
+ expect(Chef::CookbookLoader).to receive(:new).with('/opt/chef/cookbooks').and_return(@cookbook_loader)
@knife.run
end
end
@@ -84,21 +84,21 @@ describe Chef::Knife::CookbookMetadata do
describe 'generate_metadata' do
before(:each) do
@knife.config[:cookbook_path] = @cookbook_dir
- File.stub(:expand_path).with("#{@cookbook_dir}/foobar/metadata.rb").
+ allow(File).to receive(:expand_path).with("#{@cookbook_dir}/foobar/metadata.rb").
and_return("#{@cookbook_dir}/foobar/metadata.rb")
end
it 'should generate the metadata from metadata.rb if it exists' do
- File.should_receive(:exists?).with("#{@cookbook_dir}/foobar/metadata.rb").
+ expect(File).to receive(:exists?).with("#{@cookbook_dir}/foobar/metadata.rb").
and_return(true)
- @knife.should_receive(:generate_metadata_from_file).with('foobar', "#{@cookbook_dir}/foobar/metadata.rb")
+ expect(@knife).to receive(:generate_metadata_from_file).with('foobar', "#{@cookbook_dir}/foobar/metadata.rb")
@knife.run
end
it 'should validate the metadata json if metadata.rb does not exist' do
- File.should_receive(:exists?).with("#{@cookbook_dir}/foobar/metadata.rb").
+ expect(File).to receive(:exists?).with("#{@cookbook_dir}/foobar/metadata.rb").
and_return(false)
- @knife.should_receive(:validate_metadata_json).with(@cookbook_dir, 'foobar')
+ expect(@knife).to receive(:validate_metadata_json).with(@cookbook_dir, 'foobar')
@knife.run
end
end
@@ -110,16 +110,16 @@ describe Chef::Knife::CookbookMetadata do
end
it 'should generate the metatdata json from metatdata.rb' do
- Chef::Cookbook::Metadata.stub(:new).and_return(@metadata_mock)
- @metadata_mock.should_receive(:name).with('foobar')
- @metadata_mock.should_receive(:from_file).with("#{@cookbook_dir}/foobar/metadata.rb")
- File.should_receive(:open).with("#{@cookbook_dir}/foobar/metadata.json", 'w').
+ allow(Chef::Cookbook::Metadata).to receive(:new).and_return(@metadata_mock)
+ expect(@metadata_mock).to receive(:name).with('foobar')
+ expect(@metadata_mock).to receive(:from_file).with("#{@cookbook_dir}/foobar/metadata.rb")
+ expect(File).to receive(:open).with("#{@cookbook_dir}/foobar/metadata.json", 'w').
and_yield(@json_file_mock)
- @json_file_mock.should_receive(:write).with(@json_data)
- Chef::JSONCompat.should_receive(:to_json_pretty).with(@metadata_mock).
+ expect(@json_file_mock).to receive(:write).with(@json_data)
+ expect(Chef::JSONCompat).to receive(:to_json_pretty).with(@metadata_mock).
and_return(@json_data)
@knife.generate_metadata_from_file('foobar', "#{@cookbook_dir}/foobar/metadata.rb")
- @stderr.string.should match /generating metadata for foobar from #{@cookbook_dir}\/foobar\/metadata\.rb/im
+ expect(@stderr.string).to match /generating metadata for foobar from #{@cookbook_dir}\/foobar\/metadata\.rb/im
end
{ Chef::Exceptions::ObsoleteDependencySyntax => 'obsolote dependency',
@@ -127,32 +127,32 @@ describe Chef::Knife::CookbookMetadata do
}.each_pair do |klass, description|
it "should print an error and exit when an #{description} syntax exception is encountered" do
exception = klass.new("#{description} blah")
- Chef::Cookbook::Metadata.stub(:new).and_raise(exception)
- lambda {
+ allow(Chef::Cookbook::Metadata).to receive(:new).and_raise(exception)
+ expect {
@knife.generate_metadata_from_file('foobar', "#{@cookbook_dir}/foobar/metadata.rb")
- }.should raise_error(SystemExit)
- @stderr.string.should match /error: the cookbook 'foobar' contains invalid or obsolete metadata syntax/im
- @stderr.string.should match /in #{@cookbook_dir}\/foobar\/metadata\.rb/im
- @stderr.string.should match /#{description} blah/im
+ }.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
end
end
end
describe 'validate_metadata_json' do
it 'should validate the metadata json' do
- File.should_receive(:exist?).with("#{@cookbook_dir}/foobar/metadata.json").
+ expect(File).to receive(:exist?).with("#{@cookbook_dir}/foobar/metadata.json").
and_return(true)
- IO.should_receive(:read).with("#{@cookbook_dir}/foobar/metadata.json").
+ expect(IO).to receive(:read).with("#{@cookbook_dir}/foobar/metadata.json").
and_return(@json_data)
- Chef::Cookbook::Metadata.should_receive(:validate_json).with(@json_data)
+ expect(Chef::Cookbook::Metadata).to receive(:validate_json).with(@json_data)
@knife.validate_metadata_json(@cookbook_dir, 'foobar')
end
it 'should not try to validate the metadata json if the file does not exist' do
- File.should_receive(:exist?).with("#{@cookbook_dir}/foobar/metadata.json").
+ expect(File).to receive(:exist?).with("#{@cookbook_dir}/foobar/metadata.json").
and_return(false)
- IO.should_not_receive(:read)
- Chef::Cookbook::Metadata.should_not_receive(:validate_json)
+ expect(IO).not_to receive(:read)
+ expect(Chef::Cookbook::Metadata).not_to receive(:validate_json)
@knife.validate_metadata_json(@cookbook_dir, 'foobar')
end
@@ -160,18 +160,18 @@ describe Chef::Knife::CookbookMetadata do
Chef::Exceptions::InvalidVersionConstraint => 'invalid version constraint'
}.each_pair do |klass, description|
it "should print an error and exit when an #{description} syntax exception is encountered" do
- File.should_receive(:exist?).with("#{@cookbook_dir}/foobar/metadata.json").
+ expect(File).to receive(:exist?).with("#{@cookbook_dir}/foobar/metadata.json").
and_return(true)
- IO.should_receive(:read).with("#{@cookbook_dir}/foobar/metadata.json").
+ expect(IO).to receive(:read).with("#{@cookbook_dir}/foobar/metadata.json").
and_return(@json_data)
exception = klass.new("#{description} blah")
- Chef::Cookbook::Metadata.stub(:validate_json).and_raise(exception)
- lambda {
+ allow(Chef::Cookbook::Metadata).to receive(:validate_json).and_raise(exception)
+ expect {
@knife.validate_metadata_json(@cookbook_dir, 'foobar')
- }.should raise_error(SystemExit)
- @stderr.string.should match /error: the cookbook 'foobar' contains invalid or obsolete metadata syntax/im
- @stderr.string.should match /in #{@cookbook_dir}\/foobar\/metadata\.json/im
- @stderr.string.should match /#{description} blah/im
+ }.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
end
end
end
diff --git a/spec/unit/knife/cookbook_show_spec.rb b/spec/unit/knife/cookbook_show_spec.rb
index b862c3154c..bf480e3678 100644
--- a/spec/unit/knife/cookbook_show_spec.rb
+++ b/spec/unit/knife/cookbook_show_spec.rb
@@ -26,18 +26,18 @@ describe Chef::Knife::CookbookShow do
@knife.config = { }
@knife.name_args = [ "cookbook_name" ]
@rest = double(Chef::REST)
- @knife.stub(:rest).and_return(@rest)
- @knife.stub(:pretty_print).and_return(true)
- @knife.stub(:output).and_return(true)
+ allow(@knife).to receive(:rest).and_return(@rest)
+ allow(@knife).to receive(:pretty_print).and_return(true)
+ allow(@knife).to receive(:output).and_return(true)
end
describe "run" do
describe "with 0 arguments: help" do
it 'should should print usage and exit when given no arguments' do
@knife.name_args = []
- @knife.should_receive(:show_usage)
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:show_usage)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
@@ -56,15 +56,15 @@ describe Chef::Knife::CookbookShow do
end
it "should show the raw cookbook data" do
- @rest.should_receive(:get_rest).with("cookbooks/cookbook_name").and_return(@response)
- @knife.should_receive(:format_cookbook_list_for_display).with(@response)
+ expect(@rest).to receive(:get_rest).with("cookbooks/cookbook_name").and_return(@response)
+ expect(@knife).to receive(:format_cookbook_list_for_display).with(@response)
@knife.run
end
it "should respect the user-supplied environment" do
@knife.config[:environment] = "foo"
- @rest.should_receive(:get_rest).with("environments/foo/cookbooks/cookbook_name").and_return(@response)
- @knife.should_receive(:format_cookbook_list_for_display).with(@response)
+ expect(@rest).to receive(:get_rest).with("environments/foo/cookbooks/cookbook_name").and_return(@response)
+ expect(@knife).to receive(:format_cookbook_list_for_display).with(@response)
@knife.run
end
end
@@ -76,8 +76,8 @@ describe Chef::Knife::CookbookShow do
end
it "should show the specific part of a cookbook" do
- @rest.should_receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@response)
- @knife.should_receive(:output).with(@response)
+ expect(@rest).to receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@response)
+ expect(@knife).to receive(:output).with(@response)
@knife.run
end
end
@@ -101,8 +101,8 @@ describe Chef::Knife::CookbookShow do
end
it "should print the json of the part" do
- @rest.should_receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response)
- @knife.should_receive(:output).with(@cookbook_response.manifest["recipes"])
+ expect(@rest).to receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response)
+ expect(@knife).to receive(:output).with(@cookbook_response.manifest["recipes"])
@knife.run
end
end
@@ -125,9 +125,9 @@ describe Chef::Knife::CookbookShow do
end
it "should print the raw result of the request (likely a file!)" do
- @rest.should_receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response)
- @rest.should_receive(:get_rest).with("http://example.org/files/default.rb", true).and_return(StringIO.new(@response))
- @knife.should_receive(:pretty_print).with(@response)
+ expect(@rest).to receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response)
+ expect(@rest).to receive(:get_rest).with("http://example.org/files/default.rb", true).and_return(StringIO.new(@response))
+ expect(@knife).to receive(:pretty_print).with(@response)
@knife.run
end
end
@@ -177,9 +177,9 @@ describe Chef::Knife::CookbookShow do
@knife.config[:platform] = "example_platform"
@knife.config[:platform_version] = "1.0"
@knife.config[:fqdn] = "examplehost.example.org"
- @rest.should_receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response)
- @rest.should_receive(:get_rest).with("http://example.org/files/1111", true).and_return(StringIO.new(@response))
- @knife.should_receive(:pretty_print).with(@response)
+ expect(@rest).to receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response)
+ expect(@rest).to receive(:get_rest).with("http://example.org/files/1111", true).and_return(StringIO.new(@response))
+ expect(@knife).to receive(:pretty_print).with(@response)
@knife.run
end
end
@@ -189,9 +189,9 @@ describe Chef::Knife::CookbookShow do
@knife.config[:platform] = "ubuntu"
@knife.config[:platform_version] = "1.0"
@knife.config[:fqdn] = "differenthost.example.org"
- @rest.should_receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response)
- @rest.should_receive(:get_rest).with("http://example.org/files/3333", true).and_return(StringIO.new(@response))
- @knife.should_receive(:pretty_print).with(@response)
+ expect(@rest).to receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response)
+ expect(@rest).to receive(:get_rest).with("http://example.org/files/3333", true).and_return(StringIO.new(@response))
+ expect(@knife).to receive(:pretty_print).with(@response)
@knife.run
end
end
@@ -201,18 +201,18 @@ describe Chef::Knife::CookbookShow do
@knife.config[:platform] = "ubuntu"
@knife.config[:platform_version] = "9.10"
@knife.config[:fqdn] = "differenthost.example.org"
- @rest.should_receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response)
- @rest.should_receive(:get_rest).with("http://example.org/files/2222", true).and_return(StringIO.new(@response))
- @knife.should_receive(:pretty_print).with(@response)
+ expect(@rest).to receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response)
+ expect(@rest).to receive(:get_rest).with("http://example.org/files/2222", true).and_return(StringIO.new(@response))
+ expect(@knife).to receive(:pretty_print).with(@response)
@knife.run
end
end
describe "with none of the arguments, it should use the default" do
it "should pass them all" do
- @rest.should_receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response)
- @rest.should_receive(:get_rest).with("http://example.org/files/4444", true).and_return(StringIO.new(@response))
- @knife.should_receive(:pretty_print).with(@response)
+ expect(@rest).to receive(:get_rest).with("cookbooks/cookbook_name/0.1.0").and_return(@cookbook_response)
+ expect(@rest).to receive(:get_rest).with("http://example.org/files/4444", true).and_return(StringIO.new(@response))
+ expect(@knife).to receive(:pretty_print).with(@response)
@knife.run
end
end
diff --git a/spec/unit/knife/cookbook_site_download_spec.rb b/spec/unit/knife/cookbook_site_download_spec.rb
index 76ce6508d7..fdf4c2197b 100644
--- a/spec/unit/knife/cookbook_site_download_spec.rb
+++ b/spec/unit/knife/cookbook_site_download_spec.rb
@@ -26,16 +26,16 @@ describe Chef::Knife::CookbookSiteDownload do
@knife.name_args = ['apache2']
@noauth_rest = double('no auth rest')
@stderr = StringIO.new
- @cookbook_api_url = 'https://supermarket.getchef.com/api/v1/cookbooks'
+ @cookbook_api_url = 'https://supermarket.chef.io/api/v1/cookbooks'
@version = '1.0.2'
@version_us = @version.gsub '.', '_'
@current_data = { 'deprecated' => false,
'latest_version' => "#{@cookbook_api_url}/apache2/versions/#{@version_us}",
'replacement' => 'other_apache2' }
- @knife.ui.stub(:stderr).and_return(@stderr)
- @knife.stub(:noauth_rest).and_return(@noauth_rest)
- @noauth_rest.should_receive(:get_rest).
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
+ allow(@knife).to receive(:noauth_rest).and_return(@noauth_rest)
+ expect(@noauth_rest).to receive(:get_rest).
with("#{@cookbook_api_url}/apache2").
and_return(@current_data)
end
@@ -46,9 +46,9 @@ describe Chef::Knife::CookbookSiteDownload do
end
it 'should warn with info about the replacement' do
- @knife.ui.should_receive(:warn).
+ expect(@knife.ui).to receive(:warn).
with(/.+deprecated.+replaced by other_apache2.+/i)
- @knife.ui.should_receive(:warn).
+ expect(@knife.ui).to receive(:warn).
with(/use --force.+download.+/i)
@knife.run
end
@@ -61,15 +61,15 @@ describe Chef::Knife::CookbookSiteDownload do
@temp_file = double( :path => "/tmp/apache2_#{@version_us}.tgz" )
@file = File.join(Dir.pwd, "apache2-#{@version}.tar.gz")
- @noauth_rest.should_receive(:sign_on_redirect=).with(false)
+ expect(@noauth_rest).to receive(:sign_on_redirect=).with(false)
end
context 'downloading the latest version' do
before do
- @noauth_rest.should_receive(:get_rest).
+ expect(@noauth_rest).to receive(:get_rest).
with(@current_data['latest_version']).
and_return(@cookbook_data)
- @noauth_rest.should_receive(:get_rest).
+ expect(@noauth_rest).to receive(:get_rest).
with(@cookbook_data['file'], true).
and_return(@temp_file)
end
@@ -81,40 +81,40 @@ describe Chef::Knife::CookbookSiteDownload do
end
it 'should download the latest version' do
- @knife.ui.should_receive(:warn).
+ expect(@knife.ui).to receive(:warn).
with(/.+deprecated.+replaced by other_apache2.+/i)
- FileUtils.should_receive(:cp).with(@temp_file.path, @file)
+ expect(FileUtils).to receive(:cp).with(@temp_file.path, @file)
@knife.run
- @stderr.string.should match /downloading apache2.+version.+#{Regexp.escape(@version)}/i
- @stderr.string.should match /cookbook save.+#{Regexp.escape(@file)}/i
+ expect(@stderr.string).to match /downloading apache2.+version.+#{Regexp.escape(@version)}/i
+ expect(@stderr.string).to match /cookbook save.+#{Regexp.escape(@file)}/i
end
end
it 'should download the latest version' do
- FileUtils.should_receive(:cp).with(@temp_file.path, @file)
+ expect(FileUtils).to receive(:cp).with(@temp_file.path, @file)
@knife.run
- @stderr.string.should match /downloading apache2.+version.+#{Regexp.escape(@version)}/i
- @stderr.string.should match /cookbook save.+#{Regexp.escape(@file)}/i
+ expect(@stderr.string).to match /downloading apache2.+version.+#{Regexp.escape(@version)}/i
+ expect(@stderr.string).to match /cookbook save.+#{Regexp.escape(@file)}/i
end
context 'with -f or --file' do
before do
@file = '/opt/chef/cookbooks/apache2.tar.gz'
@knife.config[:file] = @file
- FileUtils.should_receive(:cp).with(@temp_file.path, @file)
+ expect(FileUtils).to receive(:cp).with(@temp_file.path, @file)
end
it 'should download the cookbook to the desired file' do
@knife.run
- @stderr.string.should match /downloading apache2.+version.+#{Regexp.escape(@version)}/i
- @stderr.string.should match /cookbook save.+#{Regexp.escape(@file)}/i
+ expect(@stderr.string).to match /downloading apache2.+version.+#{Regexp.escape(@version)}/i
+ expect(@stderr.string).to match /cookbook save.+#{Regexp.escape(@file)}/i
end
end
it 'should provide an accessor to the version' do
- FileUtils.stub(:cp).and_return(true)
- @knife.version.should == @version
+ allow(FileUtils).to receive(:cp).and_return(true)
+ expect(@knife.version).to eq(@version)
@knife.run
end
end
@@ -131,16 +131,16 @@ describe Chef::Knife::CookbookSiteDownload do
end
it 'should download the desired version' do
- @noauth_rest.should_receive(:get_rest).
+ expect(@noauth_rest).to receive(:get_rest).
with("#{@cookbook_api_url}/apache2/versions/#{@version_us}").
and_return(@cookbook_data)
- @noauth_rest.should_receive(:get_rest).
+ expect(@noauth_rest).to receive(:get_rest).
with(@cookbook_data['file'], true).
and_return(@temp_file)
- FileUtils.should_receive(:cp).with(@temp_file.path, @file)
+ expect(FileUtils).to receive(:cp).with(@temp_file.path, @file)
@knife.run
- @stderr.string.should match /downloading apache2.+version.+#{Regexp.escape(@version)}/i
- @stderr.string.should match /cookbook save.+#{Regexp.escape(@file)}/i
+ expect(@stderr.string).to match /downloading apache2.+version.+#{Regexp.escape(@version)}/i
+ expect(@stderr.string).to match /cookbook save.+#{Regexp.escape(@file)}/i
end
end
diff --git a/spec/unit/knife/cookbook_site_share_spec.rb b/spec/unit/knife/cookbook_site_share_spec.rb
index b85db98d53..f7207dd175 100644
--- a/spec/unit/knife/cookbook_site_share_spec.rb
+++ b/spec/unit/knife/cookbook_site_share_spec.rb
@@ -32,27 +32,27 @@ describe Chef::Knife::CookbookSiteShare do
@cookbook = Chef::CookbookVersion.new('cookbook_name')
@cookbook_loader = double('Chef::CookbookLoader')
- @cookbook_loader.stub(:cookbook_exists?).and_return(true)
- @cookbook_loader.stub(:[]).and_return(@cookbook)
- Chef::CookbookLoader.stub(:new).and_return(@cookbook_loader)
+ allow(@cookbook_loader).to receive(:cookbook_exists?).and_return(true)
+ allow(@cookbook_loader).to receive(:[]).and_return(@cookbook)
+ allow(Chef::CookbookLoader).to receive(:new).and_return(@cookbook_loader)
@noauth_rest = double(Chef::REST)
- @knife.stub(:noauth_rest).and_return(@noauth_rest)
+ allow(@knife).to receive(:noauth_rest).and_return(@noauth_rest)
@cookbook_uploader = Chef::CookbookUploader.new('herpderp', :rest => "norest")
- Chef::CookbookUploader.stub(:new).and_return(@cookbook_uploader)
- @cookbook_uploader.stub(:validate_cookbooks).and_return(true)
- Chef::CookbookSiteStreamingUploader.stub(:create_build_dir).and_return(Dir.mktmpdir)
+ allow(Chef::CookbookUploader).to receive(:new).and_return(@cookbook_uploader)
+ allow(@cookbook_uploader).to receive(:validate_cookbooks).and_return(true)
+ allow(Chef::CookbookSiteStreamingUploader).to receive(:create_build_dir).and_return(Dir.mktmpdir)
- @knife.stub(:shell_out!).and_return(true)
+ allow(@knife).to receive(:shell_out!).and_return(true)
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
describe 'run' do
before(:each) do
- @knife.stub(:do_upload).and_return(true)
+ allow(@knife).to receive(:do_upload).and_return(true)
@category_response = {
"name" => "cookbook_name",
"category" => "Testing Category"
@@ -66,72 +66,81 @@ describe Chef::Knife::CookbookSiteShare do
end
it 'should set true to config[:dry_run] as default' do
- @knife.config[:dry_run].should be_false
+ expect(@knife.config[:dry_run]).to be_falsey
end
it 'should should print usage and exit when given no arguments' do
@knife.name_args = []
- @knife.should_receive(:show_usage)
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:show_usage)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
it 'should not fail when given only 1 argument and can determine category' do
@knife.name_args = ['cookbook_name']
- @noauth_rest.should_receive(:get_rest).with("http://cookbooks.opscode.com/api/v1/cookbooks/cookbook_name").and_return(@category_response)
- @knife.should_receive(:do_upload)
+ expect(@noauth_rest).to receive(:get_rest).with("http://cookbooks.opscode.com/api/v1/cookbooks/cookbook_name").and_return(@category_response)
+ expect(@knife).to receive(:do_upload)
@knife.run
end
it 'should print error and exit when given only 1 argument and cannot determine category' do
@knife.name_args = ['cookbook_name']
- @noauth_rest.should_receive(:get_rest).with("http://cookbooks.opscode.com/api/v1/cookbooks/cookbook_name").and_return(@bad_category_response)
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@noauth_rest).to receive(:get_rest).with("http://cookbooks.opscode.com/api/v1/cookbooks/cookbook_name").and_return(@bad_category_response)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
it 'should print error and exit when given only 1 argument and Chef::REST throws an exception' do
@knife.name_args = ['cookbook_name']
- @noauth_rest.should_receive(:get_rest).with("http://cookbooks.opscode.com/api/v1/cookbooks/cookbook_name") { raise Errno::ECONNREFUSED, "Connection refused" }
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@noauth_rest).to receive(:get_rest).with("http://cookbooks.opscode.com/api/v1/cookbooks/cookbook_name") { raise Errno::ECONNREFUSED, "Connection refused" }
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
it 'should check if the cookbook exists' do
- @cookbook_loader.should_receive(:cookbook_exists?)
+ expect(@cookbook_loader).to receive(:cookbook_exists?)
@knife.run
end
it "should exit and log to error if the cookbook doesn't exist" do
- @cookbook_loader.stub(:cookbook_exists?).and_return(false)
- @knife.ui.should_receive(:error)
- lambda { @knife.run }.should raise_error(SystemExit)
+ allow(@cookbook_loader).to receive(:cookbook_exists?).and_return(false)
+ expect(@knife.ui).to receive(:error)
+ expect { @knife.run }.to raise_error(SystemExit)
end
- it 'should make a tarball of the cookbook' do
- @knife.should_receive(:shell_out!) do |args|
- args.to_s.should match(/tar -czf/)
+ if File.exists?('/usr/bin/gnutar') || File.exists?('/bin/gnutar')
+ it 'should use gnutar to make a tarball of the cookbook' do
+ expect(@knife).to receive(:shell_out!) do |args|
+ expect(args.to_s).to match(/gnutar -czf/)
+ end
+ @knife.run
+ end
+ else
+ it 'should make a tarball of the cookbook' do
+ expect(@knife).to receive(:shell_out!) do |args|
+ expect(args.to_s).to match(/tar -czf/)
+ end
+ @knife.run
end
- @knife.run
end
it 'should exit and log to error when the tarball creation fails' do
- @knife.stub(:shell_out!).and_raise(Chef::Exceptions::Exec)
- @knife.ui.should_receive(:error)
- lambda { @knife.run }.should raise_error(SystemExit)
+ allow(@knife).to receive(:shell_out!).and_raise(Chef::Exceptions::Exec)
+ expect(@knife.ui).to receive(:error)
+ expect { @knife.run }.to raise_error(SystemExit)
end
it 'should upload the cookbook and clean up the tarball' do
- @knife.should_receive(:do_upload)
- FileUtils.should_receive(:rm_rf)
+ expect(@knife).to receive(:do_upload)
+ expect(FileUtils).to receive(:rm_rf)
@knife.run
end
context "when the --dry-run flag is specified" do
before do
- Chef::CookbookSiteStreamingUploader.stub(:create_build_dir).and_return("/var/tmp/dummy")
+ allow(Chef::CookbookSiteStreamingUploader).to receive(:create_build_dir).and_return("/var/tmp/dummy")
@knife.config = { :dry_run => true }
- @knife.stub_chain(:shell_out!, :stdout).and_return('file')
+ allow(@knife).to receive_message_chain(:shell_out!, :stdout).and_return('file')
end
it "should list files in the tarball" do
@@ -152,46 +161,46 @@ describe Chef::Knife::CookbookSiteShare do
before(:each) do
@upload_response = double('Net::HTTPResponse')
- Chef::CookbookSiteStreamingUploader.stub(:post).and_return(@upload_response)
+ allow(Chef::CookbookSiteStreamingUploader).to receive(:post).and_return(@upload_response)
@stdout = StringIO.new
@stderr = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
- @knife.ui.stub(:stderr).and_return(@stderr)
- File.stub(:open).and_return(true)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
+ allow(File).to receive(:open).and_return(true)
end
- it 'should post the cookbook to "https://supermarket.getchef.com"' do
- response_text = Chef::JSONCompat.to_json({:uri => 'https://supermarket.getchef.com/cookbooks/cookbook_name'})
- @upload_response.stub(:body).and_return(response_text)
- @upload_response.stub(:code).and_return(201)
- Chef::CookbookSiteStreamingUploader.should_receive(:post).with(/supermarket\.getchef\.com/, anything(), anything(), anything())
+ it 'should post the cookbook to "https://supermarket.chef.io"' do
+ response_text = Chef::JSONCompat.to_json({:uri => 'https://supermarket.chef.io/cookbooks/cookbook_name'})
+ allow(@upload_response).to receive(:body).and_return(response_text)
+ allow(@upload_response).to receive(:code).and_return(201)
+ expect(Chef::CookbookSiteStreamingUploader).to receive(:post).with(/supermarket\.chef\.io/, anything(), anything(), anything())
@knife.run
end
it 'should alert the user when a version already exists' do
response_text = Chef::JSONCompat.to_json({:error_messages => ['Version already exists']})
- @upload_response.stub(:body).and_return(response_text)
- @upload_response.stub(:code).and_return(409)
- lambda { @knife.run }.should raise_error(SystemExit)
- @stderr.string.should match(/ERROR(.+)cookbook already exists/)
+ allow(@upload_response).to receive(:body).and_return(response_text)
+ allow(@upload_response).to receive(:code).and_return(409)
+ expect { @knife.run }.to raise_error(SystemExit)
+ expect(@stderr.string).to match(/ERROR(.+)cookbook already exists/)
end
it 'should pass any errors on to the user' do
response_text = Chef::JSONCompat.to_json({:error_messages => ["You're holding it wrong"]})
- @upload_response.stub(:body).and_return(response_text)
- @upload_response.stub(:code).and_return(403)
- lambda { @knife.run }.should raise_error(SystemExit)
- @stderr.string.should match("ERROR(.*)You're holding it wrong")
+ allow(@upload_response).to receive(:body).and_return(response_text)
+ allow(@upload_response).to receive(:code).and_return(403)
+ expect { @knife.run }.to raise_error(SystemExit)
+ expect(@stderr.string).to match("ERROR(.*)You're holding it wrong")
end
it 'should print the body if no errors are exposed on failure' do
response_text = Chef::JSONCompat.to_json({:system_error => "Your call was dropped", :reason => "There's a map for that"})
- @upload_response.stub(:body).and_return(response_text)
- @upload_response.stub(:code).and_return(500)
- @knife.ui.should_receive(:error).with(/#{Regexp.escape(response_text)}/)#.ordered
- @knife.ui.should_receive(:error).with(/Unknown error/)#.ordered
- lambda { @knife.run }.should raise_error(SystemExit)
+ 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.run }.to raise_error(SystemExit)
end
end
diff --git a/spec/unit/knife/cookbook_site_unshare_spec.rb b/spec/unit/knife/cookbook_site_unshare_spec.rb
index 14cda65b43..ec46a8705c 100644
--- a/spec/unit/knife/cookbook_site_unshare_spec.rb
+++ b/spec/unit/knife/cookbook_site_unshare_spec.rb
@@ -24,13 +24,13 @@ describe Chef::Knife::CookbookSiteUnshare do
before(:each) do
@knife = Chef::Knife::CookbookSiteUnshare.new
@knife.name_args = ['cookbook_name']
- @knife.stub(:confirm).and_return(true)
+ allow(@knife).to receive(:confirm).and_return(true)
@rest = double('Chef::REST')
- @rest.stub(:delete_rest).and_return(true)
- @knife.stub(:rest).and_return(@rest)
+ allow(@rest).to receive(:delete_rest).and_return(true)
+ allow(@knife).to receive(:rest).and_return(@rest)
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
describe 'run' do
@@ -38,37 +38,37 @@ describe Chef::Knife::CookbookSiteUnshare do
describe 'with no cookbook argument' do
it 'should print the usage and exit' do
@knife.name_args = []
- @knife.ui.should_receive(:fatal)
- @knife.should_receive(:show_usage)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife.ui).to receive(:fatal)
+ expect(@knife).to receive(:show_usage)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
it 'should confirm you want to unshare the cookbook' do
- @knife.should_receive(:confirm)
+ expect(@knife).to receive(:confirm)
@knife.run
end
it 'should send a delete request to the cookbook site' do
- @rest.should_receive(:delete_rest)
+ expect(@rest).to receive(:delete_rest)
@knife.run
end
it 'should log an error and exit when forbidden' do
exception = double('403 "Forbidden"', :code => '403')
- @rest.stub(:delete_rest).and_raise(Net::HTTPServerException.new('403 "Forbidden"', exception))
- @knife.ui.should_receive(:error)
- lambda { @knife.run }.should raise_error(SystemExit)
+ allow(@rest).to receive(:delete_rest).and_raise(Net::HTTPServerException.new('403 "Forbidden"', exception))
+ expect(@knife.ui).to receive(:error)
+ expect { @knife.run }.to raise_error(SystemExit)
end
it 'should re-raise any non-forbidden errors on delete_rest' do
exception = double('500 "Application Error"', :code => '500')
- @rest.stub(:delete_rest).and_raise(Net::HTTPServerException.new('500 "Application Error"', exception))
- lambda { @knife.run }.should raise_error(Net::HTTPServerException)
+ allow(@rest).to receive(:delete_rest).and_raise(Net::HTTPServerException.new('500 "Application Error"', exception))
+ expect { @knife.run }.to raise_error(Net::HTTPServerException)
end
it 'should log a success message' do
- @knife.ui.should_receive(:info)
+ expect(@knife.ui).to receive(:info)
@knife.run
end
diff --git a/spec/unit/knife/cookbook_test_spec.rb b/spec/unit/knife/cookbook_test_spec.rb
index 0e261c02a4..ce74bcaa5d 100644
--- a/spec/unit/knife/cookbook_test_spec.rb
+++ b/spec/unit/knife/cookbook_test_spec.rb
@@ -26,55 +26,55 @@ describe Chef::Knife::CookbookTest do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::CookbookTest.new
@knife.config[:cookbook_path] = File.join(CHEF_SPEC_DATA,'cookbooks')
- @knife.cookbook_loader.stub(:cookbook_exists?).and_return(true)
+ allow(@knife.cookbook_loader).to receive(:cookbook_exists?).and_return(true)
@cookbooks = []
%w{tats central_market jimmy_johns pho}.each do |cookbook_name|
@cookbooks << Chef::CookbookVersion.new(cookbook_name)
end
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
describe "run" do
it "should test the cookbook" do
- @knife.stub(:test_cookbook).and_return(true)
+ allow(@knife).to receive(:test_cookbook).and_return(true)
@knife.name_args = ["italian"]
- @knife.should_receive(:test_cookbook).with("italian")
+ expect(@knife).to receive(:test_cookbook).with("italian")
@knife.run
end
it "should test multiple cookbooks when provided" do
- @knife.stub(:test_cookbook).and_return(true)
+ allow(@knife).to receive(:test_cookbook).and_return(true)
@knife.name_args = ["tats", "jimmy_johns"]
- @knife.should_receive(:test_cookbook).with("tats")
- @knife.should_receive(:test_cookbook).with("jimmy_johns")
- @knife.should_not_receive(:test_cookbook).with("central_market")
- @knife.should_not_receive(:test_cookbook).with("pho")
+ expect(@knife).to receive(:test_cookbook).with("tats")
+ expect(@knife).to receive(:test_cookbook).with("jimmy_johns")
+ expect(@knife).not_to receive(:test_cookbook).with("central_market")
+ expect(@knife).not_to receive(:test_cookbook).with("pho")
@knife.run
end
it "should test both ruby and templates" do
@knife.name_args = ["example"]
- @knife.config[:cookbook_path].should_not be_empty
+ expect(@knife.config[:cookbook_path]).not_to be_empty
Array(@knife.config[:cookbook_path]).reverse.each do |path|
- @knife.should_receive(:test_ruby).with(an_instance_of(Chef::Cookbook::SyntaxCheck))
- @knife.should_receive(:test_templates).with(an_instance_of(Chef::Cookbook::SyntaxCheck))
+ expect(@knife).to receive(:test_ruby).with(an_instance_of(Chef::Cookbook::SyntaxCheck))
+ expect(@knife).to receive(:test_templates).with(an_instance_of(Chef::Cookbook::SyntaxCheck))
end
@knife.run
end
describe "with -a or --all" do
it "should test all of the cookbooks" do
- @knife.stub(:test_cookbook).and_return(true)
+ allow(@knife).to receive(:test_cookbook).and_return(true)
@knife.config[:all] = true
@loader = {}
- @loader.stub(:load_cookbooks).and_return(@loader)
+ allow(@loader).to receive(:load_cookbooks).and_return(@loader)
@cookbooks.each do |cookbook|
@loader[cookbook.name] = cookbook
end
- @knife.stub(:cookbook_loader).and_return(@loader)
+ allow(@knife).to receive(:cookbook_loader).and_return(@loader)
@loader.each do |key, cookbook|
- @knife.should_receive(:test_cookbook).with(cookbook.name)
+ expect(@knife).to receive(:test_cookbook).with(cookbook.name)
end
@knife.run
end
diff --git a/spec/unit/knife/cookbook_upload_spec.rb b/spec/unit/knife/cookbook_upload_spec.rb
index e5c9a40cf1..fb94886cad 100644
--- a/spec/unit/knife/cookbook_upload_spec.rb
+++ b/spec/unit/knife/cookbook_upload_spec.rb
@@ -31,8 +31,8 @@ describe Chef::Knife::CookbookUpload do
let(:cookbook_loader) do
cookbook_loader = cookbooks_by_name.dup
- cookbook_loader.stub(:merged_cookbooks).and_return([])
- cookbook_loader.stub(:load_cookbooks).and_return(cookbook_loader)
+ allow(cookbook_loader).to receive(:merged_cookbooks).and_return([])
+ allow(cookbook_loader).to receive(:load_cookbooks).and_return(cookbook_loader)
cookbook_loader
end
@@ -45,23 +45,23 @@ describe Chef::Knife::CookbookUpload do
let(:knife) do
k = Chef::Knife::CookbookUpload.new
k.name_args = name_args
- k.ui.stub(:stdout).and_return(output)
- k.ui.stub(:stderr).and_return(output)
+ allow(k.ui).to receive(:stdout).and_return(output)
+ allow(k.ui).to receive(:stderr).and_return(output)
k
end
before(:each) do
- Chef::CookbookLoader.stub(:new).and_return(cookbook_loader)
+ allow(Chef::CookbookLoader).to receive(:new).and_return(cookbook_loader)
end
describe 'with --concurrency' do
it 'should upload cookbooks with predefined concurrency' do
- Chef::CookbookVersion.stub(:list_all_versions).and_return({})
+ allow(Chef::CookbookVersion).to receive(:list_all_versions).and_return({})
knife.config[:concurrency] = 3
test_cookbook = Chef::CookbookVersion.new('test_cookbook', '/tmp/blah')
- cookbook_loader.stub(:each).and_yield("test_cookbook", test_cookbook)
- cookbook_loader.stub(:cookbook_names).and_return(["test_cookbook"])
- Chef::CookbookUploader.should_receive(:new).
+ allow(cookbook_loader).to receive(:each).and_yield("test_cookbook", test_cookbook)
+ allow(cookbook_loader).to receive(:cookbook_names).and_return(["test_cookbook"])
+ expect(Chef::CookbookUploader).to receive(:new).
with( kind_of(Array), { :force => nil, :concurrency => 3}).
and_return(double("Chef::CookbookUploader", :upload_cookbooks=> true))
knife.run
@@ -70,26 +70,26 @@ describe Chef::Knife::CookbookUpload do
describe 'run' do
before(:each) do
- Chef::CookbookUploader.stub(:new => cookbook_uploader)
- Chef::CookbookVersion.stub(:list_all_versions).and_return({})
+ allow(Chef::CookbookUploader).to receive_messages(:new => cookbook_uploader)
+ allow(Chef::CookbookVersion).to receive(:list_all_versions).and_return({})
end
it 'should print usage and exit when a cookbook name is not provided' do
knife.name_args = []
- knife.should_receive(:show_usage)
- knife.ui.should_receive(:fatal)
- lambda { knife.run }.should raise_error(SystemExit)
+ expect(knife).to receive(:show_usage)
+ expect(knife.ui).to receive(:fatal)
+ expect { knife.run }.to raise_error(SystemExit)
end
describe 'when specifying a cookbook name' do
it 'should upload the cookbook' do
- knife.should_receive(:upload).once
+ expect(knife).to receive(:upload).once
knife.run
end
it 'should report on success' do
- knife.should_receive(:upload).once
- knife.ui.should_receive(:info).with(/Uploaded 1 cookbook/)
+ expect(knife).to receive(:upload).once
+ expect(knife.ui).to receive(:info).with(/Uploaded 1 cookbook/)
knife.run
end
end
@@ -97,7 +97,7 @@ describe Chef::Knife::CookbookUpload do
describe 'when specifying the same cookbook name twice' do
it 'should upload the cookbook only once' do
knife.name_args = ['test_cookbook', 'test_cookbook']
- knife.should_receive(:upload).once
+ expect(knife).to receive(:upload).once
knife.run
end
end
@@ -105,8 +105,8 @@ describe Chef::Knife::CookbookUpload do
context "when uploading a cookbook that uses deprecated overlays" do
before do
- cookbook_loader.stub(:merged_cookbooks).and_return(['test_cookbook'])
- cookbook_loader.stub(:merged_cookbook_paths).
+ allow(cookbook_loader).to receive(:merged_cookbooks).and_return(['test_cookbook'])
+ allow(cookbook_loader).to receive(:merged_cookbook_paths).
and_return({'test_cookbook' => %w{/path/one/test_cookbook /path/two/test_cookbook}})
end
@@ -123,7 +123,7 @@ test_cookbook:
/path/one/test_cookbook
/path/two/test_cookbook
E
- output.string.should include(expected_message)
+ expect(output.string).to include(expected_message)
end
end
@@ -139,17 +139,17 @@ E
end
it "should read only one cookbook" do
- cookbook_loader.should_receive(:[]).once.with('test_cookbook1').and_call_original
+ expect(cookbook_loader).to receive(:[]).once.with('test_cookbook1').and_call_original
knife.run
end
it "should not read all cookbooks" do
- cookbook_loader.should_not_receive(:load_cookbooks)
+ expect(cookbook_loader).not_to receive(:load_cookbooks)
knife.run
end
it "should upload only one cookbook" do
- knife.should_receive(:upload).exactly(1).times
+ expect(knife).to receive(:upload).exactly(1).times
knife.run
end
end
@@ -181,13 +181,13 @@ E
it "should upload all dependencies once" do
knife.config[:depends] = true
- knife.stub(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2", "test_cookbook3"])
- knife.should_receive(:upload).exactly(3).times
- lambda do
+ allow(knife).to receive(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2", "test_cookbook3"])
+ expect(knife).to receive(:upload).exactly(3).times
+ expect do
Timeout::timeout(5) do
knife.run
end
- end.should_not raise_error
+ end.not_to raise_error
end
end
@@ -196,99 +196,133 @@ E
before(:each) do
cookbook.metadata.depends("dependency")
- cookbook_loader.stub(:[]) do |ckbk|
+ allow(cookbook_loader).to receive(:[]) do |ckbk|
{ "test_cookbook" => cookbook,
"dependency" => cookbook_dependency}[ckbk]
end
- knife.stub(:cookbook_names).and_return(["cookbook_dependency", "test_cookbook"])
+ allow(knife).to receive(:cookbook_names).and_return(["cookbook_dependency", "test_cookbook"])
@stdout, @stderr, @stdin = StringIO.new, StringIO.new, StringIO.new
knife.ui = Chef::Knife::UI.new(@stdout, @stderr, @stdin, {})
end
it 'should exit and not upload the cookbook' do
- cookbook_loader.should_receive(:[]).once.with('test_cookbook')
- cookbook_loader.should_not_receive(:load_cookbooks)
- cookbook_uploader.should_not_receive(:upload_cookbooks)
+ expect(cookbook_loader).to receive(:[]).once.with('test_cookbook')
+ expect(cookbook_loader).not_to receive(:load_cookbooks)
+ expect(cookbook_uploader).not_to receive(:upload_cookbooks)
expect {knife.run}.to raise_error(SystemExit)
end
it 'should output a message for a single missing dependency' do
expect {knife.run}.to raise_error(SystemExit)
- @stderr.string.should include('Cookbook test_cookbook depends on cookbooks which are not currently')
- @stderr.string.should include('being uploaded and cannot be found on the server.')
- @stderr.string.should include("The missing cookbook(s) are: 'dependency' version '>= 0.0.0'")
+ expect(@stderr.string).to include('Cookbook test_cookbook depends on cookbooks which are not currently')
+ expect(@stderr.string).to include('being uploaded and cannot be found on the server.')
+ expect(@stderr.string).to include("The missing cookbook(s) are: 'dependency' version '>= 0.0.0'")
end
it 'should output a message for a multiple missing dependencies which are concatenated' do
cookbook_dependency2 = Chef::CookbookVersion.new('dependency2')
cookbook.metadata.depends("dependency2")
- cookbook_loader.stub(:[]) do |ckbk|
+ allow(cookbook_loader).to receive(:[]) do |ckbk|
{ "test_cookbook" => cookbook,
"dependency" => cookbook_dependency,
"dependency2" => cookbook_dependency2}[ckbk]
end
- knife.stub(:cookbook_names).and_return(["dependency", "dependency2", "test_cookbook"])
+ allow(knife).to receive(:cookbook_names).and_return(["dependency", "dependency2", "test_cookbook"])
expect {knife.run}.to raise_error(SystemExit)
- @stderr.string.should include('Cookbook test_cookbook depends on cookbooks which are not currently')
- @stderr.string.should include('being uploaded and cannot be found on the server.')
- @stderr.string.should include("The missing cookbook(s) are:")
- @stderr.string.should include("'dependency' version '>= 0.0.0'")
- @stderr.string.should include("'dependency2' version '>= 0.0.0'")
+ expect(@stderr.string).to include('Cookbook test_cookbook depends on cookbooks which are not currently')
+ expect(@stderr.string).to include('being uploaded and cannot be found on the server.')
+ expect(@stderr.string).to include("The missing cookbook(s) are:")
+ expect(@stderr.string).to include("'dependency' version '>= 0.0.0'")
+ expect(@stderr.string).to include("'dependency2' version '>= 0.0.0'")
end
end
it "should freeze the version of the cookbooks if --freeze is specified" do
knife.config[:freeze] = true
- cookbook.should_receive(:freeze_version).once
+ expect(cookbook).to receive(:freeze_version).once
knife.run
end
describe 'with -a or --all' do
before(:each) do
knife.config[:all] = true
- @test_cookbook1 = Chef::CookbookVersion.new('test_cookbook1', '/tmp/blah')
- @test_cookbook2 = Chef::CookbookVersion.new('test_cookbook2', '/tmp/blah')
- cookbook_loader.stub(:each).and_yield("test_cookbook1", @test_cookbook1).and_yield("test_cookbook2", @test_cookbook2)
- cookbook_loader.stub(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2"])
end
- it 'should upload all cookbooks' do
- knife.should_receive(:upload).once
- knife.run
- end
+ context 'when cookbooks exist in the cookbook path' do
+ before(:each) do
+ @test_cookbook1 = Chef::CookbookVersion.new('test_cookbook1', '/tmp/blah')
+ @test_cookbook2 = Chef::CookbookVersion.new('test_cookbook2', '/tmp/blah')
+ allow(cookbook_loader).to receive(:each).and_yield("test_cookbook1", @test_cookbook1).and_yield("test_cookbook2", @test_cookbook2)
+ allow(cookbook_loader).to receive(:cookbook_names).and_return(["test_cookbook1", "test_cookbook2"])
+ end
- it 'should report on success' do
- knife.should_receive(:upload).once
- knife.ui.should_receive(:info).with(/Uploaded all cookbooks/)
- knife.run
+ it 'should upload all cookbooks' do
+ expect(knife).to receive(:upload).once
+ knife.run
+ end
+
+ it 'should report on success' do
+ expect(knife).to receive(:upload).once
+ expect(knife.ui).to receive(:info).with(/Uploaded all cookbooks/)
+ knife.run
+ end
+
+ it 'should update the version constraints for an environment' do
+ allow(knife).to receive(:assert_environment_valid!).and_return(true)
+ knife.config[:environment] = "production"
+ expect(knife).to receive(:update_version_constraints).once
+ knife.run
+ end
end
- it 'should update the version constraints for an environment' do
- knife.stub(:assert_environment_valid!).and_return(true)
- knife.config[:environment] = "production"
- knife.should_receive(:update_version_constraints).once
- knife.run
+ context 'when no cookbooks exist in the cookbook path' do
+ before(:each) do
+ allow(cookbook_loader).to receive(:each)
+ end
+
+ it 'should not upload any cookbooks' do
+ expect(knife).to_not receive(:upload)
+ knife.run
+ end
+
+ context 'when cookbook path is an array' do
+ it 'should warn users that no cookbooks exist' do
+ knife.config[:cookbook_path] = ['/chef-repo/cookbooks', '/home/user/cookbooks']
+ expect(knife.ui).to receive(:warn).with(
+ /Could not find any cookbooks in your cookbook path: #{knife.config[:cookbook_path].join(', ')}\. Use --cookbook-path to specify the desired path\./)
+ knife.run
+ end
+ end
+
+ context 'when cookbook path is a string' do
+ it 'should warn users that no cookbooks exist' do
+ knife.config[:cookbook_path] = '/chef-repo/cookbooks'
+ expect(knife.ui).to receive(:warn).with(
+ /Could not find any cookbooks in your cookbook path: #{knife.config[:cookbook_path]}\. Use --cookbook-path to specify the desired path\./)
+ knife.run
+ end
+ end
end
end
describe 'when a frozen cookbook exists on the server' do
it 'should fail to replace it' do
exception = Chef::Exceptions::CookbookFrozen.new
- cookbook_uploader.should_receive(:upload_cookbooks).
+ expect(cookbook_uploader).to receive(:upload_cookbooks).
and_raise(exception)
- knife.ui.stub(:error)
- knife.ui.should_receive(:error).with(exception)
- lambda { knife.run }.should raise_error(SystemExit)
+ allow(knife.ui).to receive(:error)
+ expect(knife.ui).to receive(:error).with(exception)
+ expect { knife.run }.to raise_error(SystemExit)
end
it 'should not update the version constraints for an environment' do
- knife.stub(:assert_environment_valid!).and_return(true)
+ allow(knife).to receive(:assert_environment_valid!).and_return(true)
knife.config[:environment] = "production"
- knife.stub(:upload).and_raise(Chef::Exceptions::CookbookFrozen)
- knife.ui.should_receive(:error).with(/Failed to upload 1 cookbook/)
- knife.ui.should_receive(:warn).with(/Not updating version constraints/)
- knife.should_not_receive(:update_version_constraints)
- lambda { knife.run }.should raise_error(SystemExit)
+ allow(knife).to receive(:upload).and_raise(Chef::Exceptions::CookbookFrozen)
+ expect(knife.ui).to receive(:error).with(/Failed to upload 1 cookbook/)
+ expect(knife.ui).to receive(:warn).with(/Not updating version constraints/)
+ expect(knife).not_to receive(:update_version_constraints)
+ expect { knife.run }.to raise_error(SystemExit)
end
end
end # run
diff --git a/spec/unit/knife/core/bootstrap_context_spec.rb b/spec/unit/knife/core/bootstrap_context_spec.rb
index 6f7adfcf57..3718cb228c 100644
--- a/spec/unit/knife/core/bootstrap_context_spec.rb
+++ b/spec/unit/knife/core/bootstrap_context_spec.rb
@@ -39,18 +39,18 @@ describe Chef::Knife::Core::BootstrapContext do
end
it "runs chef with the first-boot.json in the _default environment" do
- bootstrap_context.start_chef.should eq "chef-client -j /etc/chef/first-boot.json -E _default"
+ expect(bootstrap_context.start_chef).to eq "chef-client -j /etc/chef/first-boot.json -E _default"
end
describe "when in verbosity mode" do
let(:config) { {:verbosity => 2} }
it "adds '-l debug' when verbosity is >= 2" do
- bootstrap_context.start_chef.should eq "chef-client -j /etc/chef/first-boot.json -l debug -E _default"
+ expect(bootstrap_context.start_chef).to eq "chef-client -j /etc/chef/first-boot.json -l debug -E _default"
end
end
it "reads the validation key" do
- bootstrap_context.validation_key.should eq IO.read(File.join(CHEF_SPEC_DATA, 'ssl', 'private_key.pem'))
+ expect(bootstrap_context.validation_key).to eq IO.read(File.join(CHEF_SPEC_DATA, 'ssl', 'private_key.pem'))
end
it "generates the config file data" do
@@ -60,7 +60,7 @@ chef_server_url "http://chef.example.com:4444"
validation_client_name "chef-validator-testing"
# Using default node name (fqdn)
EXPECTED
- bootstrap_context.config_content.should eq expected
+ expect(bootstrap_context.config_content).to eq expected
end
it "does not set a default log_level" do
@@ -70,14 +70,15 @@ EXPECTED
describe "alternate chef-client path" do
let(:chef_config){ {:chef_client_path => '/usr/local/bin/chef-client'} }
it "runs chef-client from another path when specified" do
- bootstrap_context.start_chef.should eq "/usr/local/bin/chef-client -j /etc/chef/first-boot.json -E _default"
+ expect(bootstrap_context.start_chef).to eq "/usr/local/bin/chef-client -j /etc/chef/first-boot.json -E _default"
end
end
describe "validation key path that contains a ~" do
let(:chef_config){ {:validation_key => '~/my.key'} }
it "reads the validation key when it contains a ~" do
- IO.should_receive(:read).with(File.expand_path("my.key", ENV['HOME']))
+ expect(File).to receive(:exist?).with(File.expand_path("my.key", ENV['HOME'])).and_return(true)
+ expect(IO).to receive(:read).with(File.expand_path("my.key", ENV['HOME']))
bootstrap_context.validation_key
end
end
@@ -85,44 +86,44 @@ EXPECTED
describe "when an explicit node name is given" do
let(:config){ {:chef_node_name => 'foobar.example.com' }}
it "sets the node name in the client.rb" do
- bootstrap_context.config_content.should match(/node_name "foobar\.example\.com"/)
+ expect(bootstrap_context.config_content).to match(/node_name "foobar\.example\.com"/)
end
end
describe "when bootstrapping into a specific environment" do
let(:chef_config){ {:environment => "prodtastic"} }
it "starts chef in the configured environment" do
- bootstrap_context.start_chef.should == 'chef-client -j /etc/chef/first-boot.json -E prodtastic'
+ expect(bootstrap_context.start_chef).to eq('chef-client -j /etc/chef/first-boot.json -E prodtastic')
end
end
describe "when JSON attributes are given" do
let(:config) { {:first_boot_attributes => {:baz => :quux}} }
it "adds the attributes to first_boot" do
- Chef::JSONCompat.to_json(bootstrap_context.first_boot).should eq(Chef::JSONCompat.to_json({:baz => :quux, :run_list => run_list}))
+ expect(Chef::JSONCompat.to_json(bootstrap_context.first_boot)).to eq(Chef::JSONCompat.to_json({:baz => :quux, :run_list => run_list}))
end
end
describe "when JSON attributes are NOT given" do
it "sets first_boot equal to run_list" do
- Chef::JSONCompat.to_json(bootstrap_context.first_boot).should eq(Chef::JSONCompat.to_json({:run_list => run_list}))
+ expect(Chef::JSONCompat.to_json(bootstrap_context.first_boot)).to eq(Chef::JSONCompat.to_json({:run_list => run_list}))
end
end
describe "when an encrypted_data_bag_secret is provided" do
let(:secret) { "supersekret" }
it "reads the encrypted_data_bag_secret" do
- bootstrap_context.encrypted_data_bag_secret.should eq "supersekret"
+ expect(bootstrap_context.encrypted_data_bag_secret).to eq "supersekret"
end
end
describe "to support compatibility with existing templates" do
it "sets the @config instance variable" do
- bootstrap_context.instance_variable_get(:@config).should eq config
+ expect(bootstrap_context.instance_variable_get(:@config)).to eq config
end
it "sets the @run_list instance variable" do
- bootstrap_context.instance_variable_get(:@run_list).should eq run_list
+ expect(bootstrap_context.instance_variable_get(:@run_list)).to eq run_list
end
end
@@ -134,7 +135,7 @@ EXPECTED
end
it "should send the full version to the installer" do
- bootstrap_context.latest_current_chef_version_string.should eq("-v 11.12.4")
+ expect(bootstrap_context.latest_current_chef_version_string).to eq("-v 11.12.4")
end
end
@@ -146,20 +147,20 @@ EXPECTED
end
it "should send the full version to the installer and set the pre-release flag" do
- bootstrap_context.latest_current_chef_version_string.should eq("-v 11.12.4.rc.0 -p")
+ expect(bootstrap_context.latest_current_chef_version_string).to eq("-v 11.12.4.rc.0 -p")
end
end
describe "when a bootstrap_version is not specified" do
it "should send the latest current to the installer" do
# Intentionally hard coded in order not to replicate the logic.
- bootstrap_context.latest_current_chef_version_string.should eq("-v #{Chef::VERSION.to_i}")
+ expect(bootstrap_context.latest_current_chef_version_string).to eq("-v #{Chef::VERSION.to_i}")
end
end
describe "ssl_verify_mode" do
it "isn't set in the config_content by default" do
- bootstrap_context.config_content.should_not include("ssl_verify_mode")
+ expect(bootstrap_context.config_content).not_to include("ssl_verify_mode")
end
describe "when configured in config" do
@@ -170,14 +171,14 @@ EXPECTED
end
it "uses the config value" do
- bootstrap_context.config_content.should include("ssl_verify_mode :verify_peer")
+ expect(bootstrap_context.config_content).to include("ssl_verify_mode :verify_peer")
end
describe "when configured via CLI" do
let(:config) {{:node_ssl_verify_mode => "none"}}
it "uses CLI value" do
- bootstrap_context.config_content.should include("ssl_verify_mode :verify_none")
+ expect(bootstrap_context.config_content).to include("ssl_verify_mode :verify_none")
end
end
end
@@ -185,7 +186,7 @@ EXPECTED
describe "verify_api_cert" do
it "isn't set in the config_content by default" do
- bootstrap_context.config_content.should_not include("verify_api_cert")
+ expect(bootstrap_context.config_content).not_to include("verify_api_cert")
end
describe "when configured in config" do
@@ -196,17 +197,31 @@ EXPECTED
end
it "uses the config value" do
- bootstrap_context.config_content.should include("verify_api_cert false")
+ expect(bootstrap_context.config_content).to include("verify_api_cert false")
end
describe "when configured via CLI" do
let(:config) {{:node_verify_api_cert => true}}
it "uses CLI value" do
- bootstrap_context.config_content.should include("verify_api_cert true")
+ expect(bootstrap_context.config_content).to include("verify_api_cert true")
end
end
end
end
+ describe "prerelease" do
+ it "isn't set in the config_content by default" do
+ expect(bootstrap_context.config_content).not_to include("prerelease")
+ end
+
+ describe "when configured via cli" do
+ let(:config) {{:prerelease => true}}
+
+ it "uses CLI value" do
+ expect(bootstrap_context.latest_current_chef_version_string).to eq("-p")
+ end
+ end
+ end
+
end
diff --git a/spec/unit/knife/core/cookbook_scm_repo_spec.rb b/spec/unit/knife/core/cookbook_scm_repo_spec.rb
index 69da5400b0..2d66df31c1 100644
--- a/spec/unit/knife/core/cookbook_scm_repo_spec.rb
+++ b/spec/unit/knife/core/cookbook_scm_repo_spec.rb
@@ -39,45 +39,45 @@ BRANCHES
end
it "has a path to the cookbook repo" do
- @cookbook_repo.repo_path.should == @repo_path
+ expect(@cookbook_repo.repo_path).to eq(@repo_path)
end
it "has a default branch" do
- @cookbook_repo.default_branch.should == 'master'
+ expect(@cookbook_repo.default_branch).to eq('master')
end
describe "when sanity checking the repo" do
it "exits when the directory does not exist" do
- ::File.should_receive(:directory?).with(@repo_path).and_return(false)
- lambda {@cookbook_repo.sanity_check}.should raise_error(SystemExit)
+ expect(::File).to receive(:directory?).with(@repo_path).and_return(false)
+ expect {@cookbook_repo.sanity_check}.to raise_error(SystemExit)
end
describe "and the repo dir exists" do
before do
- ::File.stub(:directory?).with(@repo_path).and_return(true)
+ allow(::File).to receive(:directory?).with(@repo_path).and_return(true)
end
it "exits when there is no git repo" do
- ::File.stub(:directory?).with(/.*\.git/).and_return(false)
- lambda {@cookbook_repo.sanity_check}.should raise_error(SystemExit)
+ allow(::File).to receive(:directory?).with(/.*\.git/).and_return(false)
+ expect {@cookbook_repo.sanity_check}.to raise_error(SystemExit)
end
describe "and the repo is a git repo" do
before do
- ::File.stub(:directory?).with(File.join(@repo_path, '.git')).and_return(true)
+ allow(::File).to receive(:directory?).with(File.join(@repo_path, '.git')).and_return(true)
end
it "exits when the default branch doesn't exist" do
@nobranches = Mixlib::ShellOut.new.tap {|s|s.stdout.replace "\n"}
- @cookbook_repo.should_receive(:shell_out!).with('git branch --no-color', :cwd => @repo_path).and_return(@nobranches)
- lambda {@cookbook_repo.sanity_check}.should raise_error(SystemExit)
+ expect(@cookbook_repo).to receive(:shell_out!).with('git branch --no-color', :cwd => @repo_path).and_return(@nobranches)
+ expect {@cookbook_repo.sanity_check}.to raise_error(SystemExit)
end
describe "and the default branch exists" do
before do
@master_branch = Mixlib::ShellOut.new
@master_branch.stdout.replace "* master\n"
- @cookbook_repo.should_receive(:shell_out!).with("git branch --no-color", :cwd => @repo_path).and_return(@master_branch)
+ expect(@cookbook_repo).to receive(:shell_out!).with("git branch --no-color", :cwd => @repo_path).and_return(@master_branch)
end
it "exits when the git repo is dirty" do
@@ -85,14 +85,14 @@ BRANCHES
@dirty_status.stdout.replace(<<-DIRTY)
M chef/lib/chef/knife/cookbook_site_vendor.rb
DIRTY
- @cookbook_repo.should_receive(:shell_out!).with('git status --porcelain', :cwd => @repo_path).and_return(@dirty_status)
- lambda {@cookbook_repo.sanity_check}.should raise_error(SystemExit)
+ expect(@cookbook_repo).to receive(:shell_out!).with('git status --porcelain', :cwd => @repo_path).and_return(@dirty_status)
+ expect {@cookbook_repo.sanity_check}.to raise_error(SystemExit)
end
describe "and the repo is clean" do
before do
@clean_status = Mixlib::ShellOut.new.tap {|s| s.stdout.replace("\n")}
- @cookbook_repo.stub(:shell_out!).with('git status --porcelain', :cwd => @repo_path).and_return(@clean_status)
+ allow(@cookbook_repo).to receive(:shell_out!).with('git status --porcelain', :cwd => @repo_path).and_return(@clean_status)
end
it "passes the sanity check" do
@@ -106,35 +106,35 @@ DIRTY
end
it "resets to default state by checking out the default branch" do
- @cookbook_repo.should_receive(:shell_out!).with('git checkout master', :cwd => @repo_path)
+ expect(@cookbook_repo).to receive(:shell_out!).with('git checkout master', :cwd => @repo_path)
@cookbook_repo.reset_to_default_state
end
it "determines if a the pristine copy branch exists" do
- @cookbook_repo.should_receive(:shell_out!).with('git branch --no-color', :cwd => @repo_path).and_return(@branch_list)
- @cookbook_repo.branch_exists?("chef-vendor-apache2").should be_true
- @cookbook_repo.should_receive(:shell_out!).with('git branch --no-color', :cwd => @repo_path).and_return(@branch_list)
- @cookbook_repo.branch_exists?("chef-vendor-nginx").should be_false
+ expect(@cookbook_repo).to receive(:shell_out!).with('git branch --no-color', :cwd => @repo_path).and_return(@branch_list)
+ expect(@cookbook_repo.branch_exists?("chef-vendor-apache2")).to be_truthy
+ expect(@cookbook_repo).to receive(:shell_out!).with('git branch --no-color', :cwd => @repo_path).and_return(@branch_list)
+ expect(@cookbook_repo.branch_exists?("chef-vendor-nginx")).to be_falsey
end
it "determines if a the branch not exists correctly without substring search" do
- @cookbook_repo.should_receive(:shell_out!).twice.with('git branch --no-color', :cwd => @repo_path).and_return(@branch_list)
- @cookbook_repo.should_not be_branch_exists("chef-vendor-absent")
- @cookbook_repo.should be_branch_exists("chef-vendor-absent-new")
+ expect(@cookbook_repo).to receive(:shell_out!).twice.with('git branch --no-color', :cwd => @repo_path).and_return(@branch_list)
+ expect(@cookbook_repo).not_to be_branch_exists("chef-vendor-absent")
+ expect(@cookbook_repo).to be_branch_exists("chef-vendor-absent-new")
end
describe "when the pristine copy branch does not exist" do
it "prepares for import by creating the pristine copy branch" do
- @cookbook_repo.should_receive(:shell_out!).with('git branch --no-color', :cwd => @repo_path).and_return(@branch_list)
- @cookbook_repo.should_receive(:shell_out!).with('git checkout -b chef-vendor-nginx', :cwd => @repo_path)
+ expect(@cookbook_repo).to receive(:shell_out!).with('git branch --no-color', :cwd => @repo_path).and_return(@branch_list)
+ expect(@cookbook_repo).to receive(:shell_out!).with('git checkout -b chef-vendor-nginx', :cwd => @repo_path)
@cookbook_repo.prepare_to_import("nginx")
end
end
describe "when the pristine copy branch does exist" do
it "prepares for import by checking out the pristine copy branch" do
- @cookbook_repo.should_receive(:shell_out!).with('git branch --no-color', :cwd => @repo_path).and_return(@branch_list)
- @cookbook_repo.should_receive(:shell_out!).with('git checkout chef-vendor-apache2', :cwd => @repo_path)
+ expect(@cookbook_repo).to receive(:shell_out!).with('git branch --no-color', :cwd => @repo_path).and_return(@branch_list)
+ expect(@cookbook_repo).to receive(:shell_out!).with('git checkout chef-vendor-apache2', :cwd => @repo_path)
@cookbook_repo.prepare_to_import("apache2")
end
end
@@ -143,15 +143,15 @@ DIRTY
before do
@updates = Mixlib::ShellOut.new
@updates.stdout.replace("\n")
- @cookbook_repo.stub(:shell_out!).with('git status --porcelain -- apache2', :cwd => @repo_path).and_return(@updates)
+ allow(@cookbook_repo).to receive(:shell_out!).with('git status --porcelain -- apache2', :cwd => @repo_path).and_return(@updates)
end
it "shows no changes in the pristine copy" do
- @cookbook_repo.updated?('apache2').should be_false
+ expect(@cookbook_repo.updated?('apache2')).to be_falsey
end
it "does nothing to finalize the updates" do
- @cookbook_repo.finalize_updates_to('apache2', '1.2.3').should be_false
+ expect(@cookbook_repo.finalize_updates_to('apache2', '1.2.3')).to be_falsey
end
end
@@ -159,18 +159,18 @@ DIRTY
before do
@updates = Mixlib::ShellOut.new
@updates.stdout.replace(" M cookbooks/apache2/recipes/default.rb\n")
- @cookbook_repo.stub(:shell_out!).with('git status --porcelain -- apache2', :cwd => @repo_path).and_return(@updates)
+ allow(@cookbook_repo).to receive(:shell_out!).with('git status --porcelain -- apache2', :cwd => @repo_path).and_return(@updates)
end
it "shows changes in the pristine copy" do
- @cookbook_repo.updated?('apache2').should be_true
+ expect(@cookbook_repo.updated?('apache2')).to be_truthy
end
it "commits the changes to the repo and tags the commit" do
- @cookbook_repo.should_receive(:shell_out!).with("git add apache2", :cwd => @repo_path)
- @cookbook_repo.should_receive(:shell_out!).with("git commit -m \"Import apache2 version 1.2.3\" -- apache2", :cwd => @repo_path)
- @cookbook_repo.should_receive(:shell_out!).with("git tag -f cookbook-site-imported-apache2-1.2.3", :cwd => @repo_path)
- @cookbook_repo.finalize_updates_to("apache2", "1.2.3").should be_true
+ expect(@cookbook_repo).to receive(:shell_out!).with("git add apache2", :cwd => @repo_path)
+ expect(@cookbook_repo).to receive(:shell_out!).with("git commit -m \"Import apache2 version 1.2.3\" -- apache2", :cwd => @repo_path)
+ expect(@cookbook_repo).to receive(:shell_out!).with("git tag -f cookbook-site-imported-apache2-1.2.3", :cwd => @repo_path)
+ expect(@cookbook_repo.finalize_updates_to("apache2", "1.2.3")).to be_truthy
end
end
@@ -180,7 +180,7 @@ DIRTY
end
it "resets to default state by checking out the default branch" do
- @cookbook_repo.should_receive(:shell_out!).with('git checkout develop', :cwd => @repo_path)
+ expect(@cookbook_repo).to receive(:shell_out!).with('git checkout develop', :cwd => @repo_path)
@cookbook_repo.reset_to_default_state
end
end
diff --git a/spec/unit/knife/core/object_loader_spec.rb b/spec/unit/knife/core/object_loader_spec.rb
index 53a538da91..67fa858029 100644
--- a/spec/unit/knife/core/object_loader_spec.rb
+++ b/spec/unit/knife/core/object_loader_spec.rb
@@ -24,17 +24,17 @@ describe Chef::Knife::Core::ObjectLoader do
before(:each) do
@knife = Chef::Knife.new
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
Dir.chdir(File.join(CHEF_SPEC_DATA, 'object_loader'))
end
shared_examples_for "Chef object" do |chef_class|
it "should create a #{chef_class} object" do
- @object.should be_a_kind_of(chef_class)
+ expect(@object).to be_a_kind_of(chef_class)
end
it "should has a attribute 'name'" do
- @object.name.should eql('test')
+ expect(@object.name).to eql('test')
end
end
diff --git a/spec/unit/knife/core/subcommand_loader_spec.rb b/spec/unit/knife/core/subcommand_loader_spec.rb
index 53664cb528..df42cff2ea 100644
--- a/spec/unit/knife/core/subcommand_loader_spec.rb
+++ b/spec/unit/knife/core/subcommand_loader_spec.rb
@@ -20,22 +20,22 @@ require 'spec_helper'
describe Chef::Knife::SubcommandLoader do
before do
- Chef::Platform.stub(:windows?) { false }
+ allow(Chef::Platform).to receive(:windows?) { false }
@home = File.join(CHEF_SPEC_DATA, 'knife-home')
@env = {'HOME' => @home}
@loader = Chef::Knife::SubcommandLoader.new(File.join(CHEF_SPEC_DATA, 'knife-site-subcommands'), @env)
end
it "builds a list of the core subcommand file require paths" do
- @loader.subcommand_files.should_not be_empty
+ expect(@loader.subcommand_files).not_to be_empty
@loader.subcommand_files.each do |require_path|
- require_path.should match(/chef\/knife\/.*|plugins\/knife\/.*/)
+ expect(require_path).to match(/chef\/knife\/.*|plugins\/knife\/.*/)
end
end
it "finds files installed via rubygems" do
- @loader.find_subcommands_via_rubygems.should include('chef/knife/node_create')
- @loader.find_subcommands_via_rubygems.each {|rel_path, abs_path| abs_path.should match(%r[chef/knife/.+])}
+ expect(@loader.find_subcommands_via_rubygems).to include('chef/knife/node_create')
+ @loader.find_subcommands_via_rubygems.each {|rel_path, abs_path| expect(abs_path).to match(%r[chef/knife/.+])}
end
it "finds files from latest version of installed gems" do
@@ -44,74 +44,148 @@ describe Chef::Knife::SubcommandLoader do
'/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/ec2_base.rb',
'/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/ec2_otherstuff.rb'
]
- $LOAD_PATH.should_receive(:map).and_return([])
+ expect($LOAD_PATH).to receive(:map).and_return([])
if Gem::Specification.respond_to? :latest_specs
- Gem::Specification.should_receive(:latest_specs).with(true).and_return(gems)
- gems[0].should_receive(:matches_for_glob).with(/chef\/knife\/\*\.rb\{(.*),\.rb,(.*)\}/).and_return(gem_files)
+ expect(Gem::Specification).to receive(:latest_specs).with(true).and_return(gems)
+ expect(gems[0]).to receive(:matches_for_glob).with(/chef\/knife\/\*\.rb\{(.*),\.rb,(.*)\}/).and_return(gem_files)
else
- Gem.source_index.should_receive(:latest_specs).with(true).and_return(gems)
- gems[0].should_receive(:require_paths).twice.and_return(['lib'])
- gems[0].should_receive(:full_gem_path).and_return('/usr/lib/ruby/gems/knife-ec2-0.5.12')
- Dir.should_receive(:[]).with('/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/*.rb').and_return(gem_files)
+ expect(Gem.source_index).to receive(:latest_specs).with(true).and_return(gems)
+ expect(gems[0]).to receive(:require_paths).twice.and_return(['lib'])
+ expect(gems[0]).to receive(:full_gem_path).and_return('/usr/lib/ruby/gems/knife-ec2-0.5.12')
+ expect(Dir).to receive(:[]).with('/usr/lib/ruby/gems/knife-ec2-0.5.12/lib/chef/knife/*.rb').and_return(gem_files)
end
- @loader.should_receive(:find_subcommands_via_dirglob).and_return({})
- @loader.find_subcommands_via_rubygems.values.select { |file| file =~ /knife-ec2/ }.sort.should == gem_files
+ expect(@loader).to receive(:find_subcommands_via_dirglob).and_return({})
+ expect(@loader.find_subcommands_via_rubygems.values.select { |file| file =~ /knife-ec2/ }.sort).to eq(gem_files)
end
it "finds files using a dirglob when rubygems is not available" do
- @loader.find_subcommands_via_dirglob.should include('chef/knife/node_create')
- @loader.find_subcommands_via_dirglob.each {|rel_path, abs_path| abs_path.should match(%r[chef/knife/.+])}
+ expect(@loader.find_subcommands_via_dirglob).to include('chef/knife/node_create')
+ @loader.find_subcommands_via_dirglob.each {|rel_path, abs_path| expect(abs_path).to match(%r[chef/knife/.+])}
end
it "finds user-specific subcommands in the user's ~/.chef directory" do
expected_command = File.join(@home, '.chef', 'plugins', 'knife', 'example_home_subcommand.rb')
- @loader.site_subcommands.should include(expected_command)
+ expect(@loader.site_subcommands).to include(expected_command)
end
it "finds repo specific subcommands by searching for a .chef directory" do
expected_command = File.join(CHEF_SPEC_DATA, 'knife-site-subcommands', 'plugins', 'knife', 'example_subcommand.rb')
- @loader.site_subcommands.should include(expected_command)
+ expect(@loader.site_subcommands).to include(expected_command)
end
- describe "finding 3rd party plugins" do
+ # https://github.com/opscode/chef-dk/issues/227
+ #
+ # `knife` in ChefDK isn't from a gem install, it's directly run from a clone
+ # of the source, but there can be one or more versions of chef also installed
+ # as a gem. If the gem install contains a command that doesn't exist in the
+ # source tree of the "primary" chef install, it can be loaded and cause an
+ # error. We also want to ensure that we only load builtin commands from the
+ # "primary" chef install.
+ context "when a different version of chef is also installed as a gem" do
+
+ let(:all_found_commands) do
+ [
+ "/opt/chefdk/embedded/apps/chef/lib/chef/knife/bootstrap.rb",
+ "/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_bulk_delete.rb",
+ "/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_create.rb",
+
+ # We use the fake version 1.0.0 because that version doesn't exist,
+ # which ensures it won't ever equal "chef-#{Chef::VERSION}"
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/bootstrap.rb",
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/client_bulk_delete.rb",
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/client_create.rb",
+
+ # Test that we don't accept a version number that is different only in
+ # trailing characters, e.g. we are running Chef 12.0.0 but there is a
+ # Chef 12.0.0.rc.0 gem also:
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-#{Chef::VERSION}.rc.0/lib/chef/knife/thing.rb",
+
+ # This command is "extra" compared to what's in the embedded/apps/chef install:
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-1.0.0/lib/chef/knife/data_bag_secret_options.rb",
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-vault-2.2.4/lib/chef/knife/decrypt.rb",
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/knife-spork-1.4.1/lib/chef/knife/spork-bump.rb",
+
+ # These are fake commands that have names designed to test that the
+ # regex is strict enough
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-foo-#{Chef::VERSION}/lib/chef/knife/chef-foo.rb",
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/foo-chef-#{Chef::VERSION}/lib/chef/knife/foo-chef.rb",
+
+ # In a real scenario, we'd use rubygems APIs to only select the most
+ # recent gem, but for this test we want to check that we're doing the
+ # right thing both when the plugin version matches and does not match
+ # the current chef version. Looking at
+ # `SubcommandLoader::MATCHES_THIS_CHEF_GEM` and
+ # `SubcommandLoader::MATCHES_CHEF_GEM` should make it clear why we want
+ # to test these two cases.
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-bar-1.0.0/lib/chef/knife/chef-bar.rb",
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/bar-chef-1.0.0/lib/chef/knife/bar-chef.rb"
+ ]
+ end
+
+ let(:expected_valid_commands) do
+ [
+ "/opt/chefdk/embedded/apps/chef/lib/chef/knife/bootstrap.rb",
+ "/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_bulk_delete.rb",
+ "/opt/chefdk/embedded/apps/chef/lib/chef/knife/client_create.rb",
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-vault-2.2.4/lib/chef/knife/decrypt.rb",
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/knife-spork-1.4.1/lib/chef/knife/spork-bump.rb",
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-foo-#{Chef::VERSION}/lib/chef/knife/chef-foo.rb",
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/foo-chef-#{Chef::VERSION}/lib/chef/knife/foo-chef.rb",
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-bar-1.0.0/lib/chef/knife/chef-bar.rb",
+ "/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/bar-chef-1.0.0/lib/chef/knife/bar-chef.rb"
+ ]
+ end
+
+ before do
+ expect(@loader).to receive(:find_files_latest_gems).with("chef/knife/*.rb").and_return(all_found_commands)
+ expect(@loader).to receive(:find_subcommands_via_dirglob).and_return({})
+ end
+
+ it "ignores commands from the non-matching gem install" do
+ expect(@loader.find_subcommands_via_rubygems.values).to eq(expected_valid_commands)
+ end
+
+ end
+
+ describe "finding 3rd party plugins" do
let(:env_home) { "/home/alice" }
let(:manifest_path) { env_home + "/.chef/plugin_manifest.json" }
before do
env_dup = ENV.to_hash
- ENV.stub(:[]).and_return { |key| env_dup[key] }
- ENV.stub(:[]).with("HOME").and_return(env_home)
+ allow(ENV).to receive(:[]) { |key| env_dup[key] }
+ allow(ENV).to receive(:[]).with("HOME").and_return(env_home)
end
context "when there is not a ~/.chef/plugin_manifest.json file" do
before do
- File.stub(:exist?).with(manifest_path).and_return(false)
+ allow(File).to receive(:exist?).with(manifest_path).and_return(false)
end
it "searches rubygems for plugins" do
if Gem::Specification.respond_to?(:latest_specs)
- Gem::Specification.should_receive(:latest_specs).and_call_original
+ expect(Gem::Specification).to receive(:latest_specs).and_call_original
else
- Gem.source_index.should_receive(:latest_specs).and_call_original
+ expect(Gem.source_index).to receive(:latest_specs).and_call_original
end
@loader.subcommand_files.each do |require_path|
- require_path.should match(/chef\/knife\/.*|plugins\/knife\/.*/)
+ expect(require_path).to match(/chef\/knife\/.*|plugins\/knife\/.*/)
end
end
context "and HOME environment variable is not set" do
before do
- ENV.stub(:[]).with("HOME").and_return(nil)
+ allow(ENV).to receive(:[]).with("HOME").and_return(nil)
end
it "searches rubygems for plugins" do
if Gem::Specification.respond_to?(:latest_specs)
- Gem::Specification.should_receive(:latest_specs).and_call_original
+ expect(Gem::Specification).to receive(:latest_specs).and_call_original
else
- Gem.source_index.should_receive(:latest_specs).and_call_original
+ expect(Gem.source_index).to receive(:latest_specs).and_call_original
end
@loader.subcommand_files.each do |require_path|
- require_path.should match(/chef\/knife\/.*|plugins\/knife\/.*/)
+ expect(require_path).to match(/chef\/knife\/.*|plugins\/knife\/.*/)
end
end
end
@@ -135,13 +209,13 @@ describe Chef::Knife::SubcommandLoader do
let(:manifest_json) { Chef::JSONCompat.to_json(manifest_content) }
before do
- File.stub(:exist?).with(manifest_path).and_return(true)
- File.stub(:read).with(manifest_path).and_return(manifest_json)
+ allow(File).to receive(:exist?).with(manifest_path).and_return(true)
+ allow(File).to receive(:read).with(manifest_path).and_return(manifest_json)
end
it "uses paths from the manifest instead of searching gems" do
- Gem::Specification.should_not_receive(:latest_specs).and_call_original
- @loader.subcommand_files.should include(ec2_server_create_plugin)
+ expect(Gem::Specification).not_to receive(:latest_specs).and_call_original
+ expect(@loader.subcommand_files).to include(ec2_server_create_plugin)
end
end
diff --git a/spec/unit/knife/core/ui_spec.rb b/spec/unit/knife/core/ui_spec.rb
index ed1037ebd5..ac42ad6dd6 100644
--- a/spec/unit/knife/core/ui_spec.rb
+++ b/spec/unit/knife/core/ui_spec.rb
@@ -67,16 +67,16 @@ describe Chef::Knife::UI do
@ui.config[:disable_editing] = false
@ui.config[:editor] = my_editor
@mock = double('Tempfile')
- @mock.should_receive(:sync=).with(true)
- @mock.should_receive(:puts).with(json_from_ruby)
- @mock.should_receive(:close)
- @mock.should_receive(:path).at_least(:once).and_return(temp_path)
- Tempfile.should_receive(:open).with([ 'knife-edit-', '.json' ]).and_yield(@mock)
+ expect(@mock).to receive(:sync=).with(true)
+ expect(@mock).to receive(:puts).with(json_from_ruby)
+ expect(@mock).to receive(:close)
+ expect(@mock).to receive(:path).at_least(:once).and_return(temp_path)
+ expect(Tempfile).to receive(:open).with([ 'knife-edit-', '.json' ]).and_yield(@mock)
end
context "and the editor works" do
before do
- @ui.should_receive(:system).with("#{my_editor} #{temp_path}").and_return(true)
- IO.should_receive(:read).with(temp_path).and_return(json_from_editor)
+ expect(@ui).to receive(:system).with("#{my_editor} #{temp_path}").and_return(true)
+ expect(IO).to receive(:read).with(temp_path).and_return(json_from_editor)
end
context "when parse_output is false" do
@@ -93,8 +93,8 @@ describe Chef::Knife::UI do
end
context "when running the editor fails with nil" do
before do
- @ui.should_receive(:system).with("#{my_editor} #{temp_path}").and_return(nil)
- IO.should_not_receive(:read)
+ expect(@ui).to receive(:system).with("#{my_editor} #{temp_path}").and_return(nil)
+ expect(IO).not_to receive(:read)
end
it "throws an exception" do
expect{ subject }.to raise_error(RuntimeError)
@@ -102,8 +102,8 @@ describe Chef::Knife::UI do
end
context "when running the editor fails with false" do
before do
- @ui.should_receive(:system).with("#{my_editor} #{temp_path}").and_return(false)
- IO.should_not_receive(:read)
+ expect(@ui).to receive(:system).with("#{my_editor} #{temp_path}").and_return(false)
+ expect(IO).not_to receive(:read)
end
it "throws an exception" do
expect{ subject }.to raise_error(RuntimeError)
@@ -115,13 +115,13 @@ describe Chef::Knife::UI do
@ui.config[:disable_editing] = false
@ui.config[:editor] = my_editor
@tempfile = Tempfile.new([ 'knife-edit-', '.json' ])
- Tempfile.should_receive(:open).with([ 'knife-edit-', '.json' ]).and_yield(@tempfile)
+ expect(Tempfile).to receive(:open).with([ 'knife-edit-', '.json' ]).and_yield(@tempfile)
end
context "and the editor works" do
before do
- @ui.should_receive(:system).with("#{my_editor} #{@tempfile.path}").and_return(true)
- IO.should_receive(:read).with(@tempfile.path).and_return(json_from_editor)
+ expect(@ui).to receive(:system).with("#{my_editor} #{@tempfile.path}").and_return(true)
+ expect(IO).to receive(:read).with(@tempfile.path).and_return(json_from_editor)
end
context "when parse_output is false" do
@@ -153,33 +153,33 @@ describe Chef::Knife::UI do
describe "format_list_for_display" do
it "should print the full hash if --with-uri is true" do
@ui.config[:with_uri] = true
- @ui.format_list_for_display({ :marcy => :playground }).should == { :marcy => :playground }
+ expect(@ui.format_list_for_display({ :marcy => :playground })).to eq({ :marcy => :playground })
end
it "should print only the keys if --with-uri is false" do
@ui.config[:with_uri] = false
- @ui.format_list_for_display({ :marcy => :playground }).should == [ :marcy ]
+ expect(@ui.format_list_for_display({ :marcy => :playground })).to eq([ :marcy ])
end
end
shared_examples "an output mehthod handling IO exceptions" do |method|
it "should throw Errno::EIO exceptions" do
- @out.stub(:puts).and_raise(Errno::EIO)
- @err.stub(:puts).and_raise(Errno::EIO)
- lambda {@ui.send(method, "hi")}.should raise_error(Errno::EIO)
+ allow(@out).to receive(:puts).and_raise(Errno::EIO)
+ allow(@err).to receive(:puts).and_raise(Errno::EIO)
+ expect {@ui.send(method, "hi")}.to raise_error(Errno::EIO)
end
it "should ignore Errno::EPIPE exceptions (CHEF-3516)" do
- @out.stub(:puts).and_raise(Errno::EPIPE)
- @err.stub(:puts).and_raise(Errno::EPIPE)
- lambda {@ui.send(method, "hi")}.should raise_error(SystemExit)
+ allow(@out).to receive(:puts).and_raise(Errno::EPIPE)
+ allow(@err).to receive(:puts).and_raise(Errno::EPIPE)
+ expect {@ui.send(method, "hi")}.to raise_error(SystemExit)
end
it "should throw Errno::EPIPE exceptions with -VV (CHEF-3516)" do
@config[:verbosity] = 2
- @out.stub(:puts).and_raise(Errno::EPIPE)
- @err.stub(:puts).and_raise(Errno::EPIPE)
- lambda {@ui.send(method, "hi")}.should raise_error(Errno::EPIPE)
+ allow(@out).to receive(:puts).and_raise(Errno::EPIPE)
+ allow(@err).to receive(:puts).and_raise(Errno::EPIPE)
+ expect {@ui.send(method, "hi")}.to raise_error(Errno::EPIPE)
end
end
@@ -188,12 +188,12 @@ describe Chef::Knife::UI do
it "formats strings appropriately" do
@ui.output("hi")
- @out.string.should == "hi\n"
+ expect(@out.string).to eq("hi\n")
end
it "formats hashes appropriately" do
@ui.output({'hi' => 'a', 'lo' => 'b' })
- @out.string.should == <<EOM
+ expect(@out.string).to eq <<EOM
hi: a
lo: b
EOM
@@ -201,12 +201,12 @@ EOM
it "formats empty hashes appropriately" do
@ui.output({})
- @out.string.should == "\n"
+ expect(@out.string).to eq("\n")
end
it "formats arrays appropriately" do
@ui.output([ 'a', 'b' ])
- @out.string.should == <<EOM
+ expect(@out.string).to eq <<EOM
a
b
EOM
@@ -214,22 +214,22 @@ EOM
it "formats empty arrays appropriately" do
@ui.output([ ])
- @out.string.should == "\n"
+ expect(@out.string).to eq("\n")
end
it "formats single-member arrays appropriately" do
@ui.output([ 'a' ])
- @out.string.should == "a\n"
+ expect(@out.string).to eq("a\n")
end
it "formats nested single-member arrays appropriately" do
@ui.output([ [ 'a' ] ])
- @out.string.should == "a\n"
+ expect(@out.string).to eq("a\n")
end
it "formats nested arrays appropriately" do
@ui.output([ [ 'a', 'b' ], [ 'c', 'd' ]])
- @out.string.should == <<EOM
+ expect(@out.string).to eq <<EOM
a
b
@@ -240,7 +240,7 @@ EOM
it "formats nested arrays with single- and empty subarrays appropriately" do
@ui.output([ [ 'a', 'b' ], [ 'c' ], [], [ 'd', 'e' ]])
- @out.string.should == <<EOM
+ expect(@out.string).to eq <<EOM
a
b
@@ -254,7 +254,7 @@ EOM
it "formats arrays of hashes with extra lines in between for readability" do
@ui.output([ { 'a' => 'b', 'c' => 'd' }, { 'x' => 'y' }, { 'm' => 'n', 'o' => 'p' }])
- @out.string.should == <<EOM
+ expect(@out.string).to eq <<EOM
a: b
c: d
@@ -267,7 +267,7 @@ EOM
it "formats hashes with empty array members appropriately" do
@ui.output({ 'a' => [], 'b' => 'c' })
- @out.string.should == <<EOM
+ expect(@out.string).to eq <<EOM
a:
b: c
EOM
@@ -275,7 +275,7 @@ EOM
it "formats hashes with single-member array values appropriately" do
@ui.output({ 'a' => [ 'foo' ], 'b' => 'c' })
- @out.string.should == <<EOM
+ expect(@out.string).to eq <<EOM
a: foo
b: c
EOM
@@ -283,7 +283,7 @@ EOM
it "formats hashes with array members appropriately" do
@ui.output({ 'a' => [ 'foo', 'bar' ], 'b' => 'c' })
- @out.string.should == <<EOM
+ expect(@out.string).to eq <<EOM
a:
foo
bar
@@ -293,7 +293,7 @@ EOM
it "formats hashes with single-member nested array values appropriately" do
@ui.output({ 'a' => [ [ 'foo' ] ], 'b' => 'c' })
- @out.string.should == <<EOM
+ expect(@out.string).to eq <<EOM
a:
foo
b: c
@@ -304,12 +304,12 @@ EOM
@ui.output({ 'a' => [ [ 'foo', 'bar' ], [ 'baz', 'bjork' ] ], 'b' => 'c' })
# XXX: using a HEREDOC at this point results in a line with required spaces which auto-whitespace removal settings
# on editors will remove and will break this test.
- @out.string.should == "a:\n foo\n bar\n \n baz\n bjork\nb: c\n"
+ expect(@out.string).to eq("a:\n foo\n bar\n \n baz\n bjork\nb: c\n")
end
it "formats hashes with hash values appropriately" do
@ui.output({ 'a' => { 'aa' => 'bb', 'cc' => 'dd' }, 'b' => 'c' })
- @out.string.should == <<EOM
+ expect(@out.string).to eq <<EOM
a:
aa: bb
cc: dd
@@ -319,7 +319,7 @@ EOM
it "formats hashes with empty hash values appropriately" do
@ui.output({ 'a' => { }, 'b' => 'c' })
- @out.string.should == <<EOM
+ expect(@out.string).to eq <<EOM
a:
b: c
EOM
@@ -341,20 +341,32 @@ EOM
describe "format_for_display" do
it "should return the raw data" do
input = { :gi => :go }
- @ui.format_for_display(input).should == input
+ expect(@ui.format_for_display(input)).to eq(input)
end
describe "with --attribute passed" do
it "should return the deeply nested attribute" do
input = { "gi" => { "go" => "ge" }, "id" => "sample-data-bag-item" }
@ui.config[:attribute] = "gi.go"
- @ui.format_for_display(input).should == { "sample-data-bag-item" => { "gi.go" => "ge" } }
+ expect(@ui.format_for_display(input)).to eq({ "sample-data-bag-item" => { "gi.go" => "ge" } })
end
it "should return multiple attributes" do
input = { "gi" => "go", "hi" => "ho", "id" => "sample-data-bag-item" }
@ui.config[:attribute] = ["gi", "hi"]
- @ui.format_for_display(input).should == { "sample-data-bag-item" => { "gi" => "go", "hi"=> "ho" } }
+ expect(@ui.format_for_display(input)).to eq({ "sample-data-bag-item" => { "gi" => "go", "hi"=> "ho" } })
+ end
+
+ it "should handle attributes named the same as methods" do
+ input = { "keys" => "values", "hi" => "ho", "id" => "sample-data-bag-item" }
+ @ui.config[:attribute] = "keys"
+ expect(@ui.format_for_display(input)).to eq({ "sample-data-bag-item" => { "keys" => "values" } })
+ end
+
+ it "should handle nested attributes named the same as methods" do
+ input = { "keys" => {"keys" => "values"}, "hi" => "ho", "id" => "sample-data-bag-item" }
+ @ui.config[:attribute] = "keys.keys"
+ expect(@ui.format_for_display(input)).to eq({ "sample-data-bag-item" => { "keys.keys" => "values" } })
end
end
@@ -365,8 +377,8 @@ EOM
input.run_list("role[monkey]", "role[churchmouse]")
@ui.config[:run_list] = true
response = @ui.format_for_display(input)
- response["sample-node"]["run_list"][0].should == "role[monkey]"
- response["sample-node"]["run_list"][1].should == "role[churchmouse]"
+ expect(response["sample-node"]["run_list"][0]).to eq("role[monkey]")
+ expect(response["sample-node"]["run_list"][1]).to eq("role[churchmouse]")
end
end
end
@@ -388,7 +400,7 @@ EOM
it "should return an array of the cookbooks with versions" do
expected_response = [ "cookbook_name 3.0.0 2.0.0 1.0.0" ]
response = @ui.format_cookbook_list_for_display(@item)
- response.should == expected_response
+ expect(response).to eq(expected_response)
end
describe "with --with-uri" do
@@ -400,15 +412,15 @@ EOM
"3.0.0" => "http://url/cookbooks/3.0.0"}
}
@ui.config[:with_uri] = true
- @ui.format_cookbook_list_for_display(@item).should == response
+ expect(@ui.format_cookbook_list_for_display(@item)).to eq(response)
end
end
context "when running on Windows" do
before(:each) do
stdout = double('StringIO', :tty? => true)
- @ui.stub(:stdout).and_return(stdout)
- Chef::Platform.stub(:windows?) { true }
+ allow(@ui).to receive(:stdout).and_return(stdout)
+ allow(Chef::Platform).to receive(:windows?) { true }
Chef::Config.reset
end
@@ -444,36 +456,36 @@ EOM
let(:append_instructions) { true }
def run_confirm
- @ui.stub(:stdout).and_return(stdout)
- @ui.stdin.stub(:readline).and_return(answer)
+ allow(@ui).to receive(:stdout).and_return(stdout)
+ allow(@ui.stdin).to receive(:readline).and_return(answer)
@ui.confirm(question, append_instructions, default_choice)
end
def run_confirm_without_exit
- @ui.stub(:stdout).and_return(stdout)
- @ui.stdin.stub(:readline).and_return(answer)
+ allow(@ui).to receive(:stdout).and_return(stdout)
+ allow(@ui.stdin).to receive(:readline).and_return(answer)
@ui.confirm_without_exit(question, append_instructions, default_choice)
end
shared_examples_for "confirm with positive answer" do
it "confirm should return true" do
- run_confirm.should be_true
+ expect(run_confirm).to be_truthy
end
it "confirm_without_exit should return true" do
- run_confirm_without_exit.should be_true
+ expect(run_confirm_without_exit).to be_truthy
end
end
shared_examples_for "confirm with negative answer" do
it "confirm should exit 3" do
- lambda {
+ expect {
run_confirm
- }.should raise_error(SystemExit) { |e| e.status.should == 3 }
+ }.to raise_error(SystemExit) { |e| expect(e.status).to eq(3) }
end
it "confirm_without_exit should return false" do
- run_confirm_without_exit.should be_false
+ expect(run_confirm_without_exit).to be_falsey
end
end
@@ -482,7 +494,7 @@ EOM
it "should show 'Y/n' in the instructions" do
run_confirm
- output.should include("Y/n")
+ expect(output).to include("Y/n")
end
describe "with empty answer" do
@@ -503,7 +515,7 @@ EOM
it "should show 'y/N' in the instructions" do
run_confirm
- output.should include("y/N")
+ expect(output).to include("y/N")
end
describe "with empty answer" do
@@ -538,8 +550,8 @@ EOM
describe "with --y or --yes passed" do
it "should return true" do
@ui.config[:yes] = true
- run_confirm.should be_true
- output.should eq("")
+ expect(run_confirm).to be_truthy
+ expect(output).to eq("")
end
end
end
@@ -547,18 +559,18 @@ EOM
describe "when asking for free-form user input" do
it "asks a question and returns the answer provided by the user" do
out = StringIO.new
- @ui.stub(:stdout).and_return(out)
- @ui.stub(:stdin).and_return(StringIO.new("http://mychefserver.example.com\n"))
- @ui.ask_question("your chef server URL?").should == "http://mychefserver.example.com"
- out.string.should == "your chef server URL?"
+ allow(@ui).to receive(:stdout).and_return(out)
+ allow(@ui).to receive(:stdin).and_return(StringIO.new("http://mychefserver.example.com\n"))
+ expect(@ui.ask_question("your chef server URL?")).to eq("http://mychefserver.example.com")
+ expect(out.string).to eq("your chef server URL?")
end
it "suggests a default setting and returns the default when the user's response only contains whitespace" do
out = StringIO.new
- @ui.stub(:stdout).and_return(out)
- @ui.stub(:stdin).and_return(StringIO.new(" \n"))
- @ui.ask_question("your chef server URL? ", :default => 'http://localhost:4000').should == "http://localhost:4000"
- out.string.should == "your chef server URL? [http://localhost:4000] "
+ allow(@ui).to receive(:stdout).and_return(out)
+ allow(@ui).to receive(:stdin).and_return(StringIO.new(" \n"))
+ expect(@ui.ask_question("your chef server URL? ", :default => 'http://localhost:4000')).to eq("http://localhost:4000")
+ expect(out.string).to eq("your chef server URL? [http://localhost:4000] ")
end
end
diff --git a/spec/unit/knife/data_bag_from_file_spec.rb b/spec/unit/knife/data_bag_from_file_spec.rb
index 8de046e7a4..3882bff349 100644
--- a/spec/unit/knife/data_bag_from_file_spec.rb
+++ b/spec/unit/knife/data_bag_from_file_spec.rb
@@ -26,7 +26,7 @@ Chef::Knife::DataBagFromFile.load_deps
describe Chef::Knife::DataBagFromFile do
before :each do
- Chef::Platform.stub(:windows?) { false }
+ allow(Chef::Platform).to receive(:windows?) { false }
Chef::Config[:node_name] = "webmonkey.example.com"
FileUtils.mkdir_p([db_folder, db_folder2])
db_file.write(Chef::JSONCompat.to_json(plain_data))
diff --git a/spec/unit/knife/environment_compare_spec.rb b/spec/unit/knife/environment_compare_spec.rb
index 3606b617a9..6d4d3ead52 100644
--- a/spec/unit/knife/environment_compare_spec.rb
+++ b/spec/unit/knife/environment_compare_spec.rb
@@ -27,21 +27,21 @@ describe Chef::Knife::EnvironmentCompare do
"citm" => "http://localhost:4000/environments/citm"
}
- @knife.stub(:environment_list).and_return(@environments)
+ allow(@knife).to receive(:environment_list).and_return(@environments)
@constraints = {
"cita" => { "foo" => "= 1.0.1", "bar" => "= 0.0.4" },
"citm" => { "foo" => "= 1.0.1", "bar" => "= 0.0.2" }
}
- @knife.stub(:constraint_list).and_return(@constraints)
+ allow(@knife).to receive(:constraint_list).and_return(@constraints)
@cookbooks = { "foo"=>"= 1.0.1", "bar"=>"= 0.0.1" }
- @knife.stub(:cookbook_list).and_return(@cookbooks)
+ allow(@knife).to receive(:cookbook_list).and_return(@cookbooks)
@rest_double = double('rest')
- @knife.stub(:rest).and_return(@rest_double)
+ allow(@knife).to receive(:rest).and_return(@rest_double)
@cookbook_names = ['apache2', 'mysql', 'foo', 'bar', 'dummy', 'chef_handler']
@base_url = 'https://server.example.com/cookbooks'
@cookbook_data = {}
@@ -51,10 +51,10 @@ describe Chef::Knife::EnvironmentCompare do
'url' => "#{@base_url}/#{item}/1.0.1"}]}
end
- @rest_double.stub(:get_rest).with("/cookbooks?num_versions=1").and_return(@cookbook_data)
+ allow(@rest_double).to receive(:get_rest).with("/cookbooks?num_versions=1").and_return(@cookbook_data)
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
describe 'run' do
@@ -62,14 +62,14 @@ describe Chef::Knife::EnvironmentCompare do
@knife.config[:format] = 'summary'
@knife.run
@environments.each do |item, url|
- @stdout.string.should match /#{item}/ and @stdout.string.lines.count.should be 4
+ expect(@stdout.string).to match /#{item}/ and expect(@stdout.string.lines.count).to be 4
end
end
it 'should display 4 number of lines' do
@knife.config[:format] = 'summary'
@knife.run
- @stdout.string.lines.count.should be 4
+ expect(@stdout.string.lines.count).to be 4
end
end
@@ -79,7 +79,7 @@ describe Chef::Knife::EnvironmentCompare do
@knife.config[:mismatch] = true
@knife.run
@constraints.each do |item, ver|
- @stdout.string.should match /#{ver[1]}/
+ expect(@stdout.string).to match /#{ver[1]}/
end
end
@@ -87,7 +87,7 @@ describe Chef::Knife::EnvironmentCompare do
@knife.config[:format] = 'summary'
@knife.config[:mismatch] = true
@knife.run
- @stdout.string.lines.count.should be 3
+ expect(@stdout.string.lines.count).to be 3
end
end
@@ -97,7 +97,7 @@ describe Chef::Knife::EnvironmentCompare do
@knife.config[:all] = true
@knife.run
@constraints.each do |item, ver|
- @stdout.string.should match /#{ver[1]}/
+ expect(@stdout.string).to match /#{ver[1]}/
end
end
@@ -105,7 +105,7 @@ describe Chef::Knife::EnvironmentCompare do
@knife.config[:format] = 'summary'
@knife.config[:all] = true
@knife.run
- @stdout.string.lines.count.should be 8
+ expect(@stdout.string.lines.count).to be 8
end
end
diff --git a/spec/unit/knife/environment_create_spec.rb b/spec/unit/knife/environment_create_spec.rb
index 81bf6731b7..04e45048ef 100644
--- a/spec/unit/knife/environment_create_spec.rb
+++ b/spec/unit/knife/environment_create_spec.rb
@@ -21,49 +21,49 @@ require 'spec_helper'
describe Chef::Knife::EnvironmentCreate do
before(:each) do
@knife = Chef::Knife::EnvironmentCreate.new
- @knife.stub(:msg).and_return true
- @knife.stub(:output).and_return true
- @knife.stub(:show_usage).and_return true
+ allow(@knife).to receive(:msg).and_return true
+ allow(@knife).to receive(:output).and_return true
+ allow(@knife).to receive(:show_usage).and_return true
@knife.name_args = [ "production" ]
@environment = Chef::Environment.new
- @environment.stub(:save)
+ allow(@environment).to receive(:save)
- Chef::Environment.stub(:new).and_return @environment
- @knife.stub(:edit_data).and_return @environment
+ allow(Chef::Environment).to receive(:new).and_return @environment
+ allow(@knife).to receive(:edit_data).and_return @environment
end
describe "run" do
it "should create a new environment" do
- Chef::Environment.should_receive(:new)
+ expect(Chef::Environment).to receive(:new)
@knife.run
end
it "should set the environment name" do
- @environment.should_receive(:name).with("production")
+ expect(@environment).to receive(:name).with("production")
@knife.run
end
it "should not print the environment" do
- @knife.should_not_receive(:output)
+ expect(@knife).not_to receive(:output)
@knife.run
end
it "should prompt you to edit the data" do
- @knife.should_receive(:edit_data).with(@environment)
+ expect(@knife).to receive(:edit_data).with(@environment)
@knife.run
end
it "should save the environment" do
- @environment.should_receive(:save)
+ expect(@environment).to receive(:save)
@knife.run
end
it "should show usage and exit when no environment name is provided" do
@knife.name_args = [ ]
- @knife.ui.should_receive(:fatal)
- @knife.should_receive(:show_usage)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife.ui).to receive(:fatal)
+ expect(@knife).to receive(:show_usage)
+ expect { @knife.run }.to raise_error(SystemExit)
end
describe "with --description" do
@@ -72,7 +72,7 @@ describe Chef::Knife::EnvironmentCreate do
end
it "should set the description" do
- @environment.should_receive(:description).with("This is production")
+ expect(@environment).to receive(:description).with("This is production")
@knife.run
end
end
@@ -83,7 +83,7 @@ describe Chef::Knife::EnvironmentCreate do
end
it "should pretty print the environment, formatted for display" do
- @knife.should_receive(:output).with(@environment)
+ expect(@knife).to receive(:output).with(@environment)
@knife.run
end
end
diff --git a/spec/unit/knife/environment_delete_spec.rb b/spec/unit/knife/environment_delete_spec.rb
index 0f6b5f3272..95df6e15fe 100644
--- a/spec/unit/knife/environment_delete_spec.rb
+++ b/spec/unit/knife/environment_delete_spec.rb
@@ -21,50 +21,50 @@ require 'spec_helper'
describe Chef::Knife::EnvironmentDelete do
before(:each) do
@knife = Chef::Knife::EnvironmentDelete.new
- @knife.stub(:msg).and_return true
- @knife.stub(:output).and_return true
- @knife.stub(:show_usage).and_return true
- @knife.stub(:confirm).and_return true
+ allow(@knife).to receive(:msg).and_return true
+ allow(@knife).to receive(:output).and_return true
+ allow(@knife).to receive(:show_usage).and_return true
+ allow(@knife).to receive(:confirm).and_return true
@knife.name_args = [ "production" ]
@environment = Chef::Environment.new
@environment.name("production")
@environment.description("Please delete me")
- @environment.stub(:destroy).and_return true
- Chef::Environment.stub(:load).and_return @environment
+ allow(@environment).to receive(:destroy).and_return true
+ allow(Chef::Environment).to receive(:load).and_return @environment
end
it "should confirm that you want to delete" do
- @knife.should_receive(:confirm)
+ expect(@knife).to receive(:confirm)
@knife.run
end
it "should load the environment" do
- Chef::Environment.should_receive(:load).with("production")
+ expect(Chef::Environment).to receive(:load).with("production")
@knife.run
end
it "should delete the environment" do
- @environment.should_receive(:destroy)
+ expect(@environment).to receive(:destroy)
@knife.run
end
it "should not print the environment" do
- @knife.should_not_receive(:output)
+ expect(@knife).not_to receive(:output)
@knife.run
end
it "should show usage and exit when no environment name is provided" do
@knife.name_args = []
- @knife.ui.should_receive(:fatal)
- @knife.should_receive(:show_usage)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife.ui).to receive(:fatal)
+ expect(@knife).to receive(:show_usage)
+ expect { @knife.run }.to raise_error(SystemExit)
end
describe "with --print-after" do
it "should pretty print the environment, formatted for display" do
@knife.config[:print_after] = true
- @knife.should_receive(:output).with(@environment)
+ expect(@knife).to receive(:output).with(@environment)
@knife.run
end
end
diff --git a/spec/unit/knife/environment_edit_spec.rb b/spec/unit/knife/environment_edit_spec.rb
index a82ead0b6b..61c2663a41 100644
--- a/spec/unit/knife/environment_edit_spec.rb
+++ b/spec/unit/knife/environment_edit_spec.rb
@@ -21,26 +21,26 @@ require 'spec_helper'
describe Chef::Knife::EnvironmentEdit do
before(:each) do
@knife = Chef::Knife::EnvironmentEdit.new
- @knife.ui.stub(:msg).and_return true
- @knife.ui.stub(:output).and_return true
- @knife.ui.stub(:show_usage).and_return true
+ allow(@knife.ui).to receive(:msg).and_return true
+ allow(@knife.ui).to receive(:output).and_return true
+ allow(@knife.ui).to receive(:show_usage).and_return true
@knife.name_args = [ "production" ]
@environment = Chef::Environment.new
@environment.name("production")
@environment.description("Please edit me")
- @environment.stub(:save).and_return true
- Chef::Environment.stub(:load).and_return @environment
- @knife.ui.stub(:edit_data).and_return @environment
+ allow(@environment).to receive(:save).and_return true
+ allow(Chef::Environment).to receive(:load).and_return @environment
+ allow(@knife.ui).to receive(:edit_data).and_return @environment
end
it "should load the environment" do
- Chef::Environment.should_receive(:load).with("production")
+ expect(Chef::Environment).to receive(:load).with("production")
@knife.run
end
it "should let you edit the environment" do
- @knife.ui.should_receive(:edit_data).with(@environment)
+ expect(@knife.ui).to receive(:edit_data).with(@environment)
@knife.run
end
@@ -48,31 +48,31 @@ describe Chef::Knife::EnvironmentEdit do
pansy = Chef::Environment.new
@environment.name("new_environment_name")
- @knife.ui.should_receive(:edit_data).with(@environment).and_return(pansy)
- pansy.should_receive(:save)
+ expect(@knife.ui).to receive(:edit_data).with(@environment).and_return(pansy)
+ expect(pansy).to receive(:save)
@knife.run
end
it "should not save the unedited environment data" do
- @environment.should_not_receive(:save)
+ expect(@environment).not_to receive(:save)
@knife.run
end
it "should not print the environment" do
- @knife.should_not_receive(:output)
+ expect(@knife).not_to receive(:output)
@knife.run
end
it "shoud show usage and exit when no environment name is provided" do
@knife.name_args = []
- @knife.should_receive(:show_usage)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:show_usage)
+ expect { @knife.run }.to raise_error(SystemExit)
end
describe "with --print-after" do
it "should pretty print the environment, formatted for display" do
@knife.config[:print_after] = true
- @knife.ui.should_receive(:output).with(@environment)
+ expect(@knife.ui).to receive(:output).with(@environment)
@knife.run
end
end
diff --git a/spec/unit/knife/environment_from_file_spec.rb b/spec/unit/knife/environment_from_file_spec.rb
index 562e7f8cf5..d150e5ee64 100644
--- a/spec/unit/knife/environment_from_file_spec.rb
+++ b/spec/unit/knife/environment_from_file_spec.rb
@@ -23,24 +23,24 @@ Chef::Knife::EnvironmentFromFile.load_deps
describe Chef::Knife::EnvironmentFromFile do
before(:each) do
- Chef::Platform.stub(:windows?) { false }
+ allow(Chef::Platform).to receive(:windows?) { false }
@knife = Chef::Knife::EnvironmentFromFile.new
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
@knife.name_args = [ "spec.rb" ]
@environment = Chef::Environment.new
@environment.name("spec")
@environment.description("runs the unit tests")
@environment.cookbook_versions({"apt" => "= 1.2.3"})
- @environment.stub(:save).and_return true
- @knife.loader.stub(:load_from).and_return @environment
+ allow(@environment).to receive(:save).and_return true
+ allow(@knife.loader).to receive(:load_from).and_return @environment
end
describe "run" do
it "loads the environment data from a file and saves it" do
- @knife.loader.should_receive(:load_from).with('environments', 'spec.rb').and_return(@environment)
- @environment.should_receive(:save)
+ expect(@knife.loader).to receive(:load_from).with('environments', 'spec.rb').and_return(@environment)
+ expect(@environment).to receive(:save)
@knife.run
end
@@ -48,41 +48,41 @@ describe Chef::Knife::EnvironmentFromFile do
before(:each) do
@env_apple = @environment.dup
@env_apple.name("apple")
- @knife.loader.stub(:load_from).with("apple.rb").and_return @env_apple
+ allow(@knife.loader).to receive(:load_from).with("apple.rb").and_return @env_apple
end
it "loads multiple environments if given" do
@knife.name_args = [ "spec.rb", "apple.rb" ]
- @environment.should_receive(:save).twice
+ expect(@environment).to receive(:save).twice
@knife.run
end
it "loads all environments with -a" do
- File.stub(:expand_path).with("./environments/").and_return("/tmp/environments")
- Dir.stub(:glob).with("/tmp/environments/*.{json,rb}").and_return(["spec.rb", "apple.rb"])
+ allow(File).to receive(:expand_path).with("./environments/").and_return("/tmp/environments")
+ allow(Dir).to receive(:glob).with("/tmp/environments/*.{json,rb}").and_return(["spec.rb", "apple.rb"])
@knife.name_args = []
- @knife.stub(:config).and_return({:all => true})
- @environment.should_receive(:save).twice
+ allow(@knife).to receive(:config).and_return({:all => true})
+ expect(@environment).to receive(:save).twice
@knife.run
end
end
it "should not print the environment" do
- @knife.should_not_receive(:output)
+ expect(@knife).not_to receive(:output)
@knife.run
end
it "should show usage and exit if not filename is provided" do
@knife.name_args = []
- @knife.ui.should_receive(:fatal)
- @knife.should_receive(:show_usage)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife.ui).to receive(:fatal)
+ expect(@knife).to receive(:show_usage)
+ expect { @knife.run }.to raise_error(SystemExit)
end
describe "with --print-after" do
it "should pretty print the environment, formatted for display" do
@knife.config[:print_after] = true
- @knife.should_receive(:output)
+ expect(@knife).to receive(:output)
@knife.run
end
end
diff --git a/spec/unit/knife/environment_list_spec.rb b/spec/unit/knife/environment_list_spec.rb
index 25d2714d23..6488a073b6 100644
--- a/spec/unit/knife/environment_list_spec.rb
+++ b/spec/unit/knife/environment_list_spec.rb
@@ -21,33 +21,33 @@ require 'spec_helper'
describe Chef::Knife::EnvironmentList do
before(:each) do
@knife = Chef::Knife::EnvironmentList.new
- @knife.stub(:msg).and_return true
- @knife.stub(:output).and_return true
- @knife.stub(:show_usage).and_return true
+ allow(@knife).to receive(:msg).and_return true
+ allow(@knife).to receive(:output).and_return true
+ allow(@knife).to receive(:show_usage).and_return true
@environments = {
"production" => "http://localhost:4000/environments/production",
"development" => "http://localhost:4000/environments/development",
"testing" => "http://localhost:4000/environments/testing"
}
- Chef::Environment.stub(:list).and_return @environments
+ allow(Chef::Environment).to receive(:list).and_return @environments
end
it "should make an api call to list the environments" do
- Chef::Environment.should_receive(:list)
+ expect(Chef::Environment).to receive(:list)
@knife.run
end
it "should print the environment names in a sorted list" do
names = @environments.keys.sort { |a,b| a <=> b }
- @knife.should_receive(:output).with(names)
+ expect(@knife).to receive(:output).with(names)
@knife.run
end
describe "with --with-uri" do
it "should print and unsorted list of the environments and their URIs" do
@knife.config[:with_uri] = true
- @knife.should_receive(:output).with(@environments)
+ expect(@knife).to receive(:output).with(@environments)
@knife.run
end
end
diff --git a/spec/unit/knife/environment_show_spec.rb b/spec/unit/knife/environment_show_spec.rb
index c7b0c21657..caac958f8e 100644
--- a/spec/unit/knife/environment_show_spec.rb
+++ b/spec/unit/knife/environment_show_spec.rb
@@ -21,32 +21,32 @@ require 'spec_helper'
describe Chef::Knife::EnvironmentShow do
before(:each) do
@knife = Chef::Knife::EnvironmentShow.new
- @knife.stub(:msg).and_return true
- @knife.stub(:output).and_return true
- @knife.stub(:show_usage).and_return true
+ allow(@knife).to receive(:msg).and_return true
+ allow(@knife).to receive(:output).and_return true
+ allow(@knife).to receive(:show_usage).and_return true
@knife.name_args = [ "production" ]
@environment = Chef::Environment.new
@environment.name("production")
@environment.description("Look at me!")
- Chef::Environment.stub(:load).and_return @environment
+ allow(Chef::Environment).to receive(:load).and_return @environment
end
it "should load the environment" do
- Chef::Environment.should_receive(:load).with("production")
+ expect(Chef::Environment).to receive(:load).with("production")
@knife.run
end
it "should pretty print the environment, formatted for display" do
- @knife.should_receive(:format_for_display).with(@environment)
- @knife.should_receive(:output)
+ expect(@knife).to receive(:format_for_display).with(@environment)
+ expect(@knife).to receive(:output)
@knife.run
end
it "should show usage and exit when no environment name is provided" do
@knife.name_args = []
- @knife.ui.should_receive(:fatal)
- @knife.should_receive(:show_usage)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife.ui).to receive(:fatal)
+ expect(@knife).to receive(:show_usage)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
diff --git a/spec/unit/knife/index_rebuild_spec.rb b/spec/unit/knife/index_rebuild_spec.rb
index 3a8ec00651..6c3b60bd88 100644
--- a/spec/unit/knife/index_rebuild_spec.rb
+++ b/spec/unit/knife/index_rebuild_spec.rb
@@ -24,18 +24,18 @@ describe Chef::Knife::IndexRebuild do
let(:rest_client){double(Chef::REST)}
let(:stub_rest!) do
- knife.should_receive(:rest).and_return(rest_client)
+ expect(knife).to receive(:rest).and_return(rest_client)
end
before :each do
# This keeps the test output clean
- knife.ui.stub(:stdout).and_return(StringIO.new)
+ allow(knife.ui).to receive(:stdout).and_return(StringIO.new)
end
context "#grab_api_info" do
let(:http_not_found_response) do
e = Net::HTTPNotFound.new("1.1", 404, "blah")
- e.stub(:[]).with("x-ops-api-info").and_return(api_header_value)
+ allow(e).to receive(:[]).with("x-ops-api-info").and_return(api_header_value)
e
end
@@ -45,20 +45,20 @@ describe Chef::Knife::IndexRebuild do
before(:each) do
stub_rest!
- rest_client.stub(:get_rest).and_raise(http_server_exception)
+ allow(rest_client).to receive(:get_rest).and_raise(http_server_exception)
end
context "against a Chef 11 server" do
let(:api_header_value){"flavor=osc;version=11.0.0;erchef=1.2.3"}
it "retrieves API information" do
- knife.grab_api_info.should == {"flavor" => "osc", "version" => "11.0.0", "erchef" => "1.2.3"}
+ expect(knife.grab_api_info).to eq({"flavor" => "osc", "version" => "11.0.0", "erchef" => "1.2.3"})
end
end # Chef 11
context "against a Chef 10 server" do
let(:api_header_value){nil}
it "finds no API information" do
- knife.grab_api_info.should == {}
+ expect(knife.grab_api_info).to eq({})
end
end # Chef 10
end # grab_api_info
@@ -66,18 +66,18 @@ describe Chef::Knife::IndexRebuild do
context "#unsupported_version?" do
context "with Chef 11 API metadata" do
it "is unsupported" do
- knife.unsupported_version?({"version" => "11.0.0", "flavor" => "osc", "erchef" => "1.2.3"}).should be_true
+ expect(knife.unsupported_version?({"version" => "11.0.0", "flavor" => "osc", "erchef" => "1.2.3"})).to be_truthy
end
it "only truly relies on the version being non-nil" do
- knife.unsupported_version?({"version" => "1", "flavor" => "osc", "erchef" => "1.2.3"}).should be_true
+ expect(knife.unsupported_version?({"version" => "1", "flavor" => "osc", "erchef" => "1.2.3"})).to be_truthy
end
end
context "with Chef 10 API metadata" do
it "is supported" do
# Chef 10 will have no metadata
- knife.unsupported_version?({}).should be_false
+ expect(knife.unsupported_version?({})).to be_falsey
end
end
end # unsupported_version?
@@ -85,7 +85,7 @@ describe Chef::Knife::IndexRebuild do
context "Simulating a 'knife index rebuild' run" do
before :each do
- knife.should_receive(:grab_api_info).and_return(api_info)
+ expect(knife).to receive(:grab_api_info).and_return(api_info)
server_specific_stubs!
end
@@ -97,8 +97,8 @@ describe Chef::Knife::IndexRebuild do
}
end
let(:server_specific_stubs!) do
- knife.should_receive(:unsupported_server_message).with(api_info)
- knife.should_receive(:exit).with(1)
+ expect(knife).to receive(:unsupported_server_message).with(api_info)
+ expect(knife).to receive(:exit).with(1)
end
it "should not be allowed" do
@@ -110,11 +110,11 @@ describe Chef::Knife::IndexRebuild do
let(:api_info){ {} }
let(:server_specific_stubs!) do
stub_rest!
- rest_client.should_receive(:post_rest).with("/search/reindex", {}).and_return("representative output")
- knife.should_not_receive(:unsupported_server_message)
- knife.should_receive(:deprecated_server_message)
- knife.should_receive(:nag)
- knife.should_receive(:output).with("representative output")
+ expect(rest_client).to receive(:post_rest).with("/search/reindex", {}).and_return("representative output")
+ expect(knife).not_to receive(:unsupported_server_message)
+ expect(knife).to receive(:deprecated_server_message)
+ expect(knife).to receive(:nag)
+ expect(knife).to receive(:output).with("representative output")
end
it "should be allowed" do
knife.run
diff --git a/spec/unit/knife/knife_help.rb b/spec/unit/knife/knife_help.rb
index e66a44801b..293bae17f4 100644
--- a/spec/unit/knife/knife_help.rb
+++ b/spec/unit/knife/knife_help.rb
@@ -26,66 +26,66 @@ describe Chef::Knife::Help do
end
it "should return a list of help topics" do
- @knife.help_topics.should include("knife-status")
+ expect(@knife.help_topics).to include("knife-status")
end
it "should run man for you" do
@knife.name_args = [ "shell" ]
- @knife.should_receive(:exec).with(/^man \/.*\/shell.1$/)
+ expect(@knife).to receive(:exec).with(/^man \/.*\/shell.1$/)
@knife.run
end
it "should suggest topics" do
@knife.name_args = [ "list" ]
- @knife.ui.stub(:msg)
- @knife.ui.should_receive(:info).with("Available help topics are: ")
- @knife.ui.should_receive(:msg).with(/knife/)
- @knife.stub(:exec)
- @knife.should_receive(:exit).with(1)
+ allow(@knife.ui).to receive(:msg)
+ expect(@knife.ui).to receive(:info).with("Available help topics are: ")
+ expect(@knife.ui).to receive(:msg).with(/knife/)
+ allow(@knife).to receive(:exec)
+ expect(@knife).to receive(:exit).with(1)
@knife.run
end
describe "find_manpage_path" do
it "should find the man page in the gem" do
- @knife.find_manpage_path("shell").should =~ /distro\/common\/man\/man1\/chef-shell.1$/
+ expect(@knife.find_manpage_path("shell")).to match(/distro\/common\/man\/man1\/chef-shell.1$/)
end
it "should provide the man page name if not in the gem" do
- @knife.find_manpage_path("foo").should == "foo"
+ expect(@knife.find_manpage_path("foo")).to eq("foo")
end
end
describe "find_manpages_for_query" do
it "should error if it does not find a match" do
- @knife.ui.stub(:error)
- @knife.ui.stub(:info)
- @knife.ui.stub(:msg)
- @knife.should_receive(:exit).with(1)
- @knife.ui.should_receive(:error).with("No help found for 'chickens'")
- @knife.ui.should_receive(:msg).with(/knife/)
+ allow(@knife.ui).to receive(:error)
+ allow(@knife.ui).to receive(:info)
+ allow(@knife.ui).to receive(:msg)
+ expect(@knife).to receive(:exit).with(1)
+ expect(@knife.ui).to receive(:error).with("No help found for 'chickens'")
+ expect(@knife.ui).to receive(:msg).with(/knife/)
@knife.find_manpages_for_query("chickens")
end
end
describe "print_help_topics" do
it "should print the known help topics" do
- @knife.ui.stub(:msg)
- @knife.ui.stub(:info)
- @knife.ui.should_receive(:msg).with(/knife/)
+ allow(@knife.ui).to receive(:msg)
+ allow(@knife.ui).to receive(:info)
+ expect(@knife.ui).to receive(:msg).with(/knife/)
@knife.print_help_topics
end
it "should shorten topics prefixed by knife-" do
- @knife.ui.stub(:msg)
- @knife.ui.stub(:info)
- @knife.ui.should_receive(:msg).with(/node/)
+ allow(@knife.ui).to receive(:msg)
+ allow(@knife.ui).to receive(:info)
+ expect(@knife.ui).to receive(:msg).with(/node/)
@knife.print_help_topics
end
it "should not leave topics prefixed by knife-" do
- @knife.ui.stub(:msg)
- @knife.ui.stub(:info)
- @knife.ui.should_not_receive(:msg).with(/knife-node/)
+ allow(@knife.ui).to receive(:msg)
+ allow(@knife.ui).to receive(:info)
+ expect(@knife.ui).not_to receive(:msg).with(/knife-node/)
@knife.print_help_topics
end
end
diff --git a/spec/unit/knife/node_bulk_delete_spec.rb b/spec/unit/knife/node_bulk_delete_spec.rb
index 3faece5469..57a8d0bf64 100644
--- a/spec/unit/knife/node_bulk_delete_spec.rb
+++ b/spec/unit/knife/node_bulk_delete_spec.rb
@@ -26,8 +26,8 @@ describe Chef::Knife::NodeBulkDelete do
@knife = Chef::Knife::NodeBulkDelete.new
@knife.name_args = ["."]
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
- @knife.ui.stub(:confirm).and_return(true)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:confirm).and_return(true)
@nodes = Hash.new
%w{adam brent jacob}.each do |node_name|
@nodes[node_name] = "http://localhost:4000/nodes/#{node_name}"
@@ -40,11 +40,11 @@ describe Chef::Knife::NodeBulkDelete do
inflatedish[name] = Chef::Node.new.tap {|n| n.name(name)}
inflatedish
end
- Chef::Node.should_receive(:list).and_return(@nodes)
+ expect(Chef::Node).to receive(:list).and_return(@nodes)
# I hate not having == defined for anything :(
actual = @knife.all_nodes
- actual.keys.should =~ expected.keys
- actual.values.map {|n| n.name }.should =~ %w[adam brent jacob]
+ expect(actual.keys).to match_array(expected.keys)
+ expect(actual.values.map {|n| n.name }).to match_array(%w[adam brent jacob])
end
end
@@ -53,41 +53,41 @@ describe Chef::Knife::NodeBulkDelete do
@inflatedish_list = @nodes.keys.inject({}) do |nodes_by_name, name|
node = Chef::Node.new()
node.name(name)
- node.stub(:destroy).and_return(true)
+ allow(node).to receive(:destroy).and_return(true)
nodes_by_name[name] = node
nodes_by_name
end
- @knife.stub(:all_nodes).and_return(@inflatedish_list)
+ allow(@knife).to receive(:all_nodes).and_return(@inflatedish_list)
end
it "should print the nodes you are about to delete" do
@knife.run
- @stdout.string.should match(/#{@knife.ui.list(@nodes.keys.sort, :columns_down)}/)
+ expect(@stdout.string).to match(/#{@knife.ui.list(@nodes.keys.sort, :columns_down)}/)
end
it "should confirm you really want to delete them" do
- @knife.ui.should_receive(:confirm)
+ expect(@knife.ui).to receive(:confirm)
@knife.run
end
it "should delete each node" do
@inflatedish_list.each_value do |n|
- n.should_receive(:destroy)
+ expect(n).to receive(:destroy)
end
@knife.run
end
it "should only delete nodes that match the regex" do
@knife.name_args = ['adam']
- @inflatedish_list['adam'].should_receive(:destroy)
- @inflatedish_list['brent'].should_not_receive(:destroy)
- @inflatedish_list['jacob'].should_not_receive(:destroy)
+ expect(@inflatedish_list['adam']).to receive(:destroy)
+ expect(@inflatedish_list['brent']).not_to receive(:destroy)
+ expect(@inflatedish_list['jacob']).not_to receive(:destroy)
@knife.run
end
it "should exit if the regex is not provided" do
@knife.name_args = []
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
diff --git a/spec/unit/knife/node_delete_spec.rb b/spec/unit/knife/node_delete_spec.rb
index 04eca389c6..0941d850e5 100644
--- a/spec/unit/knife/node_delete_spec.rb
+++ b/spec/unit/knife/node_delete_spec.rb
@@ -26,41 +26,41 @@ describe Chef::Knife::NodeDelete do
:print_after => nil
}
@knife.name_args = [ "adam" ]
- @knife.stub(:output).and_return(true)
- @knife.stub(:confirm).and_return(true)
+ allow(@knife).to receive(:output).and_return(true)
+ allow(@knife).to receive(:confirm).and_return(true)
@node = Chef::Node.new()
- @node.stub(:destroy).and_return(true)
- Chef::Node.stub(:load).and_return(@node)
+ allow(@node).to receive(:destroy).and_return(true)
+ allow(Chef::Node).to receive(:load).and_return(@node)
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
describe "run" do
it "should confirm that you want to delete" do
- @knife.should_receive(:confirm)
+ expect(@knife).to receive(:confirm)
@knife.run
end
it "should load the node" do
- Chef::Node.should_receive(:load).with("adam").and_return(@node)
+ expect(Chef::Node).to receive(:load).with("adam").and_return(@node)
@knife.run
end
it "should delete the node" do
- @node.should_receive(:destroy).and_return(@node)
+ expect(@node).to receive(:destroy).and_return(@node)
@knife.run
end
it "should not print the node" do
- @knife.should_not_receive(:output).with("poop")
+ expect(@knife).not_to receive(:output).with("poop")
@knife.run
end
describe "with -p or --print-after" do
it "should pretty print the node, formatted for display" do
@knife.config[:print_after] = true
- @knife.should_receive(:format_for_display).with(@node).and_return("poop")
- @knife.should_receive(:output).with("poop")
+ expect(@knife).to receive(:format_for_display).with(@node).and_return("poop")
+ expect(@knife).to receive(:output).with("poop")
@knife.run
end
end
diff --git a/spec/unit/knife/node_edit_spec.rb b/spec/unit/knife/node_edit_spec.rb
index 27db3416f4..58e2da2a1c 100644
--- a/spec/unit/knife/node_edit_spec.rb
+++ b/spec/unit/knife/node_edit_spec.rb
@@ -39,13 +39,13 @@ describe Chef::Knife::NodeEdit do
end
it "should load the node" do
- Chef::Node.should_receive(:load).with("adam").and_return(@node)
+ expect(Chef::Node).to receive(:load).with("adam").and_return(@node)
@knife.node
end
describe "after loading the node" do
before do
- @knife.stub(:node).and_return(@node)
+ allow(@knife).to receive(:node).and_return(@node)
@node.automatic_attrs = {:go => :away}
@node.default_attrs = {:hide => :me}
@node.override_attrs = {:dont => :show}
@@ -56,37 +56,37 @@ describe Chef::Knife::NodeEdit do
it "creates a view of the node without attributes from roles or ohai" do
actual = deserialized_json_view
- actual.should_not have_key("automatic")
- actual.should_not have_key("override")
- actual.should_not have_key("default")
- actual["normal"].should == {"do_show" => "these"}
- actual["run_list"].should == ["recipe[foo]"]
- actual["chef_environment"].should == "prod"
+ expect(actual).not_to have_key("automatic")
+ expect(actual).not_to have_key("override")
+ expect(actual).not_to have_key("default")
+ expect(actual["normal"]).to eq({"do_show" => "these"})
+ expect(actual["run_list"]).to eq(["recipe[foo]"])
+ expect(actual["chef_environment"]).to eq("prod")
end
it "shows the extra attributes when given the --all option" do
@knife.config[:all_attributes] = true
actual = deserialized_json_view
- actual["automatic"].should == {"go" => "away"}
- actual["override"].should == {"dont" => "show"}
- actual["default"].should == {"hide" => "me"}
- actual["normal"].should == {"do_show" => "these"}
- actual["run_list"].should == ["recipe[foo]"]
- actual["chef_environment"].should == "prod"
+ expect(actual["automatic"]).to eq({"go" => "away"})
+ expect(actual["override"]).to eq({"dont" => "show"})
+ expect(actual["default"]).to eq({"hide" => "me"})
+ expect(actual["normal"]).to eq({"do_show" => "these"})
+ expect(actual["run_list"]).to eq(["recipe[foo]"])
+ expect(actual["chef_environment"]).to eq("prod")
end
it "does not consider unedited data updated" do
view = deserialized_json_view
@knife.node_editor.send(:apply_updates, view)
- @knife.node_editor.should_not be_updated
+ expect(@knife.node_editor).not_to be_updated
end
it "considers edited data updated" do
view = deserialized_json_view
view["run_list"] << "role[fuuu]"
@knife.node_editor.send(:apply_updates, view)
- @knife.node_editor.should be_updated
+ expect(@knife.node_editor).to be_updated
end
end
@@ -94,7 +94,7 @@ describe Chef::Knife::NodeEdit do
describe "edit_node" do
before do
- @knife.stub(:node).and_return(@node)
+ allow(@knife).to receive(:node).and_return(@node)
end
let(:subject) { @knife.node_editor.edit_node }
diff --git a/spec/unit/knife/node_environment_set_spec.rb b/spec/unit/knife/node_environment_set_spec.rb
index 46ee1fea18..10267915d7 100644
--- a/spec/unit/knife/node_environment_set_spec.rb
+++ b/spec/unit/knife/node_environment_set_spec.rb
@@ -23,32 +23,32 @@ describe Chef::Knife::NodeEnvironmentSet do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::NodeEnvironmentSet.new
@knife.name_args = [ "adam", "bar" ]
- @knife.stub(:output).and_return(true)
+ allow(@knife).to receive(:output).and_return(true)
@node = Chef::Node.new()
@node.name("knifetest-node")
@node.chef_environment << "foo"
- @node.stub(:save).and_return(true)
- Chef::Node.stub(:load).and_return(@node)
+ allow(@node).to receive(:save).and_return(true)
+ allow(Chef::Node).to receive(:load).and_return(@node)
end
describe "run" do
it "should load the node" do
- Chef::Node.should_receive(:load).with("adam")
+ expect(Chef::Node).to receive(:load).with("adam")
@knife.run
end
it "should update the environment" do
@knife.run
- @node.chef_environment.should == 'bar'
+ expect(@node.chef_environment).to eq('bar')
end
it "should save the node" do
- @node.should_receive(:save)
+ expect(@node).to receive(:save)
@knife.run
end
it "should print the environment" do
- @knife.should_receive(:output).and_return(true)
+ expect(@knife).to receive(:output).and_return(true)
@knife.run
end
@@ -58,13 +58,13 @@ describe Chef::Knife::NodeEnvironmentSet do
@stdout = StringIO.new
@stderr = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
- @knife.ui.stub(:stderr).and_return(@stderr)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
end
it "should exit" do
@knife.name_args = [ "adam" ]
- lambda { @knife.run }.should raise_error SystemExit
+ expect { @knife.run }.to raise_error SystemExit
end
it "should show the user the usage and an error" do
@@ -72,8 +72,8 @@ describe Chef::Knife::NodeEnvironmentSet do
begin ; @knife.run ; rescue SystemExit ; end
- @stdout.string.should eq "USAGE: knife node environment set NODE ENVIRONMENT\n"
- @stderr.string.should eq "FATAL: You must specify a node name and an environment.\n"
+ expect(@stdout.string).to eq "USAGE: knife node environment set NODE ENVIRONMENT\n"
+ expect(@stderr.string).to eq "FATAL: You must specify a node name and an environment.\n"
end
end
end
diff --git a/spec/unit/knife/node_from_file_spec.rb b/spec/unit/knife/node_from_file_spec.rb
index 56a2a08b68..623904753e 100644
--- a/spec/unit/knife/node_from_file_spec.rb
+++ b/spec/unit/knife/node_from_file_spec.rb
@@ -28,30 +28,30 @@ describe Chef::Knife::NodeFromFile do
:print_after => nil
}
@knife.name_args = [ "adam.rb" ]
- @knife.stub(:output).and_return(true)
- @knife.stub(:confirm).and_return(true)
+ allow(@knife).to receive(:output).and_return(true)
+ allow(@knife).to receive(:confirm).and_return(true)
@node = Chef::Node.new()
- @node.stub(:save)
- @knife.loader.stub(:load_from).and_return(@node)
+ allow(@node).to receive(:save)
+ allow(@knife.loader).to receive(:load_from).and_return(@node)
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
describe "run" do
it "should load from a file" do
- @knife.loader.should_receive(:load_from).with('nodes', 'adam.rb').and_return(@node)
+ expect(@knife.loader).to receive(:load_from).with('nodes', 'adam.rb').and_return(@node)
@knife.run
end
it "should not print the Node" do
- @knife.should_not_receive(:output)
+ expect(@knife).not_to receive(:output)
@knife.run
end
describe "with -p or --print-after" do
it "should print the Node" do
@knife.config[:print_after] = true
- @knife.should_receive(:output)
+ expect(@knife).to receive(:output)
@knife.run
end
end
diff --git a/spec/unit/knife/node_list_spec.rb b/spec/unit/knife/node_list_spec.rb
index cad2d6482d..71edea78f7 100644
--- a/spec/unit/knife/node_list_spec.rb
+++ b/spec/unit/knife/node_list_spec.rb
@@ -23,38 +23,38 @@ describe Chef::Knife::NodeList do
Chef::Config[:node_name] = "webmonkey.example.com"
Chef::Config[:environment] = nil # reset this value each time, as it is not reloaded
@knife = Chef::Knife::NodeList.new
- @knife.stub(:output).and_return(true)
+ allow(@knife).to receive(:output).and_return(true)
@list = {
"foo" => "http://example.com/foo",
"bar" => "http://example.com/foo"
}
- Chef::Node.stub(:list).and_return(@list)
- Chef::Node.stub(:list_by_environment).and_return(@list)
+ allow(Chef::Node).to receive(:list).and_return(@list)
+ allow(Chef::Node).to receive(:list_by_environment).and_return(@list)
end
describe "run" do
it "should list all of the nodes if -E is not specified" do
- Chef::Node.should_receive(:list).and_return(@list)
+ expect(Chef::Node).to receive(:list).and_return(@list)
@knife.run
end
it "should pretty print the list" do
- Chef::Node.should_receive(:list).and_return(@list)
- @knife.should_receive(:output).with([ "bar", "foo" ])
+ expect(Chef::Node).to receive(:list).and_return(@list)
+ expect(@knife).to receive(:output).with([ "bar", "foo" ])
@knife.run
end
it "should list nodes in the specific environment if -E ENVIRONMENT is specified" do
Chef::Config[:environment] = "prod"
- Chef::Node.should_receive(:list_by_environment).with("prod").and_return(@list)
+ expect(Chef::Node).to receive(:list_by_environment).with("prod").and_return(@list)
@knife.run
end
describe "with -w or --with-uri" do
it "should pretty print the hash" do
@knife.config[:with_uri] = true
- Chef::Node.should_receive(:list).and_return(@list)
- @knife.should_receive(:output).with(@list)
+ expect(Chef::Node).to receive(:list).and_return(@list)
+ expect(@knife).to receive(:output).with(@list)
@knife.run
end
end
diff --git a/spec/unit/knife/node_run_list_add_spec.rb b/spec/unit/knife/node_run_list_add_spec.rb
index bd33a359a2..92fbfd23fe 100644
--- a/spec/unit/knife/node_run_list_add_spec.rb
+++ b/spec/unit/knife/node_run_list_add_spec.rb
@@ -26,30 +26,30 @@ describe Chef::Knife::NodeRunListAdd do
:after => nil
}
@knife.name_args = [ "adam", "role[monkey]" ]
- @knife.stub(:output).and_return(true)
+ allow(@knife).to receive(:output).and_return(true)
@node = Chef::Node.new()
- @node.stub(:save).and_return(true)
- Chef::Node.stub(:load).and_return(@node)
+ allow(@node).to receive(:save).and_return(true)
+ allow(Chef::Node).to receive(:load).and_return(@node)
end
describe "run" do
it "should load the node" do
- Chef::Node.should_receive(:load).with("adam")
+ expect(Chef::Node).to receive(:load).with("adam")
@knife.run
end
it "should add to the run list" do
@knife.run
- @node.run_list[0].should == 'role[monkey]'
+ expect(@node.run_list[0]).to eq('role[monkey]')
end
it "should save the node" do
- @node.should_receive(:save)
+ expect(@node).to receive(:save)
@knife.run
end
it "should print the run list" do
- @knife.should_receive(:output).and_return(true)
+ expect(@knife).to receive(:output).and_return(true)
@knife.run
end
@@ -59,9 +59,9 @@ describe Chef::Knife::NodeRunListAdd do
@node.run_list << "role[barn]"
@knife.config[:after] = "role[acorns]"
@knife.run
- @node.run_list[0].should == "role[acorns]"
- @node.run_list[1].should == "role[monkey]"
- @node.run_list[2].should == "role[barn]"
+ expect(@node.run_list[0]).to eq("role[acorns]")
+ expect(@node.run_list[1]).to eq("role[monkey]")
+ expect(@node.run_list[2]).to eq("role[barn]")
end
end
@@ -71,9 +71,9 @@ describe Chef::Knife::NodeRunListAdd do
@node.run_list << "role[barn]"
@knife.config[:before] = "role[acorns]"
@knife.run
- @node.run_list[0].should == "role[monkey]"
- @node.run_list[1].should == "role[acorns]"
- @node.run_list[2].should == "role[barn]"
+ expect(@node.run_list[0]).to eq("role[monkey]")
+ expect(@node.run_list[1]).to eq("role[acorns]")
+ expect(@node.run_list[2]).to eq("role[barn]")
end
end
@@ -83,8 +83,8 @@ describe Chef::Knife::NodeRunListAdd do
@node.run_list << "role[barn]"
@knife.config[:before] = "role[acorns]"
@knife.config[:after] = "role[acorns]"
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
@@ -93,9 +93,9 @@ describe Chef::Knife::NodeRunListAdd do
@knife.name_args = [ "adam", "role[monkey],role[duck]" ]
@node.run_list << "role[acorns]"
@knife.run
- @node.run_list[0].should == "role[acorns]"
- @node.run_list[1].should == "role[monkey]"
- @node.run_list[2].should == "role[duck]"
+ expect(@node.run_list[0]).to eq("role[acorns]")
+ expect(@node.run_list[1]).to eq("role[monkey]")
+ expect(@node.run_list[2]).to eq("role[duck]")
end
end
@@ -104,9 +104,9 @@ describe Chef::Knife::NodeRunListAdd do
@knife.name_args = [ "adam", "role[monkey], role[duck]" ]
@node.run_list << "role[acorns]"
@knife.run
- @node.run_list[0].should == "role[acorns]"
- @node.run_list[1].should == "role[monkey]"
- @node.run_list[2].should == "role[duck]"
+ expect(@node.run_list[0]).to eq("role[acorns]")
+ expect(@node.run_list[1]).to eq("role[monkey]")
+ expect(@node.run_list[2]).to eq("role[duck]")
end
end
@@ -115,9 +115,9 @@ describe Chef::Knife::NodeRunListAdd do
@knife.name_args = [ "adam", "role[monkey]", "role[duck]" ]
@node.run_list << "role[acorns]"
@knife.run
- @node.run_list[0].should == "role[acorns]"
- @node.run_list[1].should == "role[monkey]"
- @node.run_list[2].should == "role[duck]"
+ expect(@node.run_list[0]).to eq("role[acorns]")
+ expect(@node.run_list[1]).to eq("role[monkey]")
+ expect(@node.run_list[2]).to eq("role[duck]")
end
end
@@ -126,9 +126,9 @@ describe Chef::Knife::NodeRunListAdd do
@knife.name_args = [ "adam", "role[monkey]", "role[duck],recipe[bird::fly]" ]
@node.run_list << "role[acorns]"
@knife.run
- @node.run_list[0].should == "role[acorns]"
- @node.run_list[1].should == "role[monkey]"
- @node.run_list[2].should == "role[duck]"
+ expect(@node.run_list[0]).to eq("role[acorns]")
+ expect(@node.run_list[1]).to eq("role[monkey]")
+ expect(@node.run_list[2]).to eq("role[duck]")
end
end
@@ -137,8 +137,8 @@ describe Chef::Knife::NodeRunListAdd do
@knife.name_args = [ "adam", "role[monkey]," ]
@node.run_list << "role[acorns]"
@knife.run
- @node.run_list[0].should == "role[acorns]"
- @node.run_list[1].should == "role[monkey]"
+ expect(@node.run_list[0]).to eq("role[acorns]")
+ expect(@node.run_list[1]).to eq("role[monkey]")
end
end
end
diff --git a/spec/unit/knife/node_run_list_remove_spec.rb b/spec/unit/knife/node_run_list_remove_spec.rb
index 5a008a3e07..ceceef7178 100644
--- a/spec/unit/knife/node_run_list_remove_spec.rb
+++ b/spec/unit/knife/node_run_list_remove_spec.rb
@@ -27,33 +27,33 @@ describe Chef::Knife::NodeRunListRemove do
@node = Chef::Node.new()
@node.name("knifetest-node")
@node.run_list << "role[monkey]"
- @node.stub(:save).and_return(true)
+ allow(@node).to receive(:save).and_return(true)
- @knife.ui.stub(:output).and_return(true)
- @knife.ui.stub(:confirm).and_return(true)
+ allow(@knife.ui).to receive(:output).and_return(true)
+ allow(@knife.ui).to receive(:confirm).and_return(true)
- Chef::Node.stub(:load).and_return(@node)
+ allow(Chef::Node).to receive(:load).and_return(@node)
end
describe "run" do
it "should load the node" do
- Chef::Node.should_receive(:load).with("adam").and_return(@node)
+ expect(Chef::Node).to receive(:load).with("adam").and_return(@node)
@knife.run
end
it "should remove the item from the run list" do
@knife.run
- @node.run_list[0].should_not == 'role[monkey]'
+ expect(@node.run_list[0]).not_to eq('role[monkey]')
end
it "should save the node" do
- @node.should_receive(:save).and_return(true)
+ expect(@node).to receive(:save).and_return(true)
@knife.run
end
it "should print the run list" do
@knife.config[:print_after] = true
- @knife.ui.should_receive(:output).with({ "knifetest-node" => { 'run_list' => [] } })
+ expect(@knife.ui).to receive(:output).with({ "knifetest-node" => { 'run_list' => [] } })
@knife.run
end
@@ -63,12 +63,27 @@ describe Chef::Knife::NodeRunListRemove do
@node.run_list << 'recipe[duck::type]'
@knife.name_args = [ 'adam', 'role[monkey],recipe[duck::type]' ]
@knife.run
- @node.run_list.should_not include('role[monkey]')
- @node.run_list.should_not include('recipe[duck::type]')
+ expect(@node.run_list).not_to include('role[monkey]')
+ expect(@node.run_list).not_to include('recipe[duck::type]')
+ end
+
+ it "should remove the items from the run list when name args contains whitespace" do
+ @node.run_list << 'role[monkey]'
+ @node.run_list << 'recipe[duck::type]'
+ @knife.name_args = [ 'adam', 'role[monkey], recipe[duck::type]' ]
+ @knife.run
+ expect(@node.run_list).not_to include('role[monkey]')
+ expect(@node.run_list).not_to include('recipe[duck::type]')
+ end
+
+ it "should remove the items from the run list when name args contains multiple run lists" do
+ @node.run_list << 'role[blah]'
+ @node.run_list << 'recipe[duck::type]'
+ @knife.name_args = [ 'adam', 'role[monkey], recipe[duck::type]', 'role[blah]' ]
+ @knife.run
+ expect(@node.run_list).not_to include('role[monkey]')
+ expect(@node.run_list).not_to include('recipe[duck::type]')
end
end
end
end
-
-
-
diff --git a/spec/unit/knife/node_run_list_set_spec.rb b/spec/unit/knife/node_run_list_set_spec.rb
index 02281f8385..68daaafd70 100644
--- a/spec/unit/knife/node_run_list_set_spec.rb
+++ b/spec/unit/knife/node_run_list_set_spec.rb
@@ -24,30 +24,30 @@ describe Chef::Knife::NodeRunListSet do
@knife = Chef::Knife::NodeRunListSet.new
@knife.config = {}
@knife.name_args = [ "adam", "role[monkey]" ]
- @knife.stub(:output).and_return(true)
+ allow(@knife).to receive(:output).and_return(true)
@node = Chef::Node.new()
- @node.stub(:save).and_return(true)
- Chef::Node.stub(:load).and_return(@node)
+ allow(@node).to receive(:save).and_return(true)
+ allow(Chef::Node).to receive(:load).and_return(@node)
end
describe "run" do
it "should load the node" do
- Chef::Node.should_receive(:load).with("adam")
+ expect(Chef::Node).to receive(:load).with("adam")
@knife.run
end
it "should set the run list" do
@knife.run
- @node.run_list[0].should == 'role[monkey]'
+ expect(@node.run_list[0]).to eq('role[monkey]')
end
it "should save the node" do
- @node.should_receive(:save)
+ expect(@node).to receive(:save)
@knife.run
end
it "should print the run list" do
- @knife.should_receive(:output).and_return(true)
+ expect(@knife).to receive(:output).and_return(true)
@knife.run
end
@@ -55,8 +55,8 @@ describe Chef::Knife::NodeRunListSet do
it "should set the run list to all the entries" do
@knife.name_args = [ "adam", "role[monkey],role[duck]" ]
@knife.run
- @node.run_list[0].should == "role[monkey]"
- @node.run_list[1].should == "role[duck]"
+ expect(@node.run_list[0]).to eq("role[monkey]")
+ expect(@node.run_list[1]).to eq("role[duck]")
end
end
@@ -64,8 +64,8 @@ describe Chef::Knife::NodeRunListSet do
it "should set the run list to all the entries" do
@knife.name_args = [ "adam", "role[monkey], role[duck]" ]
@knife.run
- @node.run_list[0].should == "role[monkey]"
- @node.run_list[1].should == "role[duck]"
+ expect(@node.run_list[0]).to eq("role[monkey]")
+ expect(@node.run_list[1]).to eq("role[duck]")
end
end
@@ -73,8 +73,8 @@ describe Chef::Knife::NodeRunListSet do
it "should set the run list to all the entries" do
@knife.name_args = [ "adam", "role[monkey]", "role[duck]" ]
@knife.run
- @node.run_list[0].should == "role[monkey]"
- @node.run_list[1].should == "role[duck]"
+ expect(@node.run_list[0]).to eq("role[monkey]")
+ expect(@node.run_list[1]).to eq("role[duck]")
end
end
@@ -82,8 +82,8 @@ describe Chef::Knife::NodeRunListSet do
it "should add to the run list all the entries" do
@knife.name_args = [ "adam", "role[monkey]", "role[duck],recipe[bird::fly]" ]
@knife.run
- @node.run_list[0].should == "role[monkey]"
- @node.run_list[1].should == "role[duck]"
+ expect(@node.run_list[0]).to eq("role[monkey]")
+ expect(@node.run_list[1]).to eq("role[duck]")
end
end
@@ -91,7 +91,7 @@ describe Chef::Knife::NodeRunListSet do
it "should add to the run list one item" do
@knife.name_args = [ "adam", "role[monkey]," ]
@knife.run
- @node.run_list[0].should == "role[monkey]"
+ expect(@node.run_list[0]).to eq("role[monkey]")
end
end
@@ -99,15 +99,15 @@ describe Chef::Knife::NodeRunListSet do
it "should overwrite any existing run list items" do
@node.run_list << "role[acorns]"
@node.run_list << "role[zebras]"
- @node.run_list[0].should == "role[acorns]"
- @node.run_list[1].should == "role[zebras]"
- @node.run_list.run_list_items.size.should == 2
+ expect(@node.run_list[0]).to eq("role[acorns]")
+ expect(@node.run_list[1]).to eq("role[zebras]")
+ expect(@node.run_list.run_list_items.size).to eq(2)
@knife.name_args = [ "adam", "role[monkey]", "role[duck]" ]
@knife.run
- @node.run_list[0].should == "role[monkey]"
- @node.run_list[1].should == "role[duck]"
- @node.run_list.run_list_items.size.should == 2
+ expect(@node.run_list[0]).to eq("role[monkey]")
+ expect(@node.run_list[1]).to eq("role[duck]")
+ expect(@node.run_list.run_list_items.size).to eq(2)
end
end
@@ -117,13 +117,13 @@ describe Chef::Knife::NodeRunListSet do
@stdout = StringIO.new
@stderr = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
- @knife.ui.stub(:stderr).and_return(@stderr)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
end
it "should exit" do
@knife.name_args = [ "adam" ]
- lambda { @knife.run }.should raise_error SystemExit
+ expect { @knife.run }.to raise_error SystemExit
end
it "should show the user" do
@@ -131,8 +131,8 @@ describe Chef::Knife::NodeRunListSet do
begin ; @knife.run ; rescue SystemExit ; end
- @stdout.string.should eq "USAGE: knife node run_list set NODE ENTRIES (options)\n"
- @stderr.string.should eq "FATAL: You must supply both a node name and a run list.\n"
+ expect(@stdout.string).to eq "USAGE: knife node run_list set NODE ENTRIES (options)\n"
+ expect(@stderr.string).to eq "FATAL: You must supply both a node name and a run list.\n"
end
end
diff --git a/spec/unit/knife/raw_spec.rb b/spec/unit/knife/raw_spec.rb
new file mode 100644
index 0000000000..ab929abd39
--- /dev/null
+++ b/spec/unit/knife/raw_spec.rb
@@ -0,0 +1,43 @@
+#
+# Author:: Steven Danna (<steve@getchef.com>)
+# Copyright:: Copyright (c) 2014 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 'spec_helper'
+
+describe Chef::Knife::Raw do
+ let(:rest) do
+ r = double('Chef::Knife::Raw::RawInputServerAPI')
+ allow(Chef::Knife::Raw::RawInputServerAPI).to receive(:new).and_return(r)
+ r
+ end
+
+ let(:knife) do
+ k = Chef::Knife::Raw.new
+ k.config[:method] = "GET"
+ k.name_args = [ "/nodes" ]
+ k
+ end
+
+ describe "run" do
+ it "should set the x-ops-request-source header when --proxy-auth is set" do
+ knife.config[:proxy_auth] = true
+ expect(rest).to receive(:request).with(:GET, "/nodes",
+ { 'Content-Type' => 'application/json',
+ 'x-ops-request-source' => 'web'}, false)
+ knife.run
+ end
+ end
+end
diff --git a/spec/unit/knife/role_bulk_delete_spec.rb b/spec/unit/knife/role_bulk_delete_spec.rb
index eb1d3b4cff..5b79e52a04 100644
--- a/spec/unit/knife/role_bulk_delete_spec.rb
+++ b/spec/unit/knife/role_bulk_delete_spec.rb
@@ -27,53 +27,53 @@ describe Chef::Knife::RoleBulkDelete do
}
@knife.name_args = ["."]
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
- @knife.ui.stub(:confirm).and_return(true)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:confirm).and_return(true)
@roles = Hash.new
%w{dev staging production}.each do |role_name|
role = Chef::Role.new()
role.name(role_name)
- role.stub(:destroy).and_return(true)
+ allow(role).to receive(:destroy).and_return(true)
@roles[role_name] = role
end
- Chef::Role.stub(:list).and_return(@roles)
+ allow(Chef::Role).to receive(:list).and_return(@roles)
end
describe "run" do
it "should get the list of the roles" do
- Chef::Role.should_receive(:list).and_return(@roles)
+ expect(Chef::Role).to receive(:list).and_return(@roles)
@knife.run
end
it "should print the roles you are about to delete" do
@knife.run
- @stdout.string.should match(/#{@knife.ui.list(@roles.keys.sort, :columns_down)}/)
+ expect(@stdout.string).to match(/#{@knife.ui.list(@roles.keys.sort, :columns_down)}/)
end
it "should confirm you really want to delete them" do
- @knife.ui.should_receive(:confirm)
+ expect(@knife.ui).to receive(:confirm)
@knife.run
end
it "should delete each role" do
@roles.each_value do |r|
- r.should_receive(:destroy)
+ expect(r).to receive(:destroy)
end
@knife.run
end
it "should only delete roles that match the regex" do
@knife.name_args = ["dev"]
- @roles["dev"].should_receive(:destroy)
- @roles["staging"].should_not_receive(:destroy)
- @roles["production"].should_not_receive(:destroy)
+ expect(@roles["dev"]).to receive(:destroy)
+ expect(@roles["staging"]).not_to receive(:destroy)
+ expect(@roles["production"]).not_to receive(:destroy)
@knife.run
end
it "should exit if the regex is not provided" do
@knife.name_args = []
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
diff --git a/spec/unit/knife/role_create_spec.rb b/spec/unit/knife/role_create_spec.rb
index a4d7392b68..fb748c51f6 100644
--- a/spec/unit/knife/role_create_spec.rb
+++ b/spec/unit/knife/role_create_spec.rb
@@ -26,45 +26,45 @@ describe Chef::Knife::RoleCreate do
:description => nil
}
@knife.name_args = [ "adam" ]
- @knife.stub(:output).and_return(true)
+ allow(@knife).to receive(:output).and_return(true)
@role = Chef::Role.new()
- @role.stub(:save)
- Chef::Role.stub(:new).and_return(@role)
- @knife.stub(:edit_data).and_return(@role)
+ allow(@role).to receive(:save)
+ allow(Chef::Role).to receive(:new).and_return(@role)
+ allow(@knife).to receive(:edit_data).and_return(@role)
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
describe "run" do
it "should create a new role" do
- Chef::Role.should_receive(:new).and_return(@role)
+ expect(Chef::Role).to receive(:new).and_return(@role)
@knife.run
end
it "should set the role name" do
- @role.should_receive(:name).with("adam")
+ expect(@role).to receive(:name).with("adam")
@knife.run
end
it "should not print the role" do
- @knife.should_not_receive(:output)
+ expect(@knife).not_to receive(:output)
@knife.run
end
it "should allow you to edit the data" do
- @knife.should_receive(:edit_data).with(@role)
+ expect(@knife).to receive(:edit_data).with(@role)
@knife.run
end
it "should save the role" do
- @role.should_receive(:save)
+ expect(@role).to receive(:save)
@knife.run
end
describe "with -d or --description" do
it "should set the description" do
@knife.config[:description] = "All is bob"
- @role.should_receive(:description).with("All is bob")
+ expect(@role).to receive(:description).with("All is bob")
@knife.run
end
end
@@ -72,7 +72,7 @@ describe Chef::Knife::RoleCreate do
describe "with -p or --print-after" do
it "should pretty print the node, formatted for display" do
@knife.config[:print_after] = true
- @knife.should_receive(:output).with(@role)
+ expect(@knife).to receive(:output).with(@role)
@knife.run
end
end
diff --git a/spec/unit/knife/role_delete_spec.rb b/spec/unit/knife/role_delete_spec.rb
index 0771446d49..b1a0d90410 100644
--- a/spec/unit/knife/role_delete_spec.rb
+++ b/spec/unit/knife/role_delete_spec.rb
@@ -26,40 +26,40 @@ describe Chef::Knife::RoleDelete do
:print_after => nil
}
@knife.name_args = [ "adam" ]
- @knife.stub(:output).and_return(true)
- @knife.stub(:confirm).and_return(true)
+ allow(@knife).to receive(:output).and_return(true)
+ allow(@knife).to receive(:confirm).and_return(true)
@role = Chef::Role.new()
- @role.stub(:destroy).and_return(true)
- Chef::Role.stub(:load).and_return(@role)
+ allow(@role).to receive(:destroy).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
describe "run" do
it "should confirm that you want to delete" do
- @knife.should_receive(:confirm)
+ expect(@knife).to receive(:confirm)
@knife.run
end
it "should load the Role" do
- Chef::Role.should_receive(:load).with("adam").and_return(@role)
+ expect(Chef::Role).to receive(:load).with("adam").and_return(@role)
@knife.run
end
it "should delete the Role" do
- @role.should_receive(:destroy).and_return(@role)
+ expect(@role).to receive(:destroy).and_return(@role)
@knife.run
end
it "should not print the Role" do
- @knife.should_not_receive(:output)
+ expect(@knife).not_to receive(:output)
@knife.run
end
describe "with -p or --print-after" do
it "should pretty print the Role, formatted for display" do
@knife.config[:print_after] = true
- @knife.should_receive(:output)
+ expect(@knife).to receive(:output)
@knife.run
end
end
diff --git a/spec/unit/knife/role_edit_spec.rb b/spec/unit/knife/role_edit_spec.rb
index f6d3b41d98..0975c6458d 100644
--- a/spec/unit/knife/role_edit_spec.rb
+++ b/spec/unit/knife/role_edit_spec.rb
@@ -24,22 +24,22 @@ describe Chef::Knife::RoleEdit do
@knife = Chef::Knife::RoleEdit.new
@knife.config[:print_after] = nil
@knife.name_args = [ "adam" ]
- @knife.ui.stub(:output).and_return(true)
+ allow(@knife.ui).to receive(:output).and_return(true)
@role = Chef::Role.new()
- @role.stub(:save)
- Chef::Role.stub(:load).and_return(@role)
- @knife.ui.stub(:edit_data).and_return(@role)
- @knife.ui.stub(:msg)
+ allow(@role).to receive(:save)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+ allow(@knife.ui).to receive(:edit_data).and_return(@role)
+ allow(@knife.ui).to receive(:msg)
end
describe "run" do
it "should load the role" do
- Chef::Role.should_receive(:load).with("adam").and_return(@role)
+ expect(Chef::Role).to receive(:load).with("adam").and_return(@role)
@knife.run
end
it "should edit the role data" do
- @knife.ui.should_receive(:edit_data).with(@role)
+ expect(@knife.ui).to receive(:edit_data).with(@role)
@knife.run
end
@@ -47,29 +47,29 @@ describe Chef::Knife::RoleEdit do
pansy = Chef::Role.new
@role.name("new_role_name")
- @knife.ui.should_receive(:edit_data).with(@role).and_return(pansy)
- pansy.should_receive(:save)
+ expect(@knife.ui).to receive(:edit_data).with(@role).and_return(pansy)
+ expect(pansy).to receive(:save)
@knife.run
end
it "should not save the unedited role data" do
pansy = Chef::Role.new
- @knife.ui.should_receive(:edit_data).with(@role).and_return(pansy)
- pansy.should_not_receive(:save)
+ expect(@knife.ui).to receive(:edit_data).with(@role).and_return(pansy)
+ expect(pansy).not_to receive(:save)
@knife.run
end
it "should not print the role" do
- @knife.ui.should_not_receive(:output)
+ expect(@knife.ui).not_to receive(:output)
@knife.run
end
describe "with -p or --print-after" do
it "should pretty print the role, formatted for display" do
@knife.config[:print_after] = true
- @knife.ui.should_receive(:output).with(@role)
+ expect(@knife.ui).to receive(:output).with(@role)
@knife.run
end
end
diff --git a/spec/unit/knife/role_env_run_list_add_spec.rb b/spec/unit/knife/role_env_run_list_add_spec.rb
new file mode 100644
index 0000000000..f286d5fd0d
--- /dev/null
+++ b/spec/unit/knife/role_env_run_list_add_spec.rb
@@ -0,0 +1,217 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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 'spec_helper'
+
+describe Chef::Knife::RoleEnvRunListAdd do
+ before(:each) do
+# Chef::Config[:role_name] = "websimian"
+# Chef::Config[:env_name] = "QA"
+ @knife = Chef::Knife::RoleEnvRunListAdd.new
+ @knife.config = {
+ :after => nil
+ }
+ @knife.name_args = [ "will", "QA", "role[monkey]" ]
+ allow(@knife).to receive(:output).and_return(true)
+ @role = Chef::Role.new()
+ allow(@role).to receive(:save).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+ end
+
+ describe "run" do
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should have an empty default run list" do
+ @knife.run
+ expect(@role.run_list[0]).to be_nil
+ end
+
+ it "should have a QA environment" do
+ @knife.run
+ expect(@role.active_run_list_for('QA')).to eq('QA')
+ end
+
+ it "should load the role named will" do
+ expect(Chef::Role).to receive(:load).with("will")
+ @knife.run
+ end
+
+ it "should be able to add an environment specific run list" do
+ @knife.run
+ expect(@role.run_list_for('QA')[0]).to eq('role[monkey]')
+ end
+
+ it "should save the role" do
+ expect(@role).to receive(:save)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.run
+ end
+
+ describe "with -a or --after specified" do
+ it "should not create a change if the specified 'after' never comes" do
+ @role.run_list_for("_default") << "role[acorns]"
+ @role.run_list_for("_default") << "role[barn]"
+ @knife.config[:after] = "role[acorns]"
+ @knife.name_args = [ "will", "QA", "role[pad]" ]
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to be_nil
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[barn]")
+ expect(@role.run_list[2]).to be_nil
+ end
+
+ it "should add to the run list after the specified entries in the QA run list" do
+ #Setup
+ @role.run_list_for("_default") << "role[acorns]"
+ @role.run_list_for("_default") << "role[barn]"
+ @knife.run
+ @role.run_list_for("QA") << "role[pencil]"
+ @role.run_list_for("QA") << "role[pen]"
+ #Configuration we are testing
+ @knife.config[:after] = "role[pencil]"
+ @knife.name_args = [ "will", "QA", "role[pad]", "role[whackadoo]" ]
+ @knife.run
+ #The actual tests
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[pencil]")
+ expect(@role.run_list_for("QA")[2]).to eq("role[pad]")
+ expect(@role.run_list_for("QA")[3]).to eq("role[whackadoo]")
+ expect(@role.run_list_for("QA")[4]).to eq("role[pen]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[barn]")
+ expect(@role.run_list[2]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe" do
+ it "should add to the QA run list all the entries" do
+ @knife.name_args = [ "will", "QA", "role[monkey],role[duck]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[duck]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe with space between items" do
+ it "should add to the run list all the entries" do
+ @knife.name_args = [ "will", "QA", "role[monkey], role[duck]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[duck]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe as different arguments" do
+ it "should add to the run list all the entries" do
+ @knife.name_args = [ "will", "QA", "role[monkey]", "role[duck]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[duck]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe as different arguments and list separated by comas" do
+ it "should add to the run list all the entries" do
+ @knife.name_args = [ "will", "QA", "role[monkey]", "role[duck],recipe[bird::fly]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[duck]")
+ expect(@role.run_list_for("QA")[2]).to eq("recipe[bird::fly]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ describe "Recipe with version number is allowed" do
+ it "should add to the run list all the entries including the versioned recipe" do
+ @knife.name_args = [ "will", "QA", "role[monkey]", "role[duck],recipe[bird::fly@1.1.3]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[duck]")
+ expect(@role.run_list_for("QA")[2]).to eq("recipe[bird::fly@1.1.3]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ describe "with one role or recipe but with an extraneous comma" do
+ it "should add to the run list one item" do
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.name_args = [ "will", "QA", "role[monkey]," ]
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[monkey]")
+ expect(@role.run_list_for("QA")[1]).to be_nil
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ describe "with more than one command" do
+ it "should be able to the environment run list by running multiple knife commands" do
+ @knife.name_args = [ "will", "QA", "role[blue]," ]
+ @knife.run
+ @knife.name_args = [ "will", "QA", "role[black]," ]
+ @knife.run
+ expect(@role.run_list_for("QA")[0]).to eq("role[blue]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[black]")
+ expect(@role.run_list[0]).to be_nil
+ end
+ end
+
+ describe "with more than one environment" do
+ it "should add to the run list a second environment in the specific run list" do
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.name_args = [ "will", "QA", "role[blue]," ]
+ @knife.run
+ @role.run_list_for("QA") << "role[walnuts]"
+
+ @knife.name_args = [ "will", "PRD", "role[ball]," ]
+ @knife.run
+ @role.run_list_for("PRD") << "role[pen]"
+
+ expect(@role.run_list_for("QA")[0]).to eq("role[blue]")
+ expect(@role.run_list_for("PRD")[0]).to eq("role[ball]")
+ expect(@role.run_list_for("QA")[1]).to eq("role[walnuts]")
+ expect(@role.run_list_for("PRD")[1]).to eq("role[pen]")
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to be_nil
+ end
+ end
+
+ end
+end
diff --git a/spec/unit/knife/role_env_run_list_clear_spec.rb b/spec/unit/knife/role_env_run_list_clear_spec.rb
new file mode 100644
index 0000000000..525376c358
--- /dev/null
+++ b/spec/unit/knife/role_env_run_list_clear_spec.rb
@@ -0,0 +1,100 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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 'spec_helper'
+
+describe Chef::Knife::RoleEnvRunListClear do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ Chef::Config[:env_name] = "QA"
+ @setup = Chef::Knife::RoleEnvRunListAdd.new
+ @setup.name_args = [ "will", "QA", "role[monkey]", "role[person]" ]
+
+ @knife = Chef::Knife::RoleEnvRunListClear.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "QA" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should remove the item from the run list" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list_for('QA')[0]).to be_nil
+ expect(@role.run_list[0]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "should clear an environmental run list of roles and recipes" do
+ it "should remove the items from the run list" do
+ @setup.name_args = [ "will", "QA", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @setup.name_args = [ "will", "PRD", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ 'will', 'QA' ]
+ @knife.run
+ expect(@role.run_list_for('QA')[0]).to be_nil
+ expect(@role.run_list_for('PRD')[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list_for('PRD')[1]).to eq('role[monkey]')
+ expect(@role.run_list_for('PRD')[2]).to eq('recipe[duck::type]')
+ expect(@role.run_list_for('PRD')[3]).to eq('role[person]')
+ expect(@role.run_list_for('PRD')[4]).to eq('role[bird]')
+ expect(@role.run_list_for('PRD')[5]).to eq('role[town]')
+ end
+ end
+ end
+end
+
+
+
diff --git a/spec/unit/knife/role_env_run_list_remove_spec.rb b/spec/unit/knife/role_env_run_list_remove_spec.rb
new file mode 100644
index 0000000000..a15d0af691
--- /dev/null
+++ b/spec/unit/knife/role_env_run_list_remove_spec.rb
@@ -0,0 +1,108 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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 'spec_helper'
+
+describe Chef::Knife::RoleEnvRunListRemove do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ Chef::Config[:env_name] = "QA"
+ @setup = Chef::Knife::RoleEnvRunListAdd.new
+ @setup.name_args = [ "will", "QA", "role[monkey]", "role[person]" ]
+
+ @knife = Chef::Knife::RoleEnvRunListRemove.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "QA", "role[monkey]" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should remove the item from the run list" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list_for('QA')[0]).not_to eq('role[monkey]')
+ expect(@role.run_list_for('QA')[0]).to eq('role[person]')
+ expect(@role.run_list[0]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "run with a list of roles and recipes" do
+ it "should remove the items from the run list" do
+ @setup.name_args = [ "will", "QA", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @setup.name_args = [ "will", "PRD", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ 'will', 'QA', 'role[monkey]' ]
+ @knife.run
+ @knife.name_args = [ 'will', 'QA', 'recipe[duck::type]' ]
+ @knife.run
+ expect(@role.run_list_for('QA')).not_to include('role[monkey]')
+ expect(@role.run_list_for('QA')).not_to include('recipe[duck::type]')
+ expect(@role.run_list_for('QA')[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list_for('QA')[1]).to eq('role[person]')
+ expect(@role.run_list_for('QA')[2]).to eq('role[bird]')
+ expect(@role.run_list_for('QA')[3]).to eq('role[town]')
+ expect(@role.run_list_for('PRD')[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list_for('PRD')[1]).to eq('role[monkey]')
+ expect(@role.run_list_for('PRD')[2]).to eq('recipe[duck::type]')
+ expect(@role.run_list_for('PRD')[3]).to eq('role[person]')
+ expect(@role.run_list_for('PRD')[4]).to eq('role[bird]')
+ expect(@role.run_list_for('PRD')[5]).to eq('role[town]')
+ end
+ end
+ end
+end
+
+
+
diff --git a/spec/unit/knife/role_env_run_list_replace_spec.rb b/spec/unit/knife/role_env_run_list_replace_spec.rb
new file mode 100644
index 0000000000..ea48601b8d
--- /dev/null
+++ b/spec/unit/knife/role_env_run_list_replace_spec.rb
@@ -0,0 +1,108 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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 'spec_helper'
+
+describe Chef::Knife::RoleEnvRunListReplace do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ Chef::Config[:env_name] = "QA"
+ @setup = Chef::Knife::RoleEnvRunListAdd.new
+ @setup.name_args = [ "will", "QA", "role[monkey]", "role[dude]", "role[fixer]" ]
+
+ @knife = Chef::Knife::RoleEnvRunListReplace.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "QA", "role[dude]", "role[person]" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should remove the item from the run list" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list_for('QA')[1]).not_to eq('role[dude]')
+ expect(@role.run_list_for('QA')[1]).to eq('role[person]')
+ expect(@role.run_list[0]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "run with a list of roles and recipes" do
+ it "should replace the items from the run list" do
+ @setup.name_args = [ "will", "QA", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @setup.name_args = [ "will", "PRD", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ 'will', 'QA', 'role[monkey]', 'role[gibbon]' ]
+ @knife.run
+ @knife.name_args = [ 'will', 'QA', 'recipe[duck::type]', 'recipe[duck::mallard]' ]
+ @knife.run
+ expect(@role.run_list_for('QA')).not_to include('role[monkey]')
+ expect(@role.run_list_for('QA')).not_to include('recipe[duck::type]')
+ expect(@role.run_list_for('QA')[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list_for('QA')[1]).to eq('role[gibbon]')
+ expect(@role.run_list_for('QA')[2]).to eq('recipe[duck::mallard]')
+ expect(@role.run_list_for('QA')[3]).to eq('role[person]')
+ expect(@role.run_list_for('QA')[4]).to eq('role[bird]')
+ expect(@role.run_list_for('QA')[5]).to eq('role[town]')
+ expect(@role.run_list_for('PRD')[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list_for('PRD')[1]).to eq('role[monkey]')
+ expect(@role.run_list_for('PRD')[2]).to eq('recipe[duck::type]')
+ expect(@role.run_list_for('PRD')[3]).to eq('role[person]')
+ expect(@role.run_list_for('PRD')[4]).to eq('role[bird]')
+ expect(@role.run_list_for('PRD')[5]).to eq('role[town]')
+ expect(@role.run_list[0]).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/unit/knife/role_env_run_list_set_spec.rb b/spec/unit/knife/role_env_run_list_set_spec.rb
new file mode 100644
index 0000000000..f3abb86fcf
--- /dev/null
+++ b/spec/unit/knife/role_env_run_list_set_spec.rb
@@ -0,0 +1,102 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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 'spec_helper'
+
+describe Chef::Knife::RoleEnvRunListSet do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ Chef::Config[:env_name] = "QA"
+ @setup = Chef::Knife::RoleEnvRunListAdd.new
+ @setup.name_args = [ "will", "QA", "role[monkey]", "role[person]", "role[bucket]" ]
+
+ @knife = Chef::Knife::RoleEnvRunListSet.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "QA", "role[owen]", "role[mauntel]" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should replace all the items in the runlist with what is specified" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list_for('QA')[0]).to eq("role[owen]")
+ expect(@role.run_list_for('QA')[1]).to eq("role[mauntel]")
+ expect(@role.run_list_for('QA')[2]).to be_nil
+ expect(@role.run_list[0]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "should clear an environmental run list of roles and recipes" do
+ it "should remove the items from the run list" do
+ @setup.name_args = [ "will", "QA", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @setup.name_args = [ "will", "PRD", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ "will", "QA", "role[coke]", "role[pepsi]" ]
+ @knife.run
+ expect(@role.run_list_for('QA')[0]).to eq("role[coke]")
+ expect(@role.run_list_for('QA')[1]).to eq("role[pepsi]")
+ expect(@role.run_list_for('QA')[2]).to be_nil
+ expect(@role.run_list_for('PRD')[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list_for('PRD')[1]).to eq('role[monkey]')
+ expect(@role.run_list_for('PRD')[2]).to eq('recipe[duck::type]')
+ expect(@role.run_list_for('PRD')[3]).to eq('role[person]')
+ expect(@role.run_list_for('PRD')[4]).to eq('role[bird]')
+ expect(@role.run_list_for('PRD')[5]).to eq('role[town]')
+ expect(@role.run_list[0]).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/unit/knife/role_from_file_spec.rb b/spec/unit/knife/role_from_file_spec.rb
index 986414647c..9379f08de3 100644
--- a/spec/unit/knife/role_from_file_spec.rb
+++ b/spec/unit/knife/role_from_file_spec.rb
@@ -28,30 +28,30 @@ describe Chef::Knife::RoleFromFile do
:print_after => nil
}
@knife.name_args = [ "adam.rb" ]
- @knife.stub(:output).and_return(true)
- @knife.stub(:confirm).and_return(true)
+ allow(@knife).to receive(:output).and_return(true)
+ allow(@knife).to receive(:confirm).and_return(true)
@role = Chef::Role.new()
- @role.stub(:save)
- @knife.loader.stub(:load_from).and_return(@role)
+ allow(@role).to receive(:save)
+ allow(@knife.loader).to receive(:load_from).and_return(@role)
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
describe "run" do
it "should load from a file" do
- @knife.loader.should_receive(:load_from).with('roles', 'adam.rb').and_return(@role)
+ expect(@knife.loader).to receive(:load_from).with('roles', 'adam.rb').and_return(@role)
@knife.run
end
it "should not print the role" do
- @knife.should_not_receive(:output)
+ expect(@knife).not_to receive(:output)
@knife.run
end
describe "with -p or --print-after" do
it "should print the role" do
@knife.config[:print_after] = true
- @knife.should_receive(:output)
+ expect(@knife).to receive(:output)
@knife.run
end
end
@@ -60,8 +60,8 @@ describe Chef::Knife::RoleFromFile do
describe "run with multiple arguments" do
it "should load each file" do
@knife.name_args = [ "adam.rb", "caleb.rb" ]
- @knife.loader.should_receive(:load_from).with('roles', 'adam.rb').and_return(@role)
- @knife.loader.should_receive(:load_from).with('roles', 'caleb.rb').and_return(@role)
+ expect(@knife.loader).to receive(:load_from).with('roles', 'adam.rb').and_return(@role)
+ expect(@knife.loader).to receive(:load_from).with('roles', 'caleb.rb').and_return(@role)
@knife.run
end
end
diff --git a/spec/unit/knife/role_list_spec.rb b/spec/unit/knife/role_list_spec.rb
index ef9642c04c..808a04d204 100644
--- a/spec/unit/knife/role_list_spec.rb
+++ b/spec/unit/knife/role_list_spec.rb
@@ -22,31 +22,31 @@ describe Chef::Knife::RoleList do
before(:each) do
Chef::Config[:node_name] = "webmonkey.example.com"
@knife = Chef::Knife::RoleList.new
- @knife.stub(:output).and_return(true)
+ allow(@knife).to receive(:output).and_return(true)
@list = {
"foo" => "http://example.com/foo",
"bar" => "http://example.com/foo"
}
- Chef::Role.stub(:list).and_return(@list)
+ allow(Chef::Role).to receive(:list).and_return(@list)
end
describe "run" do
it "should list the roles" do
- Chef::Role.should_receive(:list).and_return(@list)
+ expect(Chef::Role).to receive(:list).and_return(@list)
@knife.run
end
it "should pretty print the list" do
- Chef::Role.should_receive(:list).and_return(@list)
- @knife.should_receive(:output).with([ "bar", "foo" ])
+ expect(Chef::Role).to receive(:list).and_return(@list)
+ expect(@knife).to receive(:output).with([ "bar", "foo" ])
@knife.run
end
describe "with -w or --with-uri" do
it "should pretty print the hash" do
@knife.config[:with_uri] = true
- Chef::Role.should_receive(:list).and_return(@list)
- @knife.should_receive(:output).with(@list)
+ expect(Chef::Role).to receive(:list).and_return(@list)
+ expect(@knife).to receive(:output).with(@list)
@knife.run
end
end
diff --git a/spec/unit/knife/role_run_list_add_spec.rb b/spec/unit/knife/role_run_list_add_spec.rb
new file mode 100644
index 0000000000..d61c114912
--- /dev/null
+++ b/spec/unit/knife/role_run_list_add_spec.rb
@@ -0,0 +1,179 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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 'spec_helper'
+
+describe Chef::Knife::RoleRunListAdd do
+ before(:each) do
+# Chef::Config[:role_name] = "websimian"
+# Chef::Config[:env_name] = "QA"
+ @knife = Chef::Knife::RoleRunListAdd.new
+ @knife.config = {
+ :after => nil
+ }
+ @knife.name_args = [ "will", "role[monkey]" ]
+ allow(@knife).to receive(:output).and_return(true)
+ @role = Chef::Role.new()
+ allow(@role).to receive(:save).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+ end
+
+ describe "run" do
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should have a run list with the monkey role" do
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[monkey]")
+ end
+
+ it "should load the role named will" do
+ expect(Chef::Role).to receive(:load).with("will")
+ @knife.run
+ end
+
+ it "should save the role" do
+ expect(@role).to receive(:save)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.run
+ end
+
+ describe "with -a or --after specified" do
+ it "should not create a change if the specified 'after' never comes" do
+ @role.run_list_for("_default") << "role[acorns]"
+ @role.run_list_for("_default") << "role[barn]"
+ @knife.config[:after] = "role[tree]"
+ @knife.name_args = [ "will", "role[pad]" ]
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[barn]")
+ expect(@role.run_list[2]).to be_nil
+ end
+
+ it "should add to the run list after the specified entries in the default run list" do
+ #Setup
+ @role.run_list_for("_default") << "role[acorns]"
+ @role.run_list_for("_default") << "role[barn]"
+ #Configuration we are testing
+ @knife.config[:after] = "role[acorns]"
+ @knife.name_args = [ "will", "role[pad]", "role[whackadoo]" ]
+ @knife.run
+ #The actual tests
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[pad]")
+ expect(@role.run_list[2]).to eq("role[whackadoo]")
+ expect(@role.run_list[3]).to eq("role[barn]")
+ expect(@role.run_list[4]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe" do
+ it "should add to the QA run list all the entries" do
+ @knife.name_args = [ "will", "role[monkey],role[duck]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[monkey]")
+ expect(@role.run_list[2]).to eq("role[duck]")
+ expect(@role.run_list[3]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe with space between items" do
+ it "should add to the run list all the entries" do
+ @knife.name_args = [ "will", "role[monkey], role[duck]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[monkey]")
+ expect(@role.run_list[2]).to eq("role[duck]")
+ expect(@role.run_list[3]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe as different arguments" do
+ it "should add to the run list all the entries" do
+ @knife.name_args = [ "will", "role[monkey]", "role[duck]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[monkey]")
+ expect(@role.run_list[2]).to eq("role[duck]")
+ expect(@role.run_list[3]).to be_nil
+ end
+ end
+
+ describe "with more than one role or recipe as different arguments and list separated by comas" do
+ it "should add to the run list all the entries" do
+ @knife.name_args = [ "will", "role[monkey]", "role[duck],recipe[bird::fly]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[monkey]")
+ expect(@role.run_list[2]).to eq("role[duck]")
+ expect(@role.run_list[3]).to eq("recipe[bird::fly]")
+ expect(@role.run_list[4]).to be_nil
+ end
+ end
+
+ describe "Recipe with version number is allowed" do
+ it "should add to the run list all the entries including the versioned recipe" do
+ @knife.name_args = [ "will", "role[monkey]", "role[duck],recipe[bird::fly@1.1.3]" ]
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[monkey]")
+ expect(@role.run_list[2]).to eq("role[duck]")
+ expect(@role.run_list[3]).to eq("recipe[bird::fly@1.1.3]")
+ expect(@role.run_list[4]).to be_nil
+ end
+ end
+
+ describe "with one role or recipe but with an extraneous comma" do
+ it "should add to the run list one item" do
+ @role.run_list_for("_default") << "role[acorns]"
+ @knife.name_args = [ "will", "role[monkey]," ]
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[acorns]")
+ expect(@role.run_list[1]).to eq("role[monkey]")
+ expect(@role.run_list[2]).to be_nil
+ end
+ end
+
+ describe "with more than one command" do
+ it "should be able to the environment run list by running multiple knife commands" do
+ @knife.name_args = [ "will", "role[blue]," ]
+ @knife.run
+ @knife.name_args = [ "will", "role[black]," ]
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[blue]")
+ expect(@role.run_list[1]).to eq("role[black]")
+ expect(@role.run_list[2]).to be_nil
+ end
+ end
+
+ end
+end
diff --git a/spec/unit/knife/role_run_list_clear_spec.rb b/spec/unit/knife/role_run_list_clear_spec.rb
new file mode 100644
index 0000000000..e5a6e18673
--- /dev/null
+++ b/spec/unit/knife/role_run_list_clear_spec.rb
@@ -0,0 +1,90 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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 'spec_helper'
+
+describe Chef::Knife::RoleRunListClear do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ @setup = Chef::Knife::RoleRunListAdd.new
+ @setup.name_args = [ "will", "role[monkey]", "role[person]" ]
+
+ @knife = Chef::Knife::RoleRunListClear.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should remove the item from the run list" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list[0]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "should clear an environmental run list of roles and recipes" do
+ it "should remove the items from the run list" do
+ @setup.name_args = [ "will", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ 'will' ]
+ @knife.run
+ expect(@role.run_list[0]).to be_nil
+ end
+ end
+ end
+end
+
+
+
diff --git a/spec/unit/knife/role_run_list_remove_spec.rb b/spec/unit/knife/role_run_list_remove_spec.rb
new file mode 100644
index 0000000000..0f4adf253b
--- /dev/null
+++ b/spec/unit/knife/role_run_list_remove_spec.rb
@@ -0,0 +1,98 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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 'spec_helper'
+
+describe Chef::Knife::RoleRunListRemove do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ @setup = Chef::Knife::RoleRunListAdd.new
+ @setup.name_args = [ "will", "role[monkey]", "role[person]" ]
+
+ @knife = Chef::Knife::RoleRunListRemove.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "role[monkey]" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should remove the item from the run list" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list[0]).to eq('role[person]')
+ expect(@role.run_list[1]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "run with a list of roles and recipes" do
+ it "should remove the items from the run list" do
+ @setup.name_args = [ "will", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ 'will', 'role[monkey]' ]
+ @knife.run
+ @knife.name_args = [ 'will', 'recipe[duck::type]' ]
+ @knife.run
+ expect(@role.run_list).not_to include('role[monkey]')
+ expect(@role.run_list).not_to include('recipe[duck::type]')
+ expect(@role.run_list[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list[1]).to eq('role[person]')
+ expect(@role.run_list[2]).to eq('role[bird]')
+ expect(@role.run_list[3]).to eq('role[town]')
+ end
+ end
+ end
+end
+
+
+
diff --git a/spec/unit/knife/role_run_list_replace_spec.rb b/spec/unit/knife/role_run_list_replace_spec.rb
new file mode 100644
index 0000000000..2ff38f573c
--- /dev/null
+++ b/spec/unit/knife/role_run_list_replace_spec.rb
@@ -0,0 +1,101 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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 'spec_helper'
+
+describe Chef::Knife::RoleRunListReplace do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ @setup = Chef::Knife::RoleRunListAdd.new
+ @setup.name_args = [ "will", "role[monkey]", "role[dude]", "role[fixer]" ]
+
+ @knife = Chef::Knife::RoleRunListReplace.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "role[dude]", "role[person]" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should remove the item from the run list" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list[0]).to eq('role[monkey]')
+ expect(@role.run_list[1]).not_to eq('role[dude]')
+ expect(@role.run_list[1]).to eq('role[person]')
+ expect(@role.run_list[2]).to eq('role[fixer]')
+ expect(@role.run_list[3]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "run with a list of roles and recipes" do
+ it "should replace the items from the run list" do
+ @setup.name_args = [ "will", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ 'will', 'role[monkey]', 'role[gibbon]' ]
+ @knife.run
+ @knife.name_args = [ 'will', 'recipe[duck::type]', 'recipe[duck::mallard]' ]
+ @knife.run
+ expect(@role.run_list).not_to include('role[monkey]')
+ expect(@role.run_list).not_to include('recipe[duck::type]')
+ expect(@role.run_list[0]).to eq('recipe[orange::chicken]')
+ expect(@role.run_list[1]).to eq('role[gibbon]')
+ expect(@role.run_list[2]).to eq('recipe[duck::mallard]')
+ expect(@role.run_list[3]).to eq('role[person]')
+ expect(@role.run_list[4]).to eq('role[bird]')
+ expect(@role.run_list[5]).to eq('role[town]')
+ expect(@role.run_list[6]).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/unit/knife/role_run_list_set_spec.rb b/spec/unit/knife/role_run_list_set_spec.rb
new file mode 100644
index 0000000000..1350741f10
--- /dev/null
+++ b/spec/unit/knife/role_run_list_set_spec.rb
@@ -0,0 +1,92 @@
+#
+# Author:: Adam Jacob (<adam@opscode.com>)
+# Author:: Will Albenzi (<walbenzi@gmail.com>)
+# Copyright:: Copyright (c) 2008 Opscode, 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 'spec_helper'
+
+describe Chef::Knife::RoleRunListSet do
+ before(:each) do
+ Chef::Config[:role_name] = "will"
+ @setup = Chef::Knife::RoleRunListAdd.new
+ @setup.name_args = [ "will", "role[monkey]", "role[person]", "role[bucket]" ]
+
+ @knife = Chef::Knife::RoleRunListSet.new
+ @knife.config = {
+ :print_after => nil
+ }
+ @knife.name_args = [ "will", "role[owen]", "role[mauntel]" ]
+ allow(@knife).to receive(:output).and_return(true)
+
+ @role = Chef::Role.new()
+ @role.name("will")
+ allow(@role).to receive(:save).and_return(true)
+
+ allow(@knife.ui).to receive(:confirm).and_return(true)
+ allow(Chef::Role).to receive(:load).and_return(@role)
+
+ end
+
+
+
+ describe "run" do
+
+
+# it "should display all the things" do
+# @knife.run
+# @role.to_json.should == 'show all the things'
+# end
+
+ it "should load the node" do
+ expect(Chef::Role).to receive(:load).with("will").and_return(@role)
+ @knife.run
+ end
+
+ it "should replace all the items in the runlist with what is specified" do
+ @setup.run
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[owen]")
+ expect(@role.run_list[1]).to eq("role[mauntel]")
+ expect(@role.run_list[2]).to be_nil
+ end
+
+ it "should save the node" do
+ expect(@role).to receive(:save).and_return(true)
+ @knife.run
+ end
+
+ it "should print the run list" do
+ expect(@knife).to receive(:output).and_return(true)
+ @knife.config[:print_after] = true
+ @setup.run
+ @knife.run
+ end
+
+ describe "should clear an environmental run list of roles and recipes" do
+ it "should remove the items from the run list" do
+ @setup.name_args = [ "will", "recipe[orange::chicken]", "role[monkey]", "recipe[duck::type]", "role[person]", "role[bird]", "role[town]" ]
+ @setup.run
+ @knife.name_args = [ "will", "role[coke]", "role[pepsi]" ]
+ @knife.run
+ expect(@role.run_list[0]).to eq("role[coke]")
+ expect(@role.run_list[1]).to eq("role[pepsi]")
+ expect(@role.run_list[2]).to be_nil
+ expect(@role.run_list[3]).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/unit/knife/ssh_spec.rb b/spec/unit/knife/ssh_spec.rb
index 10d63c9c74..501b02c933 100644
--- a/spec/unit/knife/ssh_spec.rb
+++ b/spec/unit/knife/ssh_spec.rb
@@ -45,8 +45,8 @@ describe Chef::Knife::Ssh do
end
def configure_query(node_array)
- @query.stub(:search).and_return([node_array])
- Chef::Search::Query.stub(:new).and_return(@query)
+ allow(@query).to receive(:search).and_return([node_array])
+ allow(Chef::Search::Query).to receive(:new).and_return(@query)
end
def self.should_return_specified_attributes
@@ -54,7 +54,7 @@ describe Chef::Knife::Ssh do
@knife.config[:attribute] = "ipaddress"
@knife.config[:attribute_from_cli] = "ipaddress"
configure_query([@node_foo, @node_bar])
- @knife.should_receive(:session_from_list).with([['10.0.0.1', nil], ['10.0.0.2', nil]])
+ expect(@knife).to receive(:session_from_list).with([['10.0.0.1', nil], ['10.0.0.2', nil]])
@knife.configure_session
end
@@ -62,14 +62,14 @@ describe Chef::Knife::Ssh do
@knife.config[:attribute] = "config_file" # this value will be the config file
@knife.config[:attribute_from_cli] = "ipaddress" # this is the value of the command line via #configure_attribute
configure_query([@node_foo, @node_bar])
- @knife.should_receive(:session_from_list).with([['10.0.0.1', nil], ['10.0.0.2', nil]])
+ expect(@knife).to receive(:session_from_list).with([['10.0.0.1', nil], ['10.0.0.2', nil]])
@knife.configure_session
end
end
it "searchs for and returns an array of fqdns" do
configure_query([@node_foo, @node_bar])
- @knife.should_receive(:session_from_list).with([
+ expect(@knife).to receive(:session_from_list).with([
['foo.example.org', nil],
['bar.example.org', nil]
])
@@ -86,7 +86,7 @@ describe Chef::Knife::Ssh do
it "returns an array of cloud public hostnames" do
configure_query([@node_foo, @node_bar])
- @knife.should_receive(:session_from_list).with([
+ expect(@knife).to receive(:session_from_list).with([
['ec2-10-0-0-1.compute-1.amazonaws.com', nil],
['ec2-10-0-0-2.compute-1.amazonaws.com', nil]
])
@@ -98,22 +98,22 @@ describe Chef::Knife::Ssh do
it "should raise an error if no host are found" do
configure_query([ ])
- @knife.ui.should_receive(:fatal)
- @knife.should_receive(:exit).with(10)
+ expect(@knife.ui).to receive(:fatal)
+ expect(@knife).to receive(:exit).with(10)
@knife.configure_session
end
context "when there are some hosts found but they do not have an attribute to connect with" do
before do
- @query.stub(:search).and_return([[@node_foo, @node_bar]])
+ allow(@query).to receive(:search).and_return([[@node_foo, @node_bar]])
@node_foo.automatic_attrs[:fqdn] = nil
@node_bar.automatic_attrs[:fqdn] = nil
- Chef::Search::Query.stub(:new).and_return(@query)
+ allow(Chef::Search::Query).to receive(:new).and_return(@query)
end
it "should raise a specific error (CHEF-3402)" do
- @knife.ui.should_receive(:fatal).with(/^2 nodes found/)
- @knife.should_receive(:exit).with(10)
+ expect(@knife.ui).to receive(:fatal).with(/^2 nodes found/)
+ expect(@knife).to receive(:exit).with(10)
@knife.configure_session
end
end
@@ -126,7 +126,7 @@ describe Chef::Knife::Ssh do
it "returns an array of provided values" do
@knife.instance_variable_set(:@name_args, ["foo.example.org bar.example.org"])
- @knife.should_receive(:session_from_list).with(['foo.example.org', 'bar.example.org'])
+ expect(@knife).to receive(:session_from_list).with(['foo.example.org', 'bar.example.org'])
@knife.configure_session
end
end
@@ -140,34 +140,34 @@ describe Chef::Knife::Ssh do
it "should return fqdn by default" do
@knife.configure_attribute
- @knife.config[:attribute].should == "fqdn"
+ expect(@knife.config[:attribute]).to eq("fqdn")
end
it "should return the value set in the configuration file" do
Chef::Config[:knife][:ssh_attribute] = "config_file"
@knife.configure_attribute
- @knife.config[:attribute].should == "config_file"
+ expect(@knife.config[:attribute]).to eq("config_file")
end
it "should return the value set on the command line" do
@knife.config[:attribute] = "command_line"
@knife.configure_attribute
- @knife.config[:attribute].should == "command_line"
+ expect(@knife.config[:attribute]).to eq("command_line")
end
it "should set attribute_from_cli to the value of attribute from the command line" do
@knife.config[:attribute] = "command_line"
@knife.configure_attribute
- @knife.config[:attribute].should == "command_line"
- @knife.config[:attribute_from_cli].should == "command_line"
+ expect(@knife.config[:attribute]).to eq("command_line")
+ expect(@knife.config[:attribute_from_cli]).to eq("command_line")
end
it "should prefer the command line over the config file for the value of attribute_from_cli" do
Chef::Config[:knife][:ssh_attribute] = "config_file"
@knife.config[:attribute] = "command_line"
@knife.configure_attribute
- @knife.config[:attribute].should == "command_line"
- @knife.config[:attribute_from_cli].should == "command_line"
+ expect(@knife.config[:attribute]).to eq("command_line")
+ expect(@knife.config[:attribute_from_cli]).to eq("command_line")
end
end
@@ -175,22 +175,22 @@ describe Chef::Knife::Ssh do
before :each do
@knife.instance_variable_set(:@longest, 0)
ssh_config = {:timeout => 50, :user => "locutus", :port => 23 }
- Net::SSH.stub(:configuration_for).with('the.b.org').and_return(ssh_config)
+ allow(Net::SSH).to receive(:configuration_for).with('the.b.org').and_return(ssh_config)
end
it "uses the port from an ssh config file" do
@knife.session_from_list([['the.b.org', nil]])
- @knife.session.servers[0].port.should == 23
+ expect(@knife.session.servers[0].port).to eq(23)
end
it "uses the port from a cloud attr" do
@knife.session_from_list([['the.b.org', 123]])
- @knife.session.servers[0].port.should == 123
+ expect(@knife.session.servers[0].port).to eq(123)
end
it "uses the user from an ssh config file" do
@knife.session_from_list([['the.b.org', 123]])
- @knife.session.servers[0].user.should == "locutus"
+ expect(@knife.session.servers[0].user).to eq("locutus")
end
end
@@ -206,26 +206,26 @@ describe Chef::Knife::Ssh do
let(:command) { "false" }
before do
- execution_channel.
- should_receive(:on_request).
+ expect(execution_channel).
+ to receive(:on_request).
and_yield(nil, double(:data_stream, :read_long => exit_status))
- session_channel.
- should_receive(:exec).
+ expect(session_channel).
+ to receive(:exec).
with(command).
and_yield(execution_channel, true)
- execution_channel2.
- should_receive(:on_request).
+ expect(execution_channel2).
+ to receive(:on_request).
and_yield(nil, double(:data_stream, :read_long => exit_status2))
- session_channel2.
- should_receive(:exec).
+ expect(session_channel2).
+ to receive(:exec).
with(command).
and_yield(execution_channel2, true)
- session.
- should_receive(:open_channel).
+ expect(session).
+ to receive(:open_channel).
and_yield(session_channel).
and_yield(session_channel2)
end
@@ -235,7 +235,7 @@ describe Chef::Knife::Ssh do
let(:exit_status2) { 0 }
it "returns a 0 exit code" do
- @knife.ssh_command(command, session).should == 0
+ expect(@knife.ssh_command(command, session)).to eq(0)
end
end
@@ -244,7 +244,7 @@ describe Chef::Knife::Ssh do
let(:exit_status2) { 0 }
it "returns a non-zero exit code" do
- @knife.ssh_command(command, session).should == 1
+ expect(@knife.ssh_command(command, session)).to eq(1)
end
end
@@ -253,7 +253,7 @@ describe Chef::Knife::Ssh do
let(:exit_status2) { 2 }
it "returns a non-zero exit code" do
- @knife.ssh_command(command, session).should == 2
+ expect(@knife.ssh_command(command, session)).to eq(2)
end
end
end
@@ -261,9 +261,9 @@ describe Chef::Knife::Ssh do
describe "#run" do
before do
@query = Chef::Search::Query.new
- @query.should_receive(:search).and_return([[@node_foo]])
- Chef::Search::Query.stub(:new).and_return(@query)
- @knife.stub(:ssh_command).and_return(exit_code)
+ expect(@query).to receive(:search).and_return([[@node_foo]])
+ allow(Chef::Search::Query).to receive(:new).and_return(@query)
+ allow(@knife).to receive(:ssh_command).and_return(exit_code)
@knife.name_args = ['*:*', 'false']
end
@@ -271,7 +271,7 @@ describe Chef::Knife::Ssh do
let(:exit_code) { 1 }
it "should exit with a non-zero exit code" do
- @knife.should_receive(:exit).with(exit_code)
+ expect(@knife).to receive(:exit).with(exit_code)
@knife.run
end
end
@@ -280,7 +280,7 @@ describe Chef::Knife::Ssh do
let(:exit_code) { 0 }
it "should not exit" do
- @knife.should_not_receive(:exit)
+ expect(@knife).not_to receive(:exit)
@knife.run
end
end
@@ -296,23 +296,23 @@ describe Chef::Knife::Ssh do
# in this case ssh_password_ng exists, but ssh_password does not
it "should prompt for a password when ssh_passsword_ng is nil" do
@knife.config[:ssh_password_ng] = nil
- @knife.should_receive(:get_password).and_return("mysekretpassw0rd")
+ expect(@knife).to receive(:get_password).and_return("mysekretpassw0rd")
@knife.configure_password
- @knife.config[:ssh_password].should == "mysekretpassw0rd"
+ expect(@knife.config[:ssh_password]).to eq("mysekretpassw0rd")
end
it "should set ssh_password to false if ssh_password_ng is false" do
@knife.config[:ssh_password_ng] = false
- @knife.should_not_receive(:get_password)
+ expect(@knife).not_to receive(:get_password)
@knife.configure_password
- @knife.config[:ssh_password].should be_false
+ expect(@knife.config[:ssh_password]).to be_falsey
end
it "should set ssh_password to ssh_password_ng if we set a password" do
@knife.config[:ssh_password_ng] = "mysekretpassw0rd"
- @knife.should_not_receive(:get_password)
+ expect(@knife).not_to receive(:get_password)
@knife.configure_password
- @knife.config[:ssh_password].should == "mysekretpassw0rd"
+ expect(@knife.config[:ssh_password]).to eq("mysekretpassw0rd")
end
end
@@ -320,23 +320,23 @@ describe Chef::Knife::Ssh do
# in this case ssh_password exists, but ssh_password_ng does not
it "should set ssh_password to nil when ssh_password is nil" do
@knife.config[:ssh_password] = nil
- @knife.should_not_receive(:get_password)
+ expect(@knife).not_to receive(:get_password)
@knife.configure_password
- @knife.config[:ssh_password].should be_nil
+ expect(@knife.config[:ssh_password]).to be_nil
end
it "should set ssh_password to false when ssh_password is false" do
@knife.config[:ssh_password] = false
- @knife.should_not_receive(:get_password)
+ expect(@knife).not_to receive(:get_password)
@knife.configure_password
- @knife.config[:ssh_password].should be_false
+ expect(@knife.config[:ssh_password]).to be_falsey
end
it "should set ssh_password to ssh_password if we set a password" do
@knife.config[:ssh_password] = "mysekretpassw0rd"
- @knife.should_not_receive(:get_password)
+ expect(@knife).not_to receive(:get_password)
@knife.configure_password
- @knife.config[:ssh_password].should == "mysekretpassw0rd"
+ expect(@knife.config[:ssh_password]).to eq("mysekretpassw0rd")
end
end
context "when setting ssh_password in the config variable" do
@@ -347,23 +347,23 @@ describe Chef::Knife::Ssh do
# in this case ssh_password_ng exists, but ssh_password does not
it "should prompt for a password when ssh_passsword_ng is nil" do
@knife.config[:ssh_password_ng] = nil
- @knife.should_receive(:get_password).and_return("mysekretpassw0rd")
+ expect(@knife).to receive(:get_password).and_return("mysekretpassw0rd")
@knife.configure_password
- @knife.config[:ssh_password].should == "mysekretpassw0rd"
+ expect(@knife.config[:ssh_password]).to eq("mysekretpassw0rd")
end
it "should set ssh_password to the configured knife.rb value if ssh_password_ng is false" do
@knife.config[:ssh_password_ng] = false
- @knife.should_not_receive(:get_password)
+ expect(@knife).not_to receive(:get_password)
@knife.configure_password
- @knife.config[:ssh_password].should == "my_knife_passw0rd"
+ expect(@knife.config[:ssh_password]).to eq("my_knife_passw0rd")
end
it "should set ssh_password to ssh_password_ng if we set a password" do
@knife.config[:ssh_password_ng] = "mysekretpassw0rd"
- @knife.should_not_receive(:get_password)
+ expect(@knife).not_to receive(:get_password)
@knife.configure_password
- @knife.config[:ssh_password].should == "mysekretpassw0rd"
+ expect(@knife.config[:ssh_password]).to eq("mysekretpassw0rd")
end
end
@@ -371,23 +371,23 @@ describe Chef::Knife::Ssh do
# in this case ssh_password exists, but ssh_password_ng does not
it "should set ssh_password to the configured knife.rb value when ssh_password is nil" do
@knife.config[:ssh_password] = nil
- @knife.should_not_receive(:get_password)
+ expect(@knife).not_to receive(:get_password)
@knife.configure_password
- @knife.config[:ssh_password].should == "my_knife_passw0rd"
+ expect(@knife.config[:ssh_password]).to eq("my_knife_passw0rd")
end
it "should set ssh_password to the configured knife.rb value when ssh_password is false" do
@knife.config[:ssh_password] = false
- @knife.should_not_receive(:get_password)
+ expect(@knife).not_to receive(:get_password)
@knife.configure_password
- @knife.config[:ssh_password].should == "my_knife_passw0rd"
+ expect(@knife.config[:ssh_password]).to eq("my_knife_passw0rd")
end
it "should set ssh_password to ssh_password if we set a password" do
@knife.config[:ssh_password] = "mysekretpassw0rd"
- @knife.should_not_receive(:get_password)
+ expect(@knife).not_to receive(:get_password)
@knife.configure_password
- @knife.config[:ssh_password].should == "mysekretpassw0rd"
+ expect(@knife.config[:ssh_password]).to eq("mysekretpassw0rd")
end
end
end
diff --git a/spec/unit/knife/ssl_check_spec.rb b/spec/unit/knife/ssl_check_spec.rb
index bb803ce2ca..8eda555108 100644
--- a/spec/unit/knife/ssl_check_spec.rb
+++ b/spec/unit/knife/ssl_check_spec.rb
@@ -35,8 +35,8 @@ describe Chef::Knife::SslCheck do
subject(:ssl_check) do
s = Chef::Knife::SslCheck.new
- s.ui.stub(:stdout).and_return(stdout_io)
- s.ui.stub(:stderr).and_return(stderr_io)
+ allow(s.ui).to receive(:stdout).and_return(stdout_io)
+ allow(s.ui).to receive(:stderr).and_return(stderr_io)
s.name_args = name_args
s
end
@@ -106,17 +106,17 @@ E
before do
Chef::Config[:trusted_certs_dir] = trusted_certs_dir
- ssl_check.stub(:trusted_certificates).and_return([trusted_cert_file])
- store.stub(:add_cert).with(certificate)
- OpenSSL::X509::Store.stub(:new).and_return(store)
- OpenSSL::X509::Certificate.stub(:new).with(IO.read(trusted_cert_file)).and_return(certificate)
- ssl_check.stub(:verify_cert).and_return(true)
- ssl_check.stub(:verify_cert_host).and_return(true)
+ allow(ssl_check).to receive(:trusted_certificates).and_return([trusted_cert_file])
+ allow(store).to receive(:add_cert).with(certificate)
+ allow(OpenSSL::X509::Store).to receive(:new).and_return(store)
+ allow(OpenSSL::X509::Certificate).to receive(:new).with(IO.read(trusted_cert_file)).and_return(certificate)
+ allow(ssl_check).to receive(:verify_cert).and_return(true)
+ allow(ssl_check).to receive(:verify_cert_host).and_return(true)
end
context "when the trusted certificates have valid X509 properties" do
before do
- store.stub(:verify).with(certificate).and_return(true)
+ allow(store).to receive(:verify).with(certificate).and_return(true)
end
it "does not generate any X509 warnings" do
@@ -127,8 +127,8 @@ E
context "when the trusted certificates have invalid X509 properties" do
before do
- store.stub(:verify).with(certificate).and_return(false)
- store.stub(:error_string).and_return("unable to get local issuer certificate")
+ allow(store).to receive(:verify).with(certificate).and_return(false)
+ allow(store).to receive(:error_string).and_return("unable to get local issuer certificate")
end
it "generates a warning message with invalid certificate file names" do
@@ -145,8 +145,8 @@ E
let(:ssl_socket) { double(OpenSSL::SSL::SSLSocket) }
before do
- TCPSocket.should_receive(:new).with("foo.example.com", 8443).and_return(tcp_socket)
- OpenSSL::SSL::SSLSocket.should_receive(:new).with(tcp_socket, ssl_check.verify_peer_ssl_context).and_return(ssl_socket)
+ expect(TCPSocket).to receive(:new).with("foo.example.com", 8443).and_return(tcp_socket)
+ expect(OpenSSL::SSL::SSLSocket).to receive(:new).with(tcp_socket, ssl_check.verify_peer_ssl_context).and_return(ssl_socket)
end
def run
@@ -160,9 +160,9 @@ E
context "when the remote host's certificate is valid" do
before do
- ssl_check.should_receive(:verify_X509).and_return(true) # X509 valid certs (no warn)
- ssl_socket.should_receive(:connect) # no error
- ssl_socket.should_receive(:post_connection_check).with("foo.example.com") # no error
+ expect(ssl_check).to receive(:verify_X509).and_return(true) # X509 valid certs (no warn)
+ expect(ssl_socket).to receive(:connect) # no error
+ expect(ssl_socket).to receive(:post_connection_check).with("foo.example.com") # no error
end
it "prints a success message" do
@@ -182,23 +182,23 @@ E
before do
trap(:INT, "DEFAULT")
- TCPSocket.should_receive(:new).
+ expect(TCPSocket).to receive(:new).
with("foo.example.com", 8443).
and_return(tcp_socket_for_debug)
- OpenSSL::SSL::SSLSocket.should_receive(:new).
+ expect(OpenSSL::SSL::SSLSocket).to receive(:new).
with(tcp_socket_for_debug, ssl_check.noverify_peer_ssl_context).
and_return(ssl_socket_for_debug)
end
context "when the certificate's CN does not match the hostname" do
before do
- ssl_check.should_receive(:verify_X509).and_return(true) # X509 valid certs
- ssl_socket.should_receive(:connect) # no error
- ssl_socket.should_receive(:post_connection_check).
+ expect(ssl_check).to receive(:verify_X509).and_return(true) # X509 valid certs
+ expect(ssl_socket).to receive(:connect) # no error
+ expect(ssl_socket).to receive(:post_connection_check).
with("foo.example.com").
and_raise(OpenSSL::SSL::SSLError)
- ssl_socket_for_debug.should_receive(:connect)
- ssl_socket_for_debug.should_receive(:peer_cert).and_return(self_signed_crt)
+ expect(ssl_socket_for_debug).to receive(:connect)
+ expect(ssl_socket_for_debug).to receive(:peer_cert).and_return(self_signed_crt)
end
it "shows the CN used by the certificate and prints an error" do
@@ -212,11 +212,11 @@ E
context "when the cert is not signed by any trusted authority" do
before do
- ssl_check.should_receive(:verify_X509).and_return(true) # X509 valid certs
- ssl_socket.should_receive(:connect).
+ expect(ssl_check).to receive(:verify_X509).and_return(true) # X509 valid certs
+ expect(ssl_socket).to receive(:connect).
and_raise(OpenSSL::SSL::SSLError)
- ssl_socket_for_debug.should_receive(:connect)
- ssl_socket_for_debug.should_receive(:peer_cert).and_return(self_signed_crt)
+ expect(ssl_socket_for_debug).to receive(:connect)
+ expect(ssl_socket_for_debug).to receive(:peer_cert).and_return(self_signed_crt)
end
it "shows the CN used by the certificate and prints an error" do
diff --git a/spec/unit/knife/ssl_fetch_spec.rb b/spec/unit/knife/ssl_fetch_spec.rb
index 0d3c8913f7..cd0e423459 100644
--- a/spec/unit/knife/ssl_fetch_spec.rb
+++ b/spec/unit/knife/ssl_fetch_spec.rb
@@ -36,8 +36,8 @@ describe Chef::Knife::SslFetch do
subject(:ssl_fetch) do
s = Chef::Knife::SslFetch.new
s.name_args = name_args
- s.ui.stub(:stdout).and_return(stdout_io)
- s.ui.stub(:stderr).and_return(stderr_io)
+ allow(s.ui).to receive(:stdout).and_return(stdout_io)
+ allow(s.ui).to receive(:stderr).and_return(stderr_io)
s
end
@@ -130,22 +130,55 @@ E
before do
Chef::Config.trusted_certs_dir = trusted_certs_dir
-
- TCPSocket.should_receive(:new).with("foo.example.com", 8443).and_return(tcp_socket)
- OpenSSL::SSL::SSLSocket.should_receive(:new).with(tcp_socket, ssl_fetch.noverify_peer_ssl_context).and_return(ssl_socket)
- ssl_socket.should_receive(:connect)
- ssl_socket.should_receive(:peer_cert_chain).and_return([self_signed_crt])
end
after do
FileUtils.rm_rf(trusted_certs_dir)
end
- it "fetches the cert chain and writes the certs to the trusted_certs_dir" do
- run
- stored_cert_path = File.join(trusted_certs_dir, "example_local.crt")
- expect(File).to exist(stored_cert_path)
- expect(File.read(stored_cert_path)).to eq(File.read(self_signed_crt_path))
+ context "when the TLS connection is successful" do
+
+ before do
+ expect(TCPSocket).to receive(:new).with("foo.example.com", 8443).and_return(tcp_socket)
+ expect(OpenSSL::SSL::SSLSocket).to receive(:new).with(tcp_socket, ssl_fetch.noverify_peer_ssl_context).and_return(ssl_socket)
+ expect(ssl_socket).to receive(:connect)
+ expect(ssl_socket).to receive(:peer_cert_chain).and_return([self_signed_crt])
+ end
+
+ it "fetches the cert chain and writes the certs to the trusted_certs_dir" do
+ run
+ stored_cert_path = File.join(trusted_certs_dir, "example_local.crt")
+ expect(File).to exist(stored_cert_path)
+ expect(File.read(stored_cert_path)).to eq(File.read(self_signed_crt_path))
+ end
+
+ end
+
+ context "when connecting to a non-SSL service (like HTTP)" do
+
+ let(:name_args) { %w{http://foo.example.com} }
+
+ let(:unknown_protocol_error) { OpenSSL::SSL::SSLError.new("SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unknown protocol") }
+
+ before do
+ expect(TCPSocket).to receive(:new).with("foo.example.com", 80).and_return(tcp_socket)
+ expect(OpenSSL::SSL::SSLSocket).to receive(:new).with(tcp_socket, ssl_fetch.noverify_peer_ssl_context).and_return(ssl_socket)
+ expect(ssl_socket).to receive(:connect).and_raise(unknown_protocol_error)
+
+ expect(ssl_fetch).to receive(:exit).with(1)
+ end
+
+ it "tells the user their URL is for a non-ssl service" do
+ expected_error_text = <<-ERROR_TEXT
+ERROR: The service at the given URI (http://foo.example.com) does not accept SSL connections
+ERROR: Perhaps you meant to connect to 'https://foo.example.com'?
+ERROR_TEXT
+
+ run
+ expect(stderr).to include(expected_error_text)
+ end
+
end
+
end
end
diff --git a/spec/unit/knife/status_spec.rb b/spec/unit/knife/status_spec.rb
index bb43dd25e5..2522bc61b1 100644
--- a/spec/unit/knife/status_spec.rb
+++ b/spec/unit/knife/status_spec.rb
@@ -25,18 +25,18 @@ describe Chef::Knife::Status do
n.automatic_attrs["ohai_time"] = 1343845969
end
query = double("Chef::Search::Query")
- query.stub(:search).and_yield(node)
- Chef::Search::Query.stub(:new).and_return(query)
+ allow(query).to receive(:search).and_yield(node)
+ allow(Chef::Search::Query).to receive(:new).and_return(query)
@knife = Chef::Knife::Status.new
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
describe "run" do
it "should not colorize output unless it's writing to a tty" do
@knife.run
- @stdout.string.match(/foobar/).should_not be_nil
- @stdout.string.match(/\e.*ago/).should be_nil
+ expect(@stdout.string.match(/foobar/)).not_to be_nil
+ expect(@stdout.string.match(/\e.*ago/)).to be_nil
end
end
end
diff --git a/spec/unit/knife/tag_create_spec.rb b/spec/unit/knife/tag_create_spec.rb
index bafea8d268..586ec118bd 100644
--- a/spec/unit/knife/tag_create_spec.rb
+++ b/spec/unit/knife/tag_create_spec.rb
@@ -7,17 +7,17 @@ describe Chef::Knife::TagCreate do
@knife.name_args = [ Chef::Config[:node_name], "happytag" ]
@node = Chef::Node.new
- @node.stub :save
- Chef::Node.stub(:load).and_return @node
+ allow(@node).to receive :save
+ allow(Chef::Node).to receive(:load).and_return @node
@stderr = StringIO.new
- @knife.ui.stub(:stderr).and_return(@stderr)
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
end
describe "run" do
it "can create tags on a node" do
@knife.run
- @node.tags.should == ["happytag"]
- @stderr.string.should match /created tags happytag.+node webmonkey.example.com/i
+ expect(@node.tags).to eq(["happytag"])
+ expect(@stderr.string).to match /created tags happytag.+node webmonkey.example.com/i
end
end
end
diff --git a/spec/unit/knife/tag_delete_spec.rb b/spec/unit/knife/tag_delete_spec.rb
index 514228f0a2..e7fa108947 100644
--- a/spec/unit/knife/tag_delete_spec.rb
+++ b/spec/unit/knife/tag_delete_spec.rb
@@ -7,19 +7,19 @@ describe Chef::Knife::TagDelete do
@knife.name_args = [ Chef::Config[:node_name], "sadtag" ]
@node = Chef::Node.new
- @node.stub :save
+ allow(@node).to receive :save
@node.tags << "sadtag" << "happytag"
- Chef::Node.stub(:load).and_return @node
+ allow(Chef::Node).to receive(:load).and_return @node
@stderr = StringIO.new
- @knife.ui.stub(:stderr).and_return(@stderr)
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
end
describe "run" do
it "can delete tags on a node" do
- @node.tags.should == ["sadtag", "happytag"]
+ expect(@node.tags).to eq(["sadtag", "happytag"])
@knife.run
- @node.tags.should == ["happytag"]
- @stderr.string.should match /deleted.+sadtag/i
+ expect(@node.tags).to eq(["happytag"])
+ expect(@stderr.string).to match /deleted.+sadtag/i
end
end
end
diff --git a/spec/unit/knife/tag_list_spec.rb b/spec/unit/knife/tag_list_spec.rb
index 3724a5c0b7..9c71d22f06 100644
--- a/spec/unit/knife/tag_list_spec.rb
+++ b/spec/unit/knife/tag_list_spec.rb
@@ -7,16 +7,16 @@ describe Chef::Knife::TagList do
@knife.name_args = [ Chef::Config[:node_name], "sadtag" ]
@node = Chef::Node.new
- @node.stub :save
+ allow(@node).to receive :save
@node.tags << "sadtag" << "happytag"
- Chef::Node.stub(:load).and_return @node
+ allow(Chef::Node).to receive(:load).and_return @node
end
describe "run" do
it "can list tags on a node" do
expected = %w(sadtag happytag)
- @node.tags.should == expected
- @knife.should_receive(:output).with(expected)
+ expect(@node.tags).to eq(expected)
+ expect(@knife).to receive(:output).with(expected)
@knife.run
end
end
diff --git a/spec/unit/knife/user_create_spec.rb b/spec/unit/knife/user_create_spec.rb
index 58ef868053..ad8821cd0e 100644
--- a/spec/unit/knife/user_create_spec.rb
+++ b/spec/unit/knife/user_create_spec.rb
@@ -26,8 +26,8 @@ describe Chef::Knife::UserCreate do
@stdout = StringIO.new
@stderr = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
- @knife.ui.stub(:stderr).and_return(@stderr)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
@knife.name_args = [ 'a_user' ]
@knife.config[:user_password] = "foobar"
@@ -36,53 +36,53 @@ describe Chef::Knife::UserCreate do
@user_with_private_key = Chef::User.new
@user_with_private_key.name "a_user"
@user_with_private_key.private_key 'private_key'
- @user.stub(:create).and_return(@user_with_private_key)
- Chef::User.stub(:new).and_return(@user)
- Chef::User.stub(:from_hash).and_return(@user)
- @knife.stub(:edit_data).and_return(@user.to_hash)
+ allow(@user).to receive(:create).and_return(@user_with_private_key)
+ allow(Chef::User).to receive(:new).and_return(@user)
+ allow(Chef::User).to receive(:from_hash).and_return(@user)
+ allow(@knife).to receive(:edit_data).and_return(@user.to_hash)
end
it "creates a new user" do
- Chef::User.should_receive(:new).and_return(@user)
- @user.should_receive(:create)
+ expect(Chef::User).to receive(:new).and_return(@user)
+ expect(@user).to receive(:create)
@knife.run
- @stderr.string.should match /created user.+a_user/i
+ expect(@stderr.string).to match /created user.+a_user/i
end
it "sets the password" do
@knife.config[:user_password] = "a_password"
- @user.should_receive(:password).with("a_password")
+ expect(@user).to receive(:password).with("a_password")
@knife.run
end
it "exits with an error if password is blank" do
@knife.config[:user_password] = ''
- lambda { @knife.run }.should raise_error SystemExit
- @stderr.string.should match /You must specify a non-blank password/
+ expect { @knife.run }.to raise_error SystemExit
+ expect(@stderr.string).to match /You must specify a non-blank password/
end
it "sets the user name" do
- @user.should_receive(:name).with("a_user")
+ expect(@user).to receive(:name).with("a_user")
@knife.run
end
it "sets the public key if given" do
@knife.config[:user_key] = "/a/filename"
- File.stub(:read).with(File.expand_path("/a/filename")).and_return("a_key")
- @user.should_receive(:public_key).with("a_key")
+ allow(File).to receive(:read).with(File.expand_path("/a/filename")).and_return("a_key")
+ expect(@user).to receive(:public_key).with("a_key")
@knife.run
end
it "allows you to edit the data" do
- @knife.should_receive(:edit_data).with(@user)
+ expect(@knife).to receive(:edit_data).with(@user)
@knife.run
end
it "writes the private key to a file when --file is specified" do
@knife.config[:file] = "/tmp/a_file"
filehandle = double("filehandle")
- filehandle.should_receive(:print).with('private_key')
- File.should_receive(:open).with("/tmp/a_file", "w").and_yield(filehandle)
+ expect(filehandle).to receive(:print).with('private_key')
+ expect(File).to receive(:open).with("/tmp/a_file", "w").and_yield(filehandle)
@knife.run
end
end
diff --git a/spec/unit/knife/user_delete_spec.rb b/spec/unit/knife/user_delete_spec.rb
index be027e5128..94cfbf3db1 100644
--- a/spec/unit/knife/user_delete_spec.rb
+++ b/spec/unit/knife/user_delete_spec.rb
@@ -26,14 +26,14 @@ describe Chef::Knife::UserDelete do
end
it 'deletes the user' do
- @knife.should_receive(:delete_object).with(Chef::User, 'my_user')
+ expect(@knife).to receive(:delete_object).with(Chef::User, 'my_user')
@knife.run
end
it 'prints usage and exits when a user name is not provided' do
@knife.name_args = []
- @knife.should_receive(:show_usage)
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:show_usage)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
diff --git a/spec/unit/knife/user_edit_spec.rb b/spec/unit/knife/user_edit_spec.rb
index 20a4c0d9e9..0eb75cfa9b 100644
--- a/spec/unit/knife/user_edit_spec.rb
+++ b/spec/unit/knife/user_edit_spec.rb
@@ -25,23 +25,23 @@ describe Chef::Knife::UserEdit do
Chef::Knife::UserEdit.load_deps
@knife = Chef::Knife::UserEdit.new
- @knife.ui.stub(:stderr).and_return(@stderr)
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stderr).and_return(@stderr)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
@knife.name_args = [ 'my_user' ]
@knife.config[:disable_editing] = true
end
it 'loads and edits the user' do
data = { :name => "my_user" }
- Chef::User.stub(:load).with("my_user").and_return(data)
- @knife.should_receive(:edit_data).with(data).and_return(data)
+ allow(Chef::User).to receive(:load).with("my_user").and_return(data)
+ expect(@knife).to receive(:edit_data).with(data).and_return(data)
@knife.run
end
it 'prints usage and exits when a user name is not provided' do
@knife.name_args = []
- @knife.should_receive(:show_usage)
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:show_usage)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
diff --git a/spec/unit/knife/user_list_spec.rb b/spec/unit/knife/user_list_spec.rb
index 7a47f9ddba..db097a5c16 100644
--- a/spec/unit/knife/user_list_spec.rb
+++ b/spec/unit/knife/user_list_spec.rb
@@ -25,8 +25,8 @@ describe Chef::Knife::UserList do
end
it 'lists the users' do
- Chef::User.should_receive(:list)
- @knife.should_receive(:format_list_for_display)
+ expect(Chef::User).to receive(:list)
+ expect(@knife).to receive(:format_list_for_display)
@knife.run
end
end
diff --git a/spec/unit/knife/user_reregister_spec.rb b/spec/unit/knife/user_reregister_spec.rb
index 1cbbdb47d2..1268716f40 100644
--- a/spec/unit/knife/user_reregister_spec.rb
+++ b/spec/unit/knife/user_reregister_spec.rb
@@ -24,30 +24,30 @@ describe Chef::Knife::UserReregister do
@knife = Chef::Knife::UserReregister.new
@knife.name_args = [ 'a_user' ]
@user_mock = double('user_mock', :private_key => "private_key")
- Chef::User.stub(:load).and_return(@user_mock)
+ allow(Chef::User).to receive(:load).and_return(@user_mock)
@stdout = StringIO.new
- @knife.ui.stub(:stdout).and_return(@stdout)
+ allow(@knife.ui).to receive(:stdout).and_return(@stdout)
end
it 'prints usage and exits when a user name is not provided' do
@knife.name_args = []
- @knife.should_receive(:show_usage)
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:show_usage)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
it 'reregisters the user and prints the key' do
- @user_mock.should_receive(:reregister).and_return(@user_mock)
+ expect(@user_mock).to receive(:reregister).and_return(@user_mock)
@knife.run
- @stdout.string.should match( /private_key/ )
+ expect(@stdout.string).to match( /private_key/ )
end
it 'writes the private key to a file when --file is specified' do
- @user_mock.should_receive(:reregister).and_return(@user_mock)
+ expect(@user_mock).to receive(:reregister).and_return(@user_mock)
@knife.config[:file] = '/tmp/a_file'
filehandle = StringIO.new
- File.should_receive(:open).with('/tmp/a_file', 'w').and_yield(filehandle)
+ expect(File).to receive(:open).with('/tmp/a_file', 'w').and_yield(filehandle)
@knife.run
- filehandle.string.should == "private_key"
+ expect(filehandle.string).to eq("private_key")
end
end
diff --git a/spec/unit/knife/user_show_spec.rb b/spec/unit/knife/user_show_spec.rb
index af8485ad7d..f97cbc3f13 100644
--- a/spec/unit/knife/user_show_spec.rb
+++ b/spec/unit/knife/user_show_spec.rb
@@ -27,15 +27,15 @@ describe Chef::Knife::UserShow do
end
it 'loads and displays the user' do
- Chef::User.should_receive(:load).with('my_user').and_return(@user_mock)
- @knife.should_receive(:format_for_display).with(@user_mock)
+ expect(Chef::User).to receive(:load).with('my_user').and_return(@user_mock)
+ expect(@knife).to receive(:format_for_display).with(@user_mock)
@knife.run
end
it 'prints usage and exits when a user name is not provided' do
@knife.name_args = []
- @knife.should_receive(:show_usage)
- @knife.ui.should_receive(:fatal)
- lambda { @knife.run }.should raise_error(SystemExit)
+ expect(@knife).to receive(:show_usage)
+ expect(@knife.ui).to receive(:fatal)
+ expect { @knife.run }.to raise_error(SystemExit)
end
end
diff --git a/spec/unit/knife_spec.rb b/spec/unit/knife_spec.rb
index 86f53f6af7..2ccf8493ad 100644
--- a/spec/unit/knife_spec.rb
+++ b/spec/unit/knife_spec.rb
@@ -42,7 +42,7 @@ describe Chef::Knife do
allow(Chef::Log).to receive(:init)
allow(Chef::Log).to receive(:level)
[:debug, :info, :warn, :error, :crit].each do |level_sym|
- Chef::Log.stub(level_sym)
+ allow(Chef::Log).to receive(level_sym)
end
allow(Chef::Knife).to receive(:puts)
end
@@ -68,27 +68,27 @@ describe Chef::Knife do
end
it "has a category based on its name" do
- KnifeSpecs::TestNameMapping.subcommand_category.should == 'test'
+ expect(KnifeSpecs::TestNameMapping.subcommand_category).to eq('test')
end
- it "has an explictly defined category if set" do
- KnifeSpecs::TestExplicitCategory.subcommand_category.should == 'cookbook site'
+ it "has an explicitly defined category if set" do
+ expect(KnifeSpecs::TestExplicitCategory.subcommand_category).to eq('cookbook site')
end
it "can reference the subcommand by its snake cased name" do
- Chef::Knife.subcommands['test_name_mapping'].should equal(KnifeSpecs::TestNameMapping)
+ expect(Chef::Knife.subcommands['test_name_mapping']).to equal(KnifeSpecs::TestNameMapping)
end
it "lists subcommands by category" do
- Chef::Knife.subcommands_by_category['test'].should include('test_name_mapping')
+ expect(Chef::Knife.subcommands_by_category['test']).to include('test_name_mapping')
end
it "lists subcommands by category when the subcommands have explicit categories" do
- Chef::Knife.subcommands_by_category['cookbook site'].should include('test_explicit_category')
+ expect(Chef::Knife.subcommands_by_category['cookbook site']).to include('test_explicit_category')
end
it "has empty dependency_loader list by default" do
- KnifeSpecs::TestNameMapping.dependency_loaders.should be_empty
+ expect(KnifeSpecs::TestNameMapping.dependency_loaders).to be_empty
end
end
@@ -104,22 +104,22 @@ describe Chef::Knife do
Chef::Knife.load_commands
- Chef::Knife.subcommands.should have_key("super_awesome_command")
- Chef::Knife.subcommands["super_awesome_command"].should == SuperAwesomeCommand
+ expect(Chef::Knife.subcommands).to have_key("super_awesome_command")
+ expect(Chef::Knife.subcommands["super_awesome_command"]).to eq(SuperAwesomeCommand)
end
it "guesses a category from a given ARGV" do
Chef::Knife.subcommands_by_category["cookbook"] << :cookbook
Chef::Knife.subcommands_by_category["cookbook site"] << :cookbook_site
- Chef::Knife.guess_category(%w{cookbook foo bar baz}).should == 'cookbook'
- Chef::Knife.guess_category(%w{cookbook site foo bar baz}).should == 'cookbook site'
- Chef::Knife.guess_category(%w{cookbook site --help}).should == 'cookbook site'
+ expect(Chef::Knife.guess_category(%w{cookbook foo bar baz})).to eq('cookbook')
+ expect(Chef::Knife.guess_category(%w{cookbook site foo bar baz})).to eq('cookbook site')
+ expect(Chef::Knife.guess_category(%w{cookbook site --help})).to eq('cookbook site')
end
it "finds a subcommand class based on ARGV" do
Chef::Knife.subcommands["cookbook_site_vendor"] = :CookbookSiteVendor
Chef::Knife.subcommands["cookbook"] = :Cookbook
- Chef::Knife.subcommand_class_from(%w{cookbook site vendor --help foo bar baz}).should == :CookbookSiteVendor
+ expect(Chef::Knife.subcommand_class_from(%w{cookbook site vendor --help foo bar baz})).to eq(:CookbookSiteVendor)
end
end
@@ -137,9 +137,9 @@ describe Chef::Knife do
let(:request_mock) { {} }
let(:rest) do
- Net::HTTP.stub(:new).and_return(http_client)
- Chef::RequestID.instance.stub(:request_id).and_return(request_id)
- Chef::Config.stub(:chef_server_url).and_return("https://api.opscode.piab")
+ allow(Net::HTTP).to receive(:new).and_return(http_client)
+ allow(Chef::RequestID.instance).to receive(:request_id).and_return(request_id)
+ allow(Chef::Config).to receive(:chef_server_url).and_return("https://api.opscode.piab")
command = Chef::Knife.run(%w{test yourself})
rest = command.noauth_rest
rest
@@ -147,7 +147,7 @@ describe Chef::Knife do
let!(:http_client) do
http_client = Net::HTTP.new(url.host, url.port)
- http_client.stub(:request).and_yield(http_response).and_return(http_response)
+ allow(http_client).to receive(:request).and_yield(http_response).and_return(http_response)
http_client
end
@@ -155,8 +155,8 @@ describe Chef::Knife do
let(:http_response) do
http_response = Net::HTTPSuccess.new("1.1", "200", "successful rest req")
- http_response.stub(:read_body)
- http_response.stub(:body).and_return(body)
+ allow(http_response).to receive(:read_body)
+ allow(http_response).to receive(:body).and_return(body)
http_response["Content-Length"] = body.bytesize.to_s
http_response
end
@@ -173,7 +173,7 @@ describe Chef::Knife do
end
it "confirms that the headers include X-Remote-Request-Id" do
- Net::HTTP::Get.should_receive(:new).with("/monkey", headers).and_return(request_mock)
+ expect(Net::HTTP::Get).to receive(:new).with("/monkey", headers).and_return(request_mock)
rest.get_rest("monkey")
end
end
@@ -197,26 +197,26 @@ describe Chef::Knife do
# there is special hackery to return the subcommand instance going on here.
command = Chef::Knife.run(%w{test yourself}, extra_opts)
editor_opts = command.options[:editor]
- editor_opts[:long].should == "--editor EDITOR"
- editor_opts[:description].should == "Set the editor to use for interactive commands"
- editor_opts[:short].should == "-e EDITOR"
- editor_opts[:default].should == "/usr/bin/vim"
+ expect(editor_opts[:long]).to eq("--editor EDITOR")
+ expect(editor_opts[:description]).to eq("Set the editor to use for interactive commands")
+ expect(editor_opts[:short]).to eq("-e EDITOR")
+ expect(editor_opts[:default]).to eq("/usr/bin/vim")
end
it "creates an instance of the subcommand and runs it" do
command = Chef::Knife.run(%w{test yourself})
- command.should be_an_instance_of(KnifeSpecs::TestYourself)
- command.ran.should be_true
+ expect(command).to be_an_instance_of(KnifeSpecs::TestYourself)
+ expect(command.ran).to be_truthy
end
it "passes the command specific args to the subcommand" do
command = Chef::Knife.run(%w{test yourself with some args})
- command.name_args.should == %w{with some args}
+ expect(command.name_args).to eq(%w{with some args})
end
it "excludes the command name from the name args when parts are joined with underscores" do
command = Chef::Knife.run(%w{test_yourself with some args})
- command.name_args.should == %w{with some args}
+ expect(command.name_args).to eq(%w{with some args})
end
it "exits if no subcommand matches the CLI args" do
@@ -230,7 +230,7 @@ describe Chef::Knife do
it "loads lazy dependencies" do
Chef::Knife.run(%w{test yourself})
- KnifeSpecs::TestYourself.test_deps_loaded.should be_true
+ expect(KnifeSpecs::TestYourself.test_deps_loaded).to be_truthy
end
it "loads lazy dependencies from multiple deps calls" do
@@ -240,8 +240,8 @@ describe Chef::Knife do
end
Chef::Knife.run(%w{test yourself})
- KnifeSpecs::TestYourself.test_deps_loaded.should be_true
- other_deps_loaded.should be_true
+ expect(KnifeSpecs::TestYourself.test_deps_loaded).to be_truthy
+ expect(other_deps_loaded).to be_truthy
end
describe "merging configuration options" do
@@ -254,21 +254,21 @@ describe Chef::Knife do
it "prefers the default value if no config or command line value is present" do
knife_command = KnifeSpecs::TestYourself.new([]) #empty argv
knife_command.configure_chef
- knife_command.config[:opt_with_default].should == "default-value"
+ expect(knife_command.config[:opt_with_default]).to eq("default-value")
end
it "prefers a value in Chef::Config[:knife] to the default" do
Chef::Config[:knife][:opt_with_default] = "from-knife-config"
knife_command = KnifeSpecs::TestYourself.new([]) #empty argv
knife_command.configure_chef
- knife_command.config[:opt_with_default].should == "from-knife-config"
+ expect(knife_command.config[:opt_with_default]).to eq("from-knife-config")
end
it "prefers a value from command line over Chef::Config and the default" do
Chef::Config[:knife][:opt_with_default] = "from-knife-config"
knife_command = KnifeSpecs::TestYourself.new(["-D", "from-cli"])
knife_command.configure_chef
- knife_command.config[:opt_with_default].should == "from-cli"
+ expect(knife_command.config[:opt_with_default]).to eq("from-cli")
end
context "verbosity is greater than zero" do
@@ -311,7 +311,7 @@ describe Chef::Knife do
end
it "does not have lazy dependencies loaded" do
- expect(knife.class.test_deps_loaded).to be(nil)
+ expect(knife.class.test_deps_loaded).not_to be_truthy
end
end
diff --git a/spec/unit/lwrp_spec.rb b/spec/unit/lwrp_spec.rb
index 452e1da2a4..ec39174da6 100644
--- a/spec/unit/lwrp_spec.rb
+++ b/spec/unit/lwrp_spec.rb
@@ -33,17 +33,41 @@ describe "LWRP" do
describe "when overriding an existing class" do
before :each do
- $stderr.stub(:write)
+ allow($stderr).to receive(:write)
end
+ it "should not skip loading a resource when there's a top level symbol of the same name" do
+ Object.const_set('LwrpFoo', Class.new)
+ file = File.expand_path( "lwrp/resources/foo.rb", CHEF_SPEC_DATA)
+ expect(Chef::Log).not_to receive(:info).with(/Skipping/)
+ expect(Chef::Log).not_to receive(:debug).with(/anymore/)
+ Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
+ Object.send(:remove_const, 'LwrpFoo')
+ Chef::Resource.send(:remove_const, 'LwrpFoo')
+ end
+
+ it "should not skip loading a provider when there's a top level symbol of the same name" do
+ Object.const_set('LwrpBuckPasser', Class.new)
+ file = File.expand_path( "lwrp/providers/buck_passer.rb", CHEF_SPEC_DATA)
+ expect(Chef::Log).not_to receive(:info).with(/Skipping/)
+ expect(Chef::Log).not_to receive(:debug).with(/anymore/)
+ Chef::Provider::LWRPBase.build_from_file("lwrp", file, nil)
+ Object.send(:remove_const, 'LwrpBuckPasser')
+ Chef::Provider.send(:remove_const, 'LwrpBuckPasser')
+ end
+
+ # @todo: we need a before block to manually remove_const all of the LWRPs that we
+ # load in these tests. we're threading state through these tests in LWRPs that
+ # have already been loaded in prior tests, which probably renders some of them bogus
+
it "should log if attempting to load resource of same name" do
Dir[File.expand_path( "lwrp/resources/*", CHEF_SPEC_DATA)].each do |file|
Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
end
Dir[File.expand_path( "lwrp/resources/*", CHEF_SPEC_DATA)].each do |file|
- Chef::Log.should_receive(:info).with(/Skipping/)
- Chef::Log.should_receive(:debug).with(/anymore/)
+ expect(Chef::Log).to receive(:info).with(/Skipping/)
+ expect(Chef::Log).to receive(:debug).with(/anymore/)
Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
end
end
@@ -54,8 +78,8 @@ describe "LWRP" do
end
Dir[File.expand_path( "lwrp/providers/*", CHEF_SPEC_DATA)].each do |file|
- Chef::Log.should_receive(:info).with(/Skipping/)
- Chef::Log.should_receive(:debug).with(/anymore/)
+ expect(Chef::Log).to receive(:info).with(/Skipping/)
+ expect(Chef::Log).to receive(:debug).with(/anymore/)
Chef::Provider::LWRPBase.build_from_file("lwrp", file, nil)
end
end
@@ -67,11 +91,11 @@ describe "LWRP" do
Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
end
first_lwr_foo_class = Chef::Resource::LwrpFoo
- Chef::Resource.resource_classes.should include(first_lwr_foo_class)
+ expect(Chef::Resource.resource_classes).to include(first_lwr_foo_class)
Dir[File.expand_path( "lwrp/resources/*", CHEF_SPEC_DATA)].each do |file|
Chef::Resource::LWRPBase.build_from_file("lwrp", file, nil)
end
- Chef::Resource.resource_classes.should include(first_lwr_foo_class)
+ expect(Chef::Resource.resource_classes).to include(first_lwr_foo_class)
end
it "does not attempt to remove classes from higher up namespaces [CHEF-4117]" do
@@ -95,27 +119,27 @@ describe "LWRP" do
end
it "should load the resource into a properly-named class" do
- Chef::Resource.const_get("LwrpFoo").should be_kind_of(Class)
+ expect(Chef::Resource.const_get("LwrpFoo")).to be_kind_of(Class)
end
it "should set resource_name" do
- Chef::Resource::LwrpFoo.new("blah").resource_name.should eql(:lwrp_foo)
+ expect(Chef::Resource::LwrpFoo.new("blah").resource_name).to eql(:lwrp_foo)
end
it "should add the specified actions to the allowed_actions array" do
- Chef::Resource::LwrpFoo.new("blah").allowed_actions.should include(:pass_buck, :twiddle_thumbs)
+ expect(Chef::Resource::LwrpFoo.new("blah").allowed_actions).to include(:pass_buck, :twiddle_thumbs)
end
it "should set the specified action as the default action" do
- Chef::Resource::LwrpFoo.new("blah").action.should == :pass_buck
+ expect(Chef::Resource::LwrpFoo.new("blah").action).to eq(:pass_buck)
end
it "should create a method for each attribute" do
- Chef::Resource::LwrpFoo.new("blah").methods.map{ |m| m.to_sym}.should include(:monkey)
+ expect(Chef::Resource::LwrpFoo.new("blah").methods.map{ |m| m.to_sym}).to include(:monkey)
end
it "should build attribute methods that respect validation rules" do
- lambda { Chef::Resource::LwrpFoo.new("blah").monkey(42) }.should raise_error(ArgumentError)
+ expect { Chef::Resource::LwrpFoo.new("blah").monkey(42) }.to raise_error(ArgumentError)
end
it "should have access to the run context and node during class definition" do
@@ -128,9 +152,9 @@ describe "LWRP" do
end
cls = Chef::Resource.const_get("LwrpNodeattr")
- cls.node.should be_kind_of(Chef::Node)
- cls.run_context.should be_kind_of(Chef::RunContext)
- cls.node[:penguin_name].should eql("jackass")
+ expect(cls.node).to be_kind_of(Chef::Node)
+ expect(cls.run_context).to be_kind_of(Chef::RunContext)
+ expect(cls.node[:penguin_name]).to eql("jackass")
end
context "resource_name" do
@@ -247,7 +271,7 @@ describe "LWRP" do
end
end
- it "ammends actions when they are already defined" do
+ it "amends actions when they are already defined" do
raise_if_deprecated!
expect(child.actions).to eq([:eat, :sleep, :drink])
end
@@ -296,13 +320,13 @@ describe "LWRP" do
end
it "should load the provider into a properly-named class" do
- Chef::Provider.const_get("LwrpBuckPasser").should be_kind_of(Class)
+ expect(Chef::Provider.const_get("LwrpBuckPasser")).to be_kind_of(Class)
end
it "should create a method for each attribute" do
new_resource = double("new resource").as_null_object
- Chef::Provider::LwrpBuckPasser.new(nil, new_resource).methods.map{|m|m.to_sym}.should include(:action_pass_buck)
- Chef::Provider::LwrpThumbTwiddler.new(nil, new_resource).methods.map{|m|m.to_sym}.should include(:action_twiddle_thumbs)
+ expect(Chef::Provider::LwrpBuckPasser.new(nil, new_resource).methods.map{|m|m.to_sym}).to include(:action_pass_buck)
+ expect(Chef::Provider::LwrpThumbTwiddler.new(nil, new_resource).methods.map{|m|m.to_sym}).to include(:action_twiddle_thumbs)
end
it "should insert resources embedded in the provider into the middle of the resource collection" do
@@ -316,10 +340,10 @@ describe "LWRP" do
Chef::Runner.new(@run_context).converge
- @run_context.resource_collection[0].should eql(injector)
- @run_context.resource_collection[1].name.should eql(:prepared_thumbs)
- @run_context.resource_collection[2].name.should eql(:twiddled_thumbs)
- @run_context.resource_collection[3].should eql(dummy)
+ expect(@run_context.resource_collection[0]).to eql(injector)
+ expect(@run_context.resource_collection[1].name).to eql('prepared_thumbs')
+ expect(@run_context.resource_collection[2].name).to eql('twiddled_thumbs')
+ expect(@run_context.resource_collection[3]).to eql(dummy)
end
it "should insert embedded resources from multiple providers, including from the last position, properly into the resource collection" do
@@ -340,13 +364,13 @@ describe "LWRP" do
Chef::Runner.new(@run_context).converge
- @run_context.resource_collection[0].should eql(injector)
- @run_context.resource_collection[1].name.should eql(:prepared_thumbs)
- @run_context.resource_collection[2].name.should eql(:twiddled_thumbs)
- @run_context.resource_collection[3].should eql(dummy)
- @run_context.resource_collection[4].should eql(injector2)
- @run_context.resource_collection[5].name.should eql(:prepared_eyes)
- @run_context.resource_collection[6].name.should eql(:dried_paint_watched)
+ expect(@run_context.resource_collection[0]).to eql(injector)
+ expect(@run_context.resource_collection[1].name).to eql('prepared_thumbs')
+ expect(@run_context.resource_collection[2].name).to eql('twiddled_thumbs')
+ expect(@run_context.resource_collection[3]).to eql(dummy)
+ expect(@run_context.resource_collection[4]).to eql(injector2)
+ expect(@run_context.resource_collection[5].name).to eql('prepared_eyes')
+ expect(@run_context.resource_collection[6].name).to eql('dried_paint_watched')
end
it "should properly handle a new_resource reference" do
@@ -357,7 +381,7 @@ describe "LWRP" do
provider = Chef::Platform.provider_for_resource(resource, :twiddle_thumbs)
provider.action_twiddle_thumbs
- provider.monkey_name.should == "my monkey's name is 'bob'"
+ expect(provider.monkey_name).to eq("my monkey's name is 'bob'")
end
it "should properly handle an embedded Resource accessing the enclosing Provider's scope" do
@@ -369,7 +393,7 @@ describe "LWRP" do
#provider = @runner.build_provider(resource)
provider.action_twiddle_thumbs
- provider.enclosed_resource.monkey.should == 'bob, the monkey'
+ expect(provider.enclosed_resource.monkey).to eq('bob, the monkey')
end
describe "when using inline compilation" do
@@ -388,27 +412,27 @@ describe "LWRP" do
it "does not add interior resources to the exterior resource collection" do
@resource.run_action(:test)
- @run_context.resource_collection.should be_empty
+ expect(@run_context.resource_collection).to be_empty
end
context "when interior resources are updated" do
it "processes notifications within the LWRP provider's action" do
@resource.run_action(:test)
- $interior_ruby_block_2.should == "executed"
+ expect($interior_ruby_block_2).to eq("executed")
end
it "marks the parent resource updated" do
@resource.run_action(:test)
- @resource.should be_updated
- @resource.should be_updated_by_last_action
+ expect(@resource).to be_updated
+ expect(@resource).to be_updated_by_last_action
end
end
context "when interior resources are not updated" do
it "does not mark the parent resource updated" do
@resource.run_action(:no_updates)
- @resource.should_not be_updated
- @resource.should_not be_updated_by_last_action
+ expect(@resource).not_to be_updated
+ expect(@resource).not_to be_updated_by_last_action
end
end
diff --git a/spec/unit/mash_spec.rb b/spec/unit/mash_spec.rb
index 7358781e60..b8f4c2d5aa 100644
--- a/spec/unit/mash_spec.rb
+++ b/spec/unit/mash_spec.rb
@@ -24,27 +24,27 @@ describe Mash do
data = {:x=>"one", :y=>"two", :z=>"three"}
@orig = Mash.new(data)
@copy = @orig.dup
- @copy.to_hash.should == Mash.new(data).to_hash
+ expect(@copy.to_hash).to eq(Mash.new(data).to_hash)
@copy[:x] = "four"
- @orig[:x].should == "one"
+ expect(@orig[:x]).to eq("one")
end
it "should duplicate a mash with an array to a new mash" do
data = {:x=>"one", :y=>"two", :z=>[1,2,3]}
@orig = Mash.new(data)
@copy = @orig.dup
- @copy.to_hash.should == Mash.new(data).to_hash
+ expect(@copy.to_hash).to eq(Mash.new(data).to_hash)
@copy[:z] << 4
- @orig[:z].should == [1,2,3]
+ expect(@orig[:z]).to eq([1,2,3])
end
it "should duplicate a nested mash to a new mash" do
data = {:x=>"one", :y=>"two", :z=>Mash.new({:a=>[1,2,3]})}
@orig = Mash.new(data)
@copy = @orig.dup
- @copy.to_hash.should == Mash.new(data).to_hash
+ expect(@copy.to_hash).to eq(Mash.new(data).to_hash)
@copy[:z][:a] << 4
- @orig[:z][:a].should == [1,2,3]
+ expect(@orig[:z][:a]).to eq([1,2,3])
end
# add more!
diff --git a/spec/unit/mixin/checksum_spec.rb b/spec/unit/mixin/checksum_spec.rb
index 54689c9992..864b15f2bc 100644
--- a/spec/unit/mixin/checksum_spec.rb
+++ b/spec/unit/mixin/checksum_spec.rb
@@ -30,11 +30,11 @@ describe Chef::Mixin::Checksum do
@cache = Chef::Digester.instance
@file = CHEF_SPEC_DATA + "/checksum/random.txt"
@stat = double("File::Stat", { :mtime => Time.at(0) })
- File.stub(:stat).and_return(@stat)
+ allow(File).to receive(:stat).and_return(@stat)
end
it "gets the checksum of a file" do
- @checksum_user.checksum(@file).should == "09ee9c8cc70501763563bcf9c218d71b2fbf4186bf8e1e0da07f0f42c80a3394"
+ expect(@checksum_user.checksum(@file)).to eq("09ee9c8cc70501763563bcf9c218d71b2fbf4186bf8e1e0da07f0f42c80a3394")
end
end
diff --git a/spec/unit/mixin/command_spec.rb b/spec/unit/mixin/command_spec.rb
index 96660be436..e198e3addd 100644
--- a/spec/unit/mixin/command_spec.rb
+++ b/spec/unit/mixin/command_spec.rb
@@ -31,41 +31,41 @@ describe Chef::Mixin::Command, :volatile do
it "should be possible to read the child process's stdout and stderr" do
popen4("sh -c 'echo hello && echo world >&2'") do |pid, stdin, stdout, stderr|
- stdout.read.should == "hello\n"
- stderr.read.should == "world\n"
+ expect(stdout.read).to eq("hello\n")
+ expect(stderr.read).to eq("world\n")
end
end
it "should default all commands to be run in the POSIX standard C locale" do
popen4("echo $LC_ALL") do |pid, stdin, stdout, stderr|
- stdout.read.strip.should == "C"
+ expect(stdout.read.strip).to eq("C")
end
end
it "should respect locale when specified explicitly" do
popen4("echo $LC_ALL", :environment => {"LC_ALL" => "es"}) do |pid, stdin, stdout, stderr|
- stdout.read.strip.should == "es"
+ expect(stdout.read.strip).to eq("es")
end
end
it "should end when the child process reads from STDIN and a block is given" do
- lambda {Timeout.timeout(10) 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}" }
end
end
- }.should_not raise_error
+ }.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
- lambda {Timeout.timeout(10) do
+ expect {Timeout.timeout(10) do
pid, stdin,stdout,stderr = nil,nil,nil,nil
evil_forker="exit if fork; 10.times { sleep 1}"
popen4("ruby -e '#{evil_forker}'") do |pid,stdin,stdout,stderr|
end
- end}.should_not raise_error
+ end}.not_to raise_error
end
end
@@ -76,13 +76,13 @@ describe Chef::Mixin::Command, :volatile do
include Chef::Mixin::Command
it "logs the command's stderr and stdout output if the command failed" do
- Chef::Log.stub(:level).and_return(:debug)
+ allow(Chef::Log).to receive(:level).and_return(:debug)
begin
run_command(:command => "sh -c 'echo hello; echo world >&2; false'")
violated "Exception expected, but nothing raised."
rescue => e
- e.message.should =~ /STDOUT: hello/
- e.message.should =~ /STDERR: world/
+ expect(e.message).to match(/STDOUT: hello/)
+ expect(e.message).to match(/STDERR: world/)
end
end
@@ -93,10 +93,10 @@ 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.
- lambda {Timeout.timeout(10) do
+ expect {Timeout.timeout(10) do
evil_forker="exit if fork; 10.times { sleep 1}"
run_command(:command => "ruby -e '#{evil_forker}'")
- end}.should_not raise_error
+ end}.not_to raise_error
end
end
diff --git a/spec/unit/mixin/convert_to_class_name_spec.rb b/spec/unit/mixin/convert_to_class_name_spec.rb
index 0276a55fd7..4cf6728d64 100644
--- a/spec/unit/mixin/convert_to_class_name_spec.rb
+++ b/spec/unit/mixin/convert_to_class_name_spec.rb
@@ -29,26 +29,26 @@ describe Chef::Mixin::ConvertToClassName do
end
it "converts a_snake_case_word to a CamelCaseWord" do
- @convert.convert_to_class_name("now_camelized").should == "NowCamelized"
+ expect(@convert.convert_to_class_name("now_camelized")).to eq("NowCamelized")
end
it "converts a CamelCaseWord to a snake_case_word" do
- @convert.convert_to_snake_case("NowImASnake").should == "now_im_a_snake"
+ expect(@convert.convert_to_snake_case("NowImASnake")).to eq("now_im_a_snake")
end
it "removes the base classes before snake casing" do
- @convert.convert_to_snake_case("NameSpaced::Class::ThisIsWin", "NameSpaced::Class").should == "this_is_win"
+ expect(@convert.convert_to_snake_case("NameSpaced::Class::ThisIsWin", "NameSpaced::Class")).to eq("this_is_win")
end
it "removes the base classes without explicitly naming them and returns snake case" do
- @convert.snake_case_basename("NameSpaced::Class::ExtraWin").should == "extra_win"
+ expect(@convert.snake_case_basename("NameSpaced::Class::ExtraWin")).to eq("extra_win")
end
it "interprets non-alphanumeric characters in snake case as word boundaries" do
- @convert.convert_to_class_name("now_camelized_without-hyphen").should == "NowCamelizedWithoutHyphen"
+ expect(@convert.convert_to_class_name("now_camelized_without-hyphen")).to eq("NowCamelizedWithoutHyphen")
end
it "interprets underscore" do
- @convert.convert_to_class_name("_remove_leading_underscore").should == "RemoveLeadingUnderscore"
+ expect(@convert.convert_to_class_name("_remove_leading_underscore")).to eq("RemoveLeadingUnderscore")
end
end
diff --git a/spec/unit/mixin/deep_merge_spec.rb b/spec/unit/mixin/deep_merge_spec.rb
index d024acccdd..d107323f32 100644
--- a/spec/unit/mixin/deep_merge_spec.rb
+++ b/spec/unit/mixin/deep_merge_spec.rb
@@ -37,175 +37,175 @@ describe Chef::Mixin::DeepMerge, "deep_merge!" do
hash_src = {'id' => '2'}
hash_dst = {}
@dm.deep_merge!(hash_src.dup, hash_dst)
- hash_dst.should == hash_src
+ expect(hash_dst).to eq(hash_src)
end
it "tests merging an hash w/array into blank hash" do
hash_src = {'region' => {'id' => ['227', '2']}}
hash_dst = {}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == hash_src
+ expect(hash_dst).to eq(hash_src)
end
it "tests merge from empty hash" do
hash_src = {}
hash_dst = {"property" => ["2","4"]}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => ["2","4"]}
+ expect(hash_dst).to eq({"property" => ["2","4"]})
end
it "tests merge to empty hash" do
hash_src = {"property" => ["2","4"]}
hash_dst = {}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => ["2","4"]}
+ expect(hash_dst).to eq({"property" => ["2","4"]})
end
it "tests simple string overwrite" do
hash_src = {"name" => "value"}
hash_dst = {"name" => "value1"}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"name" => "value"}
+ expect(hash_dst).to eq({"name" => "value"})
end
it "tests simple string overwrite of empty hash" do
hash_src = {"name" => "value"}
hash_dst = {}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == hash_src
+ expect(hash_dst).to eq(hash_src)
end
it "tests hashes holding array" do
hash_src = {"property" => ["1","3"]}
hash_dst = {"property" => ["2","4"]}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => ["2","4","1","3"]}
+ expect(hash_dst).to eq({"property" => ["2","4","1","3"]})
end
it "tests hashes holding hashes holding arrays (array with duplicate elements is merged with dest then src" do
hash_src = {"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["1", "4+"]}}
hash_dst = {"property" => {"bedroom_count" => ["3", "2"], "bathroom_count" => ["2"]}}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => {"bedroom_count" => ["3","2","1"], "bathroom_count" => ["2", "1", "4+"]}}
+ expect(hash_dst).to eq({"property" => {"bedroom_count" => ["3","2","1"], "bathroom_count" => ["2", "1", "4+"]}})
end
it "tests hash holding hash holding array v string (string is overwritten by array)" do
hash_src = {"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["1", "4+"]}}
hash_dst = {"property" => {"bedroom_count" => "3", "bathroom_count" => ["2"]}}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["2","1","4+"]}}
+ expect(hash_dst).to eq({"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["2","1","4+"]}})
end
it "tests hash holding hash holding string v array (array is overwritten by string)" do
hash_src = {"property" => {"bedroom_count" => "3", "bathroom_count" => ["1", "4+"]}}
hash_dst = {"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["2"]}}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => {"bedroom_count" => "3", "bathroom_count" => ["2","1","4+"]}}
+ expect(hash_dst).to eq({"property" => {"bedroom_count" => "3", "bathroom_count" => ["2","1","4+"]}})
end
it "tests hash holding hash holding hash v array (array is overwritten by hash)" do
hash_src = {"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => 1}, "bathroom_count" => ["1", "4+"]}}
hash_dst = {"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["2"]}}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => 1}, "bathroom_count" => ["2","1","4+"]}}
+ expect(hash_dst).to eq({"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => 1}, "bathroom_count" => ["2","1","4+"]}})
end
it "tests 3 hash layers holding integers (integers are overwritten by source)" do
hash_src = {"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => 1}, "bathroom_count" => ["1", "4+"]}}
hash_dst = {"property" => {"bedroom_count" => {"king_bed" => 2, "queen_bed" => 4}, "bathroom_count" => ["2"]}}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => 1}, "bathroom_count" => ["2","1","4+"]}}
+ expect(hash_dst).to eq({"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => 1}, "bathroom_count" => ["2","1","4+"]}})
end
it "tests 3 hash layers holding arrays of int (arrays are merged)" do
hash_src = {"property" => {"bedroom_count" => {"king_bed" => [3], "queen_bed" => [1]}, "bathroom_count" => ["1", "4+"]}}
hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => {"bedroom_count" => {"king_bed" => [2,3], "queen_bed" => [4,1]}, "bathroom_count" => ["2","1","4+"]}}
+ expect(hash_dst).to eq({"property" => {"bedroom_count" => {"king_bed" => [2,3], "queen_bed" => [4,1]}, "bathroom_count" => ["2","1","4+"]}})
end
it "tests 1 hash overwriting 3 hash layers holding arrays of int" do
hash_src = {"property" => "1"}
hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => "1"}
+ expect(hash_dst).to eq({"property" => "1"})
end
it "tests 3 hash layers holding arrays of int (arrays are merged) but second hash's array is overwritten" do
hash_src = {"property" => {"bedroom_count" => {"king_bed" => [3], "queen_bed" => [1]}, "bathroom_count" => "1"}}
hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => {"bedroom_count" => {"king_bed" => [2,3], "queen_bed" => [4,1]}, "bathroom_count" => "1"}}
+ expect(hash_dst).to eq({"property" => {"bedroom_count" => {"king_bed" => [2,3], "queen_bed" => [4,1]}, "bathroom_count" => "1"}})
end
it "tests 3 hash layers holding arrays of int, but one holds int. This one overwrites, but the rest merge" do
hash_src = {"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => [1]}, "bathroom_count" => ["1"]}}
hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => [4,1]}, "bathroom_count" => ["2","1"]}}
+ expect(hash_dst).to eq({"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => [4,1]}, "bathroom_count" => ["2","1"]}})
end
it "tests 3 hash layers holding arrays of int, but source is incomplete." do
hash_src = {"property" => {"bedroom_count" => {"king_bed" => [3]}, "bathroom_count" => ["1"]}}
hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => {"bedroom_count" => {"king_bed" => [2,3], "queen_bed" => [4]}, "bathroom_count" => ["2","1"]}}
+ expect(hash_dst).to eq({"property" => {"bedroom_count" => {"king_bed" => [2,3], "queen_bed" => [4]}, "bathroom_count" => ["2","1"]}})
end
it "tests 3 hash layers holding arrays of int, but source is shorter and has new 2nd level ints." do
hash_src = {"property" => {"bedroom_count" => {2=>3, "king_bed" => [3]}, "bathroom_count" => ["1"]}}
hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => {"bedroom_count" => {2=>3, "king_bed" => [2,3], "queen_bed" => [4]}, "bathroom_count" => ["2","1"]}}
+ expect(hash_dst).to eq({"property" => {"bedroom_count" => {2=>3, "king_bed" => [2,3], "queen_bed" => [4]}, "bathroom_count" => ["2","1"]}})
end
it "tests 3 hash layers holding arrays of int, but source is empty" do
hash_src = {}
hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
+ expect(hash_dst).to eq({"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}})
end
it "tests 3 hash layers holding arrays of int, but dest is empty" do
hash_src = {"property" => {"bedroom_count" => {2=>3, "king_bed" => [3]}, "bathroom_count" => ["1"]}}
hash_dst = {}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"property" => {"bedroom_count" => {2=>3, "king_bed" => [3]}, "bathroom_count" => ["1"]}}
+ expect(hash_dst).to eq({"property" => {"bedroom_count" => {2=>3, "king_bed" => [3]}, "bathroom_count" => ["1"]}})
end
it "tests hash holding arrays of arrays" do
hash_src = {["1", "2", "3"] => ["1", "2"]}
hash_dst = {["4", "5"] => ["3"]}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {["1","2","3"] => ["1", "2"], ["4", "5"] => ["3"]}
+ expect(hash_dst).to eq({["1","2","3"] => ["1", "2"], ["4", "5"] => ["3"]})
end
it "tests merging of hash with blank hash, and make sure that source array split does not function when turned off" do
hash_src = {'property' => {'bedroom_count' => ["1","2,3"]}}
hash_dst = {}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {'property' => {'bedroom_count' => ["1","2,3"]}}
+ expect(hash_dst).to eq({'property' => {'bedroom_count' => ["1","2,3"]}})
end
it "tests merging into a blank hash" do
hash_src = {"action"=>"browse", "controller"=>"results"}
hash_dst = {}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == hash_src
+ expect(hash_dst).to eq(hash_src)
end
it "tests are unmerged hashes passed unmodified w/out :unpack_arrays?" do
hash_src = {"amenity"=>{"id"=>["26,27"]}}
hash_dst = {}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"amenity"=>{"id"=>["26,27"]}}
+ expect(hash_dst).to eq({"amenity"=>{"id"=>["26,27"]}})
end
it "tests hash of array of hashes" do
hash_src = {"item" => [{"1" => "3"}, {"2" => "4"}]}
hash_dst = {"item" => [{"3" => "5"}]}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"item" => [{"3" => "5"}, {"1" => "3"}, {"2" => "4"}]}
+ expect(hash_dst).to eq({"item" => [{"3" => "5"}, {"1" => "3"}, {"2" => "4"}]})
end
# Additions since import
@@ -213,28 +213,28 @@ describe Chef::Mixin::DeepMerge, "deep_merge!" do
hash_src = {"valid" => false}
hash_dst = {"valid" => true}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"valid" => false}
+ expect(hash_dst).to eq({"valid" => false})
end
it "should overwrite false with true when merging boolean values" do
hash_src = {"valid" => true}
hash_dst = {"valid" => false}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"valid" => true}
+ expect(hash_dst).to eq({"valid" => true})
end
it "should overwrite a string with an empty string when merging string values" do
hash_src = {"item" => " "}
hash_dst = {"item" => "orange"}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"item" => " "}
+ expect(hash_dst).to eq({"item" => " "})
end
it "should overwrite an empty string with a string when merging string values" do
hash_src = {"item" => "orange"}
hash_dst = {"item" => " "}
@dm.deep_merge!(hash_src, hash_dst)
- hash_dst.should == {"item" => "orange"}
+ expect(hash_dst).to eq({"item" => "orange"})
end
end # deep_merge!
@@ -248,40 +248,40 @@ describe Chef::Mixin::DeepMerge do
it "should merge a hash into an empty hash" do
hash_dst = {}
hash_src = {'id' => '2'}
- @dm.merge(hash_dst, hash_src).should == hash_src
+ expect(@dm.merge(hash_dst, hash_src)).to eq(hash_src)
end
it "should merge a nested hash into an empty hash" do
hash_dst = {}
hash_src = {'region' => {'id' => ['227', '2']}}
- @dm.merge(hash_dst, hash_src).should == hash_src
+ expect(@dm.merge(hash_dst, hash_src)).to eq(hash_src)
end
it "should overwrite as string value when merging hashes" do
hash_dst = {"name" => "value1"}
hash_src = {"name" => "value"}
- @dm.merge(hash_dst, hash_src).should == {"name" => "value"}
+ expect(@dm.merge(hash_dst, hash_src)).to eq({"name" => "value"})
end
it "should merge arrays within hashes" do
hash_dst = {"property" => ["2","4"]}
hash_src = {"property" => ["1","3"]}
- @dm.merge(hash_dst, hash_src).should == {"property" => ["2","4","1","3"]}
+ expect(@dm.merge(hash_dst, hash_src)).to eq({"property" => ["2","4","1","3"]})
end
it "should merge deeply nested hashes" do
hash_dst = {"property" => {"values" => {"are" => "falling", "can" => "change"}}}
hash_src = {"property" => {"values" => {"are" => "stable", "may" => "rise"}}}
- @dm.merge(hash_dst, hash_src).should == {"property" => {"values" => {"are" => "stable", "can" => "change", "may" => "rise"}}}
+ expect(@dm.merge(hash_dst, hash_src)).to eq({"property" => {"values" => {"are" => "stable", "can" => "change", "may" => "rise"}}})
end
it "should not modify the source or destination during the merge" do
hash_dst = {"property" => ["1","2","3"]}
hash_src = {"property" => ["4","5","6"]}
ret = @dm.merge(hash_dst, hash_src)
- hash_dst.should == {"property" => ["1","2","3"]}
- hash_src.should == {"property" => ["4","5","6"]}
- ret.should == {"property" => ["1","2","3","4","5","6"]}
+ expect(hash_dst).to eq({"property" => ["1","2","3"]})
+ expect(hash_src).to eq({"property" => ["4","5","6"]})
+ expect(ret).to eq({"property" => ["1","2","3","4","5","6"]})
end
it "should not error merging un-dupable objects" do
@@ -297,10 +297,10 @@ describe Chef::Mixin::DeepMerge do
merged_result = @dm.hash_only_merge(merge_ee_hash, merge_with_hash)
- merged_result["top_level_b"].should == "top-level-b-merged-onto"
- merged_result["top_level_a"]["1_deep_a"].should == "1-a-merge-ee"
- merged_result["top_level_a"]["1_deep_b"].should == "1-deep-b-merged-onto"
- merged_result["top_level_a"]["1_deep_c"].should == "1-deep-c-merged-onto"
+ expect(merged_result["top_level_b"]).to eq("top-level-b-merged-onto")
+ expect(merged_result["top_level_a"]["1_deep_a"]).to eq("1-a-merge-ee")
+ expect(merged_result["top_level_a"]["1_deep_b"]).to eq("1-deep-b-merged-onto")
+ expect(merged_result["top_level_a"]["1_deep_c"]).to eq("1-deep-c-merged-onto")
end
it "replaces arrays rather than merging them" do
@@ -309,9 +309,9 @@ describe Chef::Mixin::DeepMerge do
merged_result = @dm.hash_only_merge(merge_ee_hash, merge_with_hash)
- merged_result["top_level_b"].should == "top-level-b-merged-onto"
- merged_result["top_level_a"]["1_deep_a"].should == "1-a-merge-ee"
- merged_result["top_level_a"]["1_deep_b"].should == %w[B B B]
+ expect(merged_result["top_level_b"]).to eq("top-level-b-merged-onto")
+ expect(merged_result["top_level_a"]["1_deep_a"]).to eq("1-a-merge-ee")
+ expect(merged_result["top_level_a"]["1_deep_b"]).to eq(%w[B B B])
end
it "replaces non-hash items with hashes when there's a conflict" do
@@ -320,17 +320,17 @@ describe Chef::Mixin::DeepMerge do
merged_result = @dm.hash_only_merge(merge_ee_hash, merge_with_hash)
- merged_result["top_level_a"].should be_a(Hash)
- merged_result["top_level_a"]["1_deep_a"].should be_nil
- merged_result["top_level_a"]["1_deep_b"].should == %w[B B B]
+ expect(merged_result["top_level_a"]).to be_a(Hash)
+ expect(merged_result["top_level_a"]["1_deep_a"]).to be_nil
+ expect(merged_result["top_level_a"]["1_deep_b"]).to eq(%w[B B B])
end
it "does not mutate deeply-nested original hashes by default" do
merge_ee_hash = {"top_level_a" => {"1_deep_a" => { "2_deep_a" => { "3_deep_a" => "foo" }}}}
merge_with_hash = {"top_level_a" => {"1_deep_a" => { "2_deep_a" => { "3_deep_b" => "bar" }}}}
@dm.hash_only_merge(merge_ee_hash, merge_with_hash)
- merge_ee_hash.should == {"top_level_a" => {"1_deep_a" => { "2_deep_a" => { "3_deep_a" => "foo" }}}}
- merge_with_hash.should == {"top_level_a" => {"1_deep_a" => { "2_deep_a" => { "3_deep_b" => "bar" }}}}
+ expect(merge_ee_hash).to eq({"top_level_a" => {"1_deep_a" => { "2_deep_a" => { "3_deep_a" => "foo" }}}})
+ expect(merge_with_hash).to eq({"top_level_a" => {"1_deep_a" => { "2_deep_a" => { "3_deep_b" => "bar" }}}})
end
it "does not error merging un-dupable items" do
diff --git a/spec/unit/mixin/deprecation_spec.rb b/spec/unit/mixin/deprecation_spec.rb
index 3ebf06e830..6d9f39af9f 100644
--- a/spec/unit/mixin/deprecation_spec.rb
+++ b/spec/unit/mixin/deprecation_spec.rb
@@ -28,16 +28,16 @@ describe Chef::Mixin do
end
it "has a list of deprecated constants" do
- Chef::Mixin.deprecated_constants.should have_key(:DeprecatedClass)
+ expect(Chef::Mixin.deprecated_constants).to have_key(:DeprecatedClass)
end
it "returns the replacement when accessing the deprecated constant" do
- Chef::Mixin::DeprecatedClass.should == Chef::Node
+ expect(Chef::Mixin::DeprecatedClass).to eq(Chef::Node)
end
it "warns when accessing the deprecated constant" do
Chef::Mixin::DeprecatedClass
- @log_io.string.should include("This is a test deprecation")
+ expect(@log_io.string).to include("This is a test deprecation")
end
end
end
@@ -50,8 +50,8 @@ describe Chef::Mixin::Deprecation::DeprecatedInstanceVariable do
end
it "forward method calls to the target object" do
- @deprecated_ivar.length.should == 5
- @deprecated_ivar.to_sym.should == :value
+ expect(@deprecated_ivar.length).to eq(5)
+ expect(@deprecated_ivar.to_sym).to eq(:value)
end
end
diff --git a/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb b/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb
index fe72d53de5..aeef175ff9 100644
--- a/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb
+++ b/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb
@@ -40,15 +40,15 @@ describe Chef::Mixin::EnforceOwnershipAndPermissions do
end
it "should call set_all on the file access control object" do
- Chef::FileAccessControl.any_instance.should_receive(:set_all)
+ expect_any_instance_of(Chef::FileAccessControl).to receive(:set_all)
@provider.enforce_ownership_and_permissions
end
context "when nothing was updated" do
before do
- Chef::FileAccessControl.any_instance.stub(:uid_from_resource).and_return(0)
- Chef::FileAccessControl.any_instance.stub(:requires_changes?).and_return(false)
- Chef::FileAccessControl.any_instance.stub(:define_resource_requirements)
+ allow_any_instance_of(Chef::FileAccessControl).to receive(:uid_from_resource).and_return(0)
+ allow_any_instance_of(Chef::FileAccessControl).to receive(:requires_changes?).and_return(false)
+ allow_any_instance_of(Chef::FileAccessControl).to receive(:define_resource_requirements)
passwd_struct = if windows?
Struct::Passwd.new("root", "x", 0, 0, "/root", "/bin/bash")
@@ -56,14 +56,14 @@ describe Chef::Mixin::EnforceOwnershipAndPermissions do
Struct::Passwd.new("root", "x", 0, 0, "root", "/root", "/bin/bash")
end
group_struct = OpenStruct.new(:name => "root", :passwd => "x", :gid => 0)
- Etc.stub(:getpwuid).and_return(passwd_struct)
- Etc.stub(:getgrgid).and_return(group_struct)
+ allow(Etc).to receive(:getpwuid).and_return(passwd_struct)
+ allow(Etc).to receive(:getgrgid).and_return(group_struct)
end
it "does not set updated_by_last_action on the new resource" do
- @provider.new_resource.should_not_receive(:updated_by_last_action)
+ expect(@provider.new_resource).not_to receive(:updated_by_last_action)
- Chef::FileAccessControl.any_instance.stub(:set_all)
+ allow_any_instance_of(Chef::FileAccessControl).to receive(:set_all)
@provider.run_action(:create)
end
@@ -71,8 +71,8 @@ describe Chef::Mixin::EnforceOwnershipAndPermissions do
context "when something was modified" do
before do
- Chef::FileAccessControl.any_instance.stub(:requires_changes?).and_return(true)
- Chef::FileAccessControl.any_instance.stub(:uid_from_resource).and_return(0)
+ allow_any_instance_of(Chef::FileAccessControl).to receive(:requires_changes?).and_return(true)
+ allow_any_instance_of(Chef::FileAccessControl).to receive(:uid_from_resource).and_return(0)
passwd_struct = if windows?
Struct::Passwd.new("root", "x", 0, 0, "/root", "/bin/bash")
@@ -80,15 +80,15 @@ describe Chef::Mixin::EnforceOwnershipAndPermissions do
Struct::Passwd.new("root", "x", 0, 0, "root", "/root", "/bin/bash")
end
group_struct = OpenStruct.new(:name => "root", :passwd => "x", :gid => 0)
- Etc.stub(:getpwuid).and_return(passwd_struct)
- Etc.stub(:getgrgid).and_return(group_struct)
+ allow(Etc).to receive(:getpwuid).and_return(passwd_struct)
+ allow(Etc).to receive(:getgrgid).and_return(group_struct)
end
it "sets updated_by_last_action on the new resource" do
@provider.new_resource.owner(0) # CHEF-3557 hack - Set these because we don't for windows
@provider.new_resource.group(0) # CHEF-3557 hack - Set these because we don't for windows
- @provider.new_resource.should_receive(:updated_by_last_action)
- Chef::FileAccessControl.any_instance.stub(:set_all)
+ expect(@provider.new_resource).to receive(:updated_by_last_action)
+ allow_any_instance_of(Chef::FileAccessControl).to receive(:set_all)
@provider.run_action(:create)
end
end
diff --git a/spec/unit/mixin/homebrew_user_spec.rb b/spec/unit/mixin/homebrew_user_spec.rb
index 4e30455765..57b89720dc 100644
--- a/spec/unit/mixin/homebrew_user_spec.rb
+++ b/spec/unit/mixin/homebrew_user_spec.rb
@@ -41,7 +41,7 @@ describe Chef::Mixin::HomebrewUser do
it 'returns the homebrew user without looking at the file when name is provided' do
expect(File).to receive(:exist?).exactly(0).times
- Etc.stub_chain(:getpwnam, :uid).and_return(uid)
+ allow(Etc).to receive_message_chain(:getpwnam, :uid).and_return(uid)
expect(homebrew_user.find_homebrew_uid(user)).to eq(uid)
end
@@ -71,7 +71,7 @@ describe Chef::Mixin::HomebrewUser do
it 'returns the owner of the brew executable when it is not at a default location' do
expect(File).to receive(:exist?).with(default_brew_path).and_return(false)
- homebrew_user.stub_chain(:shell_out, :stdout, :strip).and_return("/foo")
+ allow(homebrew_user).to receive_message_chain(:shell_out, :stdout, :strip).and_return("/foo")
expect(File).to receive(:stat).with("/foo").and_return(stat_double)
expect(homebrew_user.find_homebrew_uid(user)).to eq(brew_owner)
end
@@ -83,7 +83,7 @@ describe Chef::Mixin::HomebrewUser do
it 'raises an error if no executable is found' do
expect(File).to receive(:exist?).with(default_brew_path).and_return(false)
- homebrew_user.stub_chain(:shell_out, :stdout, :strip).and_return("")
+ allow(homebrew_user).to receive_message_chain(:shell_out, :stdout, :strip).and_return("")
expect { homebrew_user.find_homebrew_uid(user) }.to raise_error(Chef::Exceptions::CannotDetermineHomebrewOwner)
end
diff --git a/spec/unit/mixin/params_validate_spec.rb b/spec/unit/mixin/params_validate_spec.rb
index cc2fe198ca..85e1c1abab 100644
--- a/spec/unit/mixin/params_validate_spec.rb
+++ b/spec/unit/mixin/params_validate_spec.rb
@@ -32,29 +32,29 @@ describe Chef::Mixin::ParamsValidate do
end
it "should allow a hash and a hash as arguments to validate" do
- lambda { @vo.validate({:one => "two"}, {}) }.should_not raise_error
+ expect { @vo.validate({:one => "two"}, {}) }.not_to raise_error
end
it "should raise an argument error if validate is called incorrectly" do
- lambda { @vo.validate("one", "two") }.should raise_error(ArgumentError)
+ expect { @vo.validate("one", "two") }.to raise_error(ArgumentError)
end
it "should require validation map keys to be symbols or strings" do
- lambda { @vo.validate({:one => "two"}, { :one => true }) }.should_not raise_error
- lambda { @vo.validate({:one => "two"}, { "one" => true }) }.should_not raise_error
- lambda { @vo.validate({:one => "two"}, { Hash.new => true }) }.should raise_error(ArgumentError)
+ expect { @vo.validate({:one => "two"}, { :one => true }) }.not_to raise_error
+ expect { @vo.validate({:one => "two"}, { "one" => true }) }.not_to raise_error
+ expect { @vo.validate({:one => "two"}, { Hash.new => true }) }.to raise_error(ArgumentError)
end
it "should allow options to be required with true" do
- lambda { @vo.validate({:one => "two"}, { :one => true }) }.should_not raise_error
+ expect { @vo.validate({:one => "two"}, { :one => true }) }.not_to raise_error
end
it "should allow options to be optional with false" do
- lambda { @vo.validate({}, {:one => false})}.should_not raise_error
+ expect { @vo.validate({}, {:one => false})}.not_to raise_error
end
it "should allow you to check what kind_of? thing an argument is with kind_of" do
- lambda {
+ expect {
@vo.validate(
{:one => "string"},
{
@@ -63,9 +63,9 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should_not raise_error
+ }.not_to raise_error
- lambda {
+ expect {
@vo.validate(
{:one => "string"},
{
@@ -74,11 +74,11 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should allow you to specify an argument is required with required" do
- lambda {
+ expect {
@vo.validate(
{:one => "string"},
{
@@ -87,9 +87,9 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should_not raise_error
+ }.not_to raise_error
- lambda {
+ expect {
@vo.validate(
{:two => "string"},
{
@@ -98,9 +98,9 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
- lambda {
+ expect {
@vo.validate(
{:two => "string"},
{
@@ -109,11 +109,11 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should_not raise_error
+ }.not_to raise_error
end
it "should allow you to specify whether an object has a method with respond_to" do
- lambda {
+ expect {
@vo.validate(
{:one => @vo},
{
@@ -122,9 +122,9 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should_not raise_error
+ }.not_to raise_error
- lambda {
+ expect {
@vo.validate(
{:one => @vo},
{
@@ -133,11 +133,11 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should raise_error(ArgumentError)
+ }.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
- lambda {
+ expect {
@vo.validate(
{:one => @vo},
{
@@ -146,9 +146,9 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should_not raise_error
+ }.not_to raise_error
- lambda {
+ expect {
@vo.validate(
{:one => @vo},
{
@@ -157,7 +157,7 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should let you set a default value with default => value" do
@@ -167,11 +167,11 @@ describe Chef::Mixin::ParamsValidate do
:default => "is the loneliest number"
}
})
- arguments[:one].should == "is the loneliest number"
+ expect(arguments[:one]).to eq("is the loneliest number")
end
it "should let you check regular expressions" do
- lambda {
+ expect {
@vo.validate(
{ :one => "is good" },
{
@@ -180,9 +180,9 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should_not raise_error
+ }.not_to raise_error
- lambda {
+ expect {
@vo.validate(
{ :one => "is good" },
{
@@ -191,11 +191,11 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should let you specify your own callbacks" do
- lambda {
+ expect {
@vo.validate(
{ :one => "is good" },
{
@@ -208,9 +208,9 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should_not raise_error
+ }.not_to raise_error
- lambda {
+ expect {
@vo.validate(
{ :one => "is bad" },
{
@@ -223,12 +223,12 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should let you combine checks" do
args = { :one => "is good", :two => "is bad" }
- lambda {
+ expect {
@vo.validate(
args,
{
@@ -250,9 +250,9 @@ describe Chef::Mixin::ParamsValidate do
:three => { :default => "neato mosquito" }
}
)
- }.should_not raise_error
- args[:three].should == "neato mosquito"
- lambda {
+ }.not_to raise_error
+ expect(args[:three]).to eq("neato mosquito")
+ expect {
@vo.validate(
args,
{
@@ -274,11 +274,11 @@ describe Chef::Mixin::ParamsValidate do
:three => { :default => "neato mosquito" }
}
)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should raise an ArgumentError if the validation map has an unknown check" do
- lambda { @vo.validate(
+ expect { @vo.validate(
{ :one => "two" },
{
:one => {
@@ -286,17 +286,17 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should accept keys that are strings in the options" do
- lambda {
+ expect {
@vo.validate({ "one" => "two" }, { :one => { :regex => /^two$/ }})
- }.should_not raise_error
+ }.not_to raise_error
end
it "should allow an array to kind_of" do
- lambda {
+ expect {
@vo.validate(
{:one => "string"},
{
@@ -305,8 +305,8 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
@vo.validate(
{:one => ["string"]},
{
@@ -315,8 +315,8 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should_not raise_error
- lambda {
+ }.not_to raise_error
+ expect {
@vo.validate(
{:one => Hash.new},
{
@@ -325,48 +325,48 @@ describe Chef::Mixin::ParamsValidate do
}
}
)
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "asserts that a value returns false from a predicate method" do
- lambda do
+ expect do
@vo.validate({:not_blank => "should pass"},
{:not_blank => {:cannot_be => :nil, :cannot_be => :empty}})
- end.should_not raise_error
- lambda do
+ end.not_to raise_error
+ expect do
@vo.validate({:not_blank => ""},
{:not_blank => {:cannot_be => :nil, :cannot_be => :empty}})
- end.should raise_error(Chef::Exceptions::ValidationFailed)
+ end.to raise_error(Chef::Exceptions::ValidationFailed)
end
it "should set and return a value, then return the same value" do
value = "meow"
- @vo.set_or_return(:test, value, {}).object_id.should == value.object_id
- @vo.set_or_return(:test, nil, {}).object_id.should == value.object_id
+ expect(@vo.set_or_return(:test, value, {}).object_id).to eq(value.object_id)
+ expect(@vo.set_or_return(:test, nil, {}).object_id).to eq(value.object_id)
end
it "should set and return a default value when the argument is nil, then return the same value" do
value = "meow"
- @vo.set_or_return(:test, nil, { :default => value }).object_id.should == value.object_id
- @vo.set_or_return(:test, nil, {}).object_id.should == value.object_id
+ expect(@vo.set_or_return(:test, nil, { :default => value }).object_id).to eq(value.object_id)
+ expect(@vo.set_or_return(:test, nil, {}).object_id).to eq(value.object_id)
end
it "should raise an ArgumentError when argument is nil and required is true" do
- lambda {
+ expect {
@vo.set_or_return(:test, nil, { :required => true })
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should not raise an error when argument is nil and required is false" do
- lambda {
+ expect {
@vo.set_or_return(:test, nil, { :required => false })
- }.should_not raise_error
+ }.not_to raise_error
end
it "should set and return @name, then return @name for foo when argument is nil" do
value = "meow"
- @vo.set_or_return(:name, value, { }).object_id.should == value.object_id
- @vo.set_or_return(:foo, nil, { :name_attribute => true }).object_id.should == value.object_id
+ expect(@vo.set_or_return(:name, value, { }).object_id).to eq(value.object_id)
+ expect(@vo.set_or_return(:foo, nil, { :name_attribute => true }).object_id).to eq(value.object_id)
end
it "should allow DelayedEvaluator instance to be set for value regardless of restriction" do
@@ -377,31 +377,31 @@ describe Chef::Mixin::ParamsValidate do
it "should raise an error when delayed evaluated attribute is not valid" do
value = Chef::DelayedEvaluator.new{ 'test' }
@vo.set_or_return(:test, value, {:kind_of => Numeric})
- lambda do
+ expect do
@vo.set_or_return(:test, nil, {:kind_of => Numeric})
- end.should raise_error(Chef::Exceptions::ValidationFailed)
+ end.to raise_error(Chef::Exceptions::ValidationFailed)
end
it "should create DelayedEvaluator instance when #lazy is used" do
@vo.set_or_return(:delayed, @vo.lazy{ 'test' }, {})
- @vo.instance_variable_get(:@delayed).should be_a(Chef::DelayedEvaluator)
+ expect(@vo.instance_variable_get(:@delayed)).to be_a(Chef::DelayedEvaluator)
end
it "should execute block on each call when DelayedEvaluator" do
value = 'fubar'
@vo.set_or_return(:test, @vo.lazy{ value }, {})
- @vo.set_or_return(:test, nil, {}).should == 'fubar'
+ expect(@vo.set_or_return(:test, nil, {})).to eq('fubar')
value = 'foobar'
- @vo.set_or_return(:test, nil, {}).should == 'foobar'
+ expect(@vo.set_or_return(:test, nil, {})).to eq('foobar')
value = 'fauxbar'
- @vo.set_or_return(:test, nil, {}).should == 'fauxbar'
+ expect(@vo.set_or_return(:test, nil, {})).to eq('fauxbar')
end
it "should not evaluate non DelayedEvaluator instances" do
value = lambda{ 'test' }
@vo.set_or_return(:test, value, {})
- @vo.set_or_return(:test, nil, {}).object_id.should == value.object_id
- @vo.set_or_return(:test, nil, {}).should be_a(Proc)
+ expect(@vo.set_or_return(:test, nil, {}).object_id).to eq(value.object_id)
+ expect(@vo.set_or_return(:test, nil, {})).to be_a(Proc)
end
end
diff --git a/spec/unit/mixin/path_sanity_spec.rb b/spec/unit/mixin/path_sanity_spec.rb
index 64c667b483..ec8e182e3d 100644
--- a/spec/unit/mixin/path_sanity_spec.rb
+++ b/spec/unit/mixin/path_sanity_spec.rb
@@ -33,54 +33,54 @@ describe Chef::Mixin::PathSanity do
Chef::Config[:enforce_path_sanity] = true
@ruby_bindir = '/some/ruby/bin'
@gem_bindir = '/some/gem/bin'
- Gem.stub(:bindir).and_return(@gem_bindir)
- RbConfig::CONFIG.stub(:[]).with('bindir').and_return(@ruby_bindir)
- Chef::Platform.stub(:windows?).and_return(false)
+ allow(Gem).to receive(:bindir).and_return(@gem_bindir)
+ allow(RbConfig::CONFIG).to receive(:[]).with('bindir').and_return(@ruby_bindir)
+ allow(Chef::Platform).to receive(:windows?).and_return(false)
end
it "adds all useful PATHs even if environment is an empty hash" do
env={}
@sanity.enforce_path_sanity(env)
- env["PATH"].should == "#{@ruby_bindir}:#{@gem_bindir}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+ expect(env["PATH"]).to eq("#{@ruby_bindir}:#{@gem_bindir}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")
end
it "adds all useful PATHs that are not yet in PATH to PATH" do
env = {"PATH" => ""}
@sanity.enforce_path_sanity(env)
- env["PATH"].should == "#{@ruby_bindir}:#{@gem_bindir}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+ expect(env["PATH"]).to eq("#{@ruby_bindir}:#{@gem_bindir}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")
end
it "does not re-add paths that already exist in PATH" do
env = {"PATH" => "/usr/bin:/sbin:/bin"}
@sanity.enforce_path_sanity(env)
- env["PATH"].should == "/usr/bin:/sbin:/bin:#{@ruby_bindir}:#{@gem_bindir}:/usr/local/sbin:/usr/local/bin:/usr/sbin"
+ expect(env["PATH"]).to eq("/usr/bin:/sbin:/bin:#{@ruby_bindir}:#{@gem_bindir}:/usr/local/sbin:/usr/local/bin:/usr/sbin")
end
it "adds the current executing Ruby's bindir and Gem bindir to the PATH" do
env = {"PATH" => ""}
@sanity.enforce_path_sanity(env)
- env["PATH"].should == "#{@ruby_bindir}:#{@gem_bindir}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+ expect(env["PATH"]).to eq("#{@ruby_bindir}:#{@gem_bindir}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")
end
it "does not create entries for Ruby/Gem bindirs if they exist in SANE_PATH or PATH" do
ruby_bindir = '/usr/bin'
gem_bindir = '/yo/gabba/gabba'
- Gem.stub(:bindir).and_return(gem_bindir)
- RbConfig::CONFIG.stub(:[]).with('bindir').and_return(ruby_bindir)
+ allow(Gem).to receive(:bindir).and_return(gem_bindir)
+ allow(RbConfig::CONFIG).to receive(:[]).with('bindir').and_return(ruby_bindir)
env = {"PATH" => gem_bindir}
@sanity.enforce_path_sanity(env)
- env["PATH"].should == "/yo/gabba/gabba:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+ expect(env["PATH"]).to eq("/yo/gabba/gabba:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")
end
it "builds a valid windows path" do
ruby_bindir = 'C:\ruby\bin'
gem_bindir = 'C:\gems\bin'
- Gem.stub(:bindir).and_return(gem_bindir)
- RbConfig::CONFIG.stub(:[]).with('bindir').and_return(ruby_bindir)
- Chef::Platform.stub(:windows?).and_return(true)
+ allow(Gem).to receive(:bindir).and_return(gem_bindir)
+ allow(RbConfig::CONFIG).to receive(:[]).with('bindir').and_return(ruby_bindir)
+ allow(Chef::Platform).to receive(:windows?).and_return(true)
env = {"PATH" => 'C:\Windows\system32;C:\mr\softie'}
@sanity.enforce_path_sanity(env)
- env["PATH"].should == "C:\\Windows\\system32;C:\\mr\\softie;#{ruby_bindir};#{gem_bindir}"
+ expect(env["PATH"]).to eq("C:\\Windows\\system32;C:\\mr\\softie;#{ruby_bindir};#{gem_bindir}")
end
end
end
diff --git a/spec/unit/mixin/securable_spec.rb b/spec/unit/mixin/securable_spec.rb
index 10954083d8..714d6dedae 100644
--- a/spec/unit/mixin/securable_spec.rb
+++ b/spec/unit/mixin/securable_spec.rb
@@ -28,19 +28,19 @@ describe Chef::Mixin::Securable do
end
it "should accept a group name or id for group" do
- lambda { @securable.group "root" }.should_not raise_error
- lambda { @securable.group 123 }.should_not raise_error
- lambda { @securable.group "+bad:group" }.should raise_error(ArgumentError)
+ expect { @securable.group "root" }.not_to raise_error
+ expect { @securable.group 123 }.not_to raise_error
+ expect { @securable.group "+bad:group" }.to raise_error(ArgumentError)
end
it "should accept a user name or id for owner" do
- lambda { @securable.owner "root" }.should_not raise_error
- lambda { @securable.owner 123 }.should_not raise_error
- lambda { @securable.owner "+bad:owner" }.should raise_error(ArgumentError)
+ expect { @securable.owner "root" }.not_to raise_error
+ expect { @securable.owner 123 }.not_to raise_error
+ expect { @securable.owner "+bad:owner" }.to raise_error(ArgumentError)
end
it "allows the owner to be specified as #user" do
- @securable.should respond_to(:user)
+ expect(@securable).to respond_to(:user)
end
describe "unix-specific behavior" do
@@ -54,69 +54,69 @@ describe Chef::Mixin::Securable do
end
it "should accept group/owner names with spaces and backslashes" do
- lambda { @securable.group 'test\ group' }.should_not raise_error
- lambda { @securable.owner 'test\ group' }.should_not raise_error
+ expect { @securable.group 'test\ group' }.not_to raise_error
+ expect { @securable.owner 'test\ group' }.not_to raise_error
end
it "should accept group/owner names that are a single character or digit" do
- lambda { @securable.group 'v' }.should_not raise_error
- lambda { @securable.group '1' }.should_not raise_error
- lambda { @securable.owner 'v' }.should_not raise_error
- lambda { @securable.owner '1' }.should_not raise_error
+ expect { @securable.group 'v' }.not_to raise_error
+ expect { @securable.group '1' }.not_to raise_error
+ expect { @securable.owner 'v' }.not_to raise_error
+ expect { @securable.owner '1' }.not_to raise_error
end
it "should not accept group/owner names starting with '-', '+', or '~'" do
- lambda { @securable.group '-test' }.should raise_error(ArgumentError)
- lambda { @securable.group '+test' }.should raise_error(ArgumentError)
- lambda { @securable.group '~test' }.should raise_error(ArgumentError)
- lambda { @securable.group 'te-st' }.should_not raise_error
- lambda { @securable.group 'te+st' }.should_not raise_error
- lambda { @securable.group 'te~st' }.should_not raise_error
- lambda { @securable.owner '-test' }.should raise_error(ArgumentError)
- lambda { @securable.owner '+test' }.should raise_error(ArgumentError)
- lambda { @securable.owner '~test' }.should raise_error(ArgumentError)
- lambda { @securable.owner 'te-st' }.should_not raise_error
- lambda { @securable.owner 'te+st' }.should_not raise_error
- lambda { @securable.owner 'te~st' }.should_not raise_error
+ expect { @securable.group '-test' }.to raise_error(ArgumentError)
+ expect { @securable.group '+test' }.to raise_error(ArgumentError)
+ expect { @securable.group '~test' }.to raise_error(ArgumentError)
+ expect { @securable.group 'te-st' }.not_to raise_error
+ expect { @securable.group 'te+st' }.not_to raise_error
+ expect { @securable.group 'te~st' }.not_to raise_error
+ expect { @securable.owner '-test' }.to raise_error(ArgumentError)
+ expect { @securable.owner '+test' }.to raise_error(ArgumentError)
+ expect { @securable.owner '~test' }.to raise_error(ArgumentError)
+ expect { @securable.owner 'te-st' }.not_to raise_error
+ expect { @securable.owner 'te+st' }.not_to raise_error
+ expect { @securable.owner 'te~st' }.not_to raise_error
end
it "should not accept group/owner names containing ':', ',' or non-space whitespace" do
- lambda { @securable.group ':test' }.should raise_error(ArgumentError)
- lambda { @securable.group 'te:st' }.should raise_error(ArgumentError)
- lambda { @securable.group ',test' }.should raise_error(ArgumentError)
- lambda { @securable.group 'te,st' }.should raise_error(ArgumentError)
- lambda { @securable.group "\ttest" }.should raise_error(ArgumentError)
- lambda { @securable.group "te\tst" }.should raise_error(ArgumentError)
- lambda { @securable.group "\rtest" }.should raise_error(ArgumentError)
- lambda { @securable.group "te\rst" }.should raise_error(ArgumentError)
- lambda { @securable.group "\ftest" }.should raise_error(ArgumentError)
- lambda { @securable.group "te\fst" }.should raise_error(ArgumentError)
- lambda { @securable.group "\0test" }.should raise_error(ArgumentError)
- lambda { @securable.group "te\0st" }.should raise_error(ArgumentError)
- lambda { @securable.owner ':test' }.should raise_error(ArgumentError)
- lambda { @securable.owner 'te:st' }.should raise_error(ArgumentError)
- lambda { @securable.owner ',test' }.should raise_error(ArgumentError)
- lambda { @securable.owner 'te,st' }.should raise_error(ArgumentError)
- lambda { @securable.owner "\ttest" }.should raise_error(ArgumentError)
- lambda { @securable.owner "te\tst" }.should raise_error(ArgumentError)
- lambda { @securable.owner "\rtest" }.should raise_error(ArgumentError)
- lambda { @securable.owner "te\rst" }.should raise_error(ArgumentError)
- lambda { @securable.owner "\ftest" }.should raise_error(ArgumentError)
- lambda { @securable.owner "te\fst" }.should raise_error(ArgumentError)
- lambda { @securable.owner "\0test" }.should raise_error(ArgumentError)
- lambda { @securable.owner "te\0st" }.should raise_error(ArgumentError)
+ expect { @securable.group ':test' }.to raise_error(ArgumentError)
+ expect { @securable.group 'te:st' }.to raise_error(ArgumentError)
+ expect { @securable.group ',test' }.to raise_error(ArgumentError)
+ expect { @securable.group 'te,st' }.to raise_error(ArgumentError)
+ expect { @securable.group "\ttest" }.to raise_error(ArgumentError)
+ expect { @securable.group "te\tst" }.to raise_error(ArgumentError)
+ expect { @securable.group "\rtest" }.to raise_error(ArgumentError)
+ expect { @securable.group "te\rst" }.to raise_error(ArgumentError)
+ expect { @securable.group "\ftest" }.to raise_error(ArgumentError)
+ expect { @securable.group "te\fst" }.to raise_error(ArgumentError)
+ expect { @securable.group "\0test" }.to raise_error(ArgumentError)
+ expect { @securable.group "te\0st" }.to raise_error(ArgumentError)
+ expect { @securable.owner ':test' }.to raise_error(ArgumentError)
+ expect { @securable.owner 'te:st' }.to raise_error(ArgumentError)
+ expect { @securable.owner ',test' }.to raise_error(ArgumentError)
+ expect { @securable.owner 'te,st' }.to raise_error(ArgumentError)
+ expect { @securable.owner "\ttest" }.to raise_error(ArgumentError)
+ expect { @securable.owner "te\tst" }.to raise_error(ArgumentError)
+ expect { @securable.owner "\rtest" }.to raise_error(ArgumentError)
+ expect { @securable.owner "te\rst" }.to raise_error(ArgumentError)
+ expect { @securable.owner "\ftest" }.to raise_error(ArgumentError)
+ expect { @securable.owner "te\fst" }.to raise_error(ArgumentError)
+ expect { @securable.owner "\0test" }.to raise_error(ArgumentError)
+ expect { @securable.owner "te\0st" }.to raise_error(ArgumentError)
end
it "should accept Active Directory-style domain names pulled in via LDAP (on unix hosts)" do
- lambda { @securable.owner "domain\@user" }.should_not raise_error
- lambda { @securable.owner "domain\\user" }.should_not raise_error
- lambda { @securable.group "domain\@group" }.should_not raise_error
- lambda { @securable.group "domain\\group" }.should_not raise_error
- lambda { @securable.group "domain\\group^name" }.should_not raise_error
+ expect { @securable.owner "domain\@user" }.not_to raise_error
+ expect { @securable.owner "domain\\user" }.not_to raise_error
+ expect { @securable.group "domain\@group" }.not_to raise_error
+ expect { @securable.group "domain\\group" }.not_to raise_error
+ expect { @securable.group "domain\\group^name" }.not_to raise_error
end
it "should not accept group/owner names containing embedded carriage returns" do
- pending "XXX: params_validate needs to be extended to support multi-line regex"
+ skip "XXX: params_validate needs to be extended to support multi-line regex"
#lambda { @securable.group "\ntest" }.should raise_error(ArgumentError)
#lambda { @securable.group "te\nst" }.should raise_error(ArgumentError)
#lambda { @securable.owner "\ntest" }.should raise_error(ArgumentError)
@@ -124,53 +124,53 @@ describe Chef::Mixin::Securable do
end
it "should accept group/owner names in UTF-8" do
- lambda { @securable.group 'tëst' }.should_not raise_error
- lambda { @securable.group 'ë' }.should_not raise_error
- lambda { @securable.owner 'tëst' }.should_not raise_error
- lambda { @securable.owner 'ë' }.should_not raise_error
+ expect { @securable.group 'tëst' }.not_to raise_error
+ expect { @securable.group 'ë' }.not_to raise_error
+ expect { @securable.owner 'tëst' }.not_to raise_error
+ expect { @securable.owner 'ë' }.not_to raise_error
end
it "should accept a unix file mode in string form as an octal number" do
- lambda { @securable.mode "0" }.should_not raise_error
- lambda { @securable.mode "0000" }.should_not raise_error
- lambda { @securable.mode "0111" }.should_not raise_error
- lambda { @securable.mode "0444" }.should_not raise_error
-
- lambda { @securable.mode "111" }.should_not raise_error
- lambda { @securable.mode "444" }.should_not raise_error
- lambda { @securable.mode "7777" }.should_not raise_error
- lambda { @securable.mode "07777" }.should_not raise_error
-
- lambda { @securable.mode "-01" }.should raise_error(ArgumentError)
- lambda { @securable.mode "010000" }.should raise_error(ArgumentError)
- lambda { @securable.mode "-1" }.should raise_error(ArgumentError)
- lambda { @securable.mode "10000" }.should raise_error(ArgumentError)
-
- lambda { @securable.mode "07778" }.should raise_error(ArgumentError)
- lambda { @securable.mode "7778" }.should raise_error(ArgumentError)
- lambda { @securable.mode "4095" }.should raise_error(ArgumentError)
-
- lambda { @securable.mode "0foo1234" }.should raise_error(ArgumentError)
- lambda { @securable.mode "foo1234" }.should raise_error(ArgumentError)
+ expect { @securable.mode "0" }.not_to raise_error
+ expect { @securable.mode "0000" }.not_to raise_error
+ expect { @securable.mode "0111" }.not_to raise_error
+ expect { @securable.mode "0444" }.not_to raise_error
+
+ expect { @securable.mode "111" }.not_to raise_error
+ expect { @securable.mode "444" }.not_to raise_error
+ expect { @securable.mode "7777" }.not_to raise_error
+ expect { @securable.mode "07777" }.not_to raise_error
+
+ expect { @securable.mode "-01" }.to raise_error(ArgumentError)
+ expect { @securable.mode "010000" }.to raise_error(ArgumentError)
+ expect { @securable.mode "-1" }.to raise_error(ArgumentError)
+ expect { @securable.mode "10000" }.to raise_error(ArgumentError)
+
+ expect { @securable.mode "07778" }.to raise_error(ArgumentError)
+ expect { @securable.mode "7778" }.to raise_error(ArgumentError)
+ expect { @securable.mode "4095" }.to raise_error(ArgumentError)
+
+ expect { @securable.mode "0foo1234" }.to raise_error(ArgumentError)
+ expect { @securable.mode "foo1234" }.to raise_error(ArgumentError)
end
it "should accept a unix file mode in numeric form as a ruby-interpreted integer" do
- lambda { @securable.mode(0) }.should_not raise_error
- lambda { @securable.mode(0000) }.should_not raise_error
- lambda { @securable.mode(444) }.should_not raise_error
- lambda { @securable.mode(0444) }.should_not raise_error
- lambda { @securable.mode(07777) }.should_not raise_error
-
- lambda { @securable.mode(292) }.should_not raise_error
- lambda { @securable.mode(4095) }.should_not raise_error
-
- lambda { @securable.mode(0111) }.should_not raise_error
- lambda { @securable.mode(73) }.should_not raise_error
-
- lambda { @securable.mode(-01) }.should raise_error(ArgumentError)
- lambda { @securable.mode(010000) }.should raise_error(ArgumentError)
- lambda { @securable.mode(-1) }.should raise_error(ArgumentError)
- lambda { @securable.mode(4096) }.should raise_error(ArgumentError)
+ expect { @securable.mode(0) }.not_to raise_error
+ expect { @securable.mode(0000) }.not_to raise_error
+ expect { @securable.mode(444) }.not_to raise_error
+ expect { @securable.mode(0444) }.not_to raise_error
+ expect { @securable.mode(07777) }.not_to raise_error
+
+ expect { @securable.mode(292) }.not_to raise_error
+ expect { @securable.mode(4095) }.not_to raise_error
+
+ expect { @securable.mode(0111) }.not_to raise_error
+ expect { @securable.mode(73) }.not_to raise_error
+
+ expect { @securable.mode(-01) }.to raise_error(ArgumentError)
+ expect { @securable.mode(010000) }.to raise_error(ArgumentError)
+ expect { @securable.mode(-1) }.to raise_error(ArgumentError)
+ expect { @securable.mode(4096) }.to raise_error(ArgumentError)
end
end
@@ -187,94 +187,94 @@ describe Chef::Mixin::Securable do
end
it "should not accept a group name or id for group with spaces and multiple backslashes" do
- lambda { @securable.group 'test\ \group' }.should raise_error(ArgumentError)
+ expect { @securable.group 'test\ \group' }.to raise_error(ArgumentError)
end
it "should accept a unix file mode in string form as an octal number" do
- lambda { @securable.mode "0" }.should_not raise_error
- lambda { @securable.mode "0000" }.should_not raise_error
- lambda { @securable.mode "0111" }.should_not raise_error
- lambda { @securable.mode "0444" }.should_not raise_error
-
- lambda { @securable.mode "111" }.should_not raise_error
- lambda { @securable.mode "444" }.should_not raise_error
- lambda { @securable.mode "7777" }.should raise_error(ArgumentError)
- lambda { @securable.mode "07777" }.should raise_error(ArgumentError)
-
- lambda { @securable.mode "-01" }.should raise_error(ArgumentError)
- lambda { @securable.mode "010000" }.should raise_error(ArgumentError)
- lambda { @securable.mode "-1" }.should raise_error(ArgumentError)
- lambda { @securable.mode "10000" }.should raise_error(ArgumentError)
-
- lambda { @securable.mode "07778" }.should raise_error(ArgumentError)
- lambda { @securable.mode "7778" }.should raise_error(ArgumentError)
- lambda { @securable.mode "4095" }.should raise_error(ArgumentError)
-
- lambda { @securable.mode "0foo1234" }.should raise_error(ArgumentError)
- lambda { @securable.mode "foo1234" }.should raise_error(ArgumentError)
+ expect { @securable.mode "0" }.not_to raise_error
+ expect { @securable.mode "0000" }.not_to raise_error
+ expect { @securable.mode "0111" }.not_to raise_error
+ expect { @securable.mode "0444" }.not_to raise_error
+
+ expect { @securable.mode "111" }.not_to raise_error
+ expect { @securable.mode "444" }.not_to raise_error
+ expect { @securable.mode "7777" }.to raise_error(ArgumentError)
+ expect { @securable.mode "07777" }.to raise_error(ArgumentError)
+
+ expect { @securable.mode "-01" }.to raise_error(ArgumentError)
+ expect { @securable.mode "010000" }.to raise_error(ArgumentError)
+ expect { @securable.mode "-1" }.to raise_error(ArgumentError)
+ expect { @securable.mode "10000" }.to raise_error(ArgumentError)
+
+ expect { @securable.mode "07778" }.to raise_error(ArgumentError)
+ expect { @securable.mode "7778" }.to raise_error(ArgumentError)
+ expect { @securable.mode "4095" }.to raise_error(ArgumentError)
+
+ expect { @securable.mode "0foo1234" }.to raise_error(ArgumentError)
+ expect { @securable.mode "foo1234" }.to raise_error(ArgumentError)
end
it "should accept a unix file mode in numeric form as a ruby-interpreted integer" do
- lambda { @securable.mode 0 }.should_not raise_error
- lambda { @securable.mode 0000 }.should_not raise_error
- lambda { @securable.mode 444 }.should_not raise_error
- lambda { @securable.mode 0444 }.should_not raise_error
- lambda { @securable.mode 07777 }.should raise_error(ArgumentError)
-
- lambda { @securable.mode 292 }.should_not raise_error
- lambda { @securable.mode 4095 }.should raise_error(ArgumentError)
-
- lambda { @securable.mode 0111 }.should_not raise_error
- lambda { @securable.mode 73 }.should_not raise_error
-
- lambda { @securable.mode -01 }.should raise_error(ArgumentError)
- lambda { @securable.mode 010000 }.should raise_error(ArgumentError)
- lambda { @securable.mode -1 }.should raise_error(ArgumentError)
- lambda { @securable.mode 4096 }.should raise_error(ArgumentError)
+ expect { @securable.mode 0 }.not_to raise_error
+ expect { @securable.mode 0000 }.not_to raise_error
+ expect { @securable.mode 444 }.not_to raise_error
+ expect { @securable.mode 0444 }.not_to raise_error
+ expect { @securable.mode 07777 }.to raise_error(ArgumentError)
+
+ expect { @securable.mode 292 }.not_to raise_error
+ expect { @securable.mode 4095 }.to raise_error(ArgumentError)
+
+ expect { @securable.mode 0111 }.not_to raise_error
+ expect { @securable.mode 73 }.not_to raise_error
+
+ expect { @securable.mode -01 }.to raise_error(ArgumentError)
+ expect { @securable.mode 010000 }.to raise_error(ArgumentError)
+ expect { @securable.mode -1 }.to raise_error(ArgumentError)
+ expect { @securable.mode 4096 }.to raise_error(ArgumentError)
end
it "should allow you to specify :full_control, :modify, :read_execute, :read, and :write rights" do
- lambda { @securable.rights :full_control, "The Dude" }.should_not raise_error
- lambda { @securable.rights :modify, "The Dude" }.should_not raise_error
- lambda { @securable.rights :read_execute, "The Dude" }.should_not raise_error
- lambda { @securable.rights :read, "The Dude" }.should_not raise_error
- lambda { @securable.rights :write, "The Dude" }.should_not raise_error
- lambda { @securable.rights :to_party, "The Dude" }.should raise_error(ArgumentError)
+ expect { @securable.rights :full_control, "The Dude" }.not_to raise_error
+ expect { @securable.rights :modify, "The Dude" }.not_to raise_error
+ expect { @securable.rights :read_execute, "The Dude" }.not_to raise_error
+ expect { @securable.rights :read, "The Dude" }.not_to raise_error
+ expect { @securable.rights :write, "The Dude" }.not_to raise_error
+ expect { @securable.rights :to_party, "The Dude" }.to raise_error(ArgumentError)
end
it "should allow you to specify :full_control, :modify, :read_execute, :read, and :write deny_rights" do
- lambda { @securable.deny_rights :full_control, "The Dude" }.should_not raise_error
- lambda { @securable.deny_rights :modify, "The Dude" }.should_not raise_error
- lambda { @securable.deny_rights :read_execute, "The Dude" }.should_not raise_error
- lambda { @securable.deny_rights :read, "The Dude" }.should_not raise_error
- lambda { @securable.deny_rights :write, "The Dude" }.should_not raise_error
- lambda { @securable.deny_rights :to_party, "The Dude" }.should raise_error(ArgumentError)
+ expect { @securable.deny_rights :full_control, "The Dude" }.not_to raise_error
+ expect { @securable.deny_rights :modify, "The Dude" }.not_to raise_error
+ expect { @securable.deny_rights :read_execute, "The Dude" }.not_to raise_error
+ expect { @securable.deny_rights :read, "The Dude" }.not_to raise_error
+ expect { @securable.deny_rights :write, "The Dude" }.not_to raise_error
+ expect { @securable.deny_rights :to_party, "The Dude" }.to raise_error(ArgumentError)
end
it "should accept a principal as a string or an array" do
- lambda { @securable.rights :read, "The Dude" }.should_not raise_error
- lambda { @securable.rights :read, ["The Dude","Donny"] }.should_not raise_error
- lambda { @securable.rights :read, 3 }.should raise_error(ArgumentError)
+ expect { @securable.rights :read, "The Dude" }.not_to raise_error
+ expect { @securable.rights :read, ["The Dude","Donny"] }.not_to raise_error
+ expect { @securable.rights :read, 3 }.to raise_error(ArgumentError)
end
it "should allow you to specify whether the permissions applies_to_children with true/false/:containers_only/:objects_only" do
- lambda { @securable.rights :read, "The Dude", :applies_to_children => false }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_children => :containers_only }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_children => :objects_only }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_children => 'poop' }.should raise_error(ArgumentError)
+ expect { @securable.rights :read, "The Dude", :applies_to_children => false }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => true }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => :containers_only }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => :objects_only }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => 'poop' }.to raise_error(ArgumentError)
end
it "should allow you to specify whether the permissions applies_to_self with true/false" do
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :applies_to_self => false }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_self => true }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_self => 'poop' }.should raise_error(ArgumentError)
+ expect { @securable.rights :read, "The Dude", :applies_to_children => true, :applies_to_self => false }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_self => true }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_self => 'poop' }.to raise_error(ArgumentError)
end
it "should allow you to specify whether the permissions applies one_level_deep with true/false" do
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => false }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => true }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => 'poop' }.should raise_error(ArgumentError)
+ expect { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => false }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => true }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => 'poop' }.to raise_error(ArgumentError)
end
it "should allow multiple rights and deny_rights declarations" do
@@ -283,32 +283,32 @@ describe Chef::Mixin::Securable do
@securable.rights :full_control, "The Dude"
@securable.rights :write, "The Dude"
@securable.deny_rights :read, "The Dude"
- @securable.rights.size.should == 3
- @securable.deny_rights.size.should == 2
+ expect(@securable.rights.size).to eq(3)
+ expect(@securable.deny_rights.size).to eq(2)
end
it "should allow you to specify whether the permission applies_to_self only if you specified applies_to_children" do
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :applies_to_self => true }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :applies_to_self => false }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_children => false, :applies_to_self => true }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_children => false, :applies_to_self => false }.should raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_self => true }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_self => false }.should_not raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => true, :applies_to_self => true }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => true, :applies_to_self => false }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => false, :applies_to_self => true }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => false, :applies_to_self => false }.to raise_error(ArgumentError)
+ expect { @securable.rights :read, "The Dude", :applies_to_self => true }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_self => false }.not_to raise_error
end
it "should allow you to specify whether the permission applies one_level_deep only if you specified applies_to_children" do
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => true }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => false }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :applies_to_children => false, :one_level_deep => true }.should raise_error(ArgumentError)
- lambda { @securable.rights :read, "The Dude", :applies_to_children => false, :one_level_deep => false }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :one_level_deep => true }.should_not raise_error
- lambda { @securable.rights :read, "The Dude", :one_level_deep => false }.should_not raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => true }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => true, :one_level_deep => false }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :applies_to_children => false, :one_level_deep => true }.to raise_error(ArgumentError)
+ expect { @securable.rights :read, "The Dude", :applies_to_children => false, :one_level_deep => false }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :one_level_deep => true }.not_to raise_error
+ expect { @securable.rights :read, "The Dude", :one_level_deep => false }.not_to raise_error
end
it "should allow you to specify whether the permissions inherit with true/false" do
- lambda { @securable.inherits true }.should_not raise_error
- lambda { @securable.inherits false }.should_not raise_error
- lambda { @securable.inherits "monkey" }.should raise_error(ArgumentError)
+ expect { @securable.inherits true }.not_to raise_error
+ expect { @securable.inherits false }.not_to raise_error
+ expect { @securable.inherits "monkey" }.to raise_error(ArgumentError)
end
end
end
diff --git a/spec/unit/mixin/shell_out_spec.rb b/spec/unit/mixin/shell_out_spec.rb
index 09ab6e8a7f..beaf624ddb 100644
--- a/spec/unit/mixin/shell_out_spec.rb
+++ b/spec/unit/mixin/shell_out_spec.rb
@@ -38,16 +38,16 @@ describe Chef::Mixin::ShellOut do
let(:command_args) { [ cmd ] }
it 'should not edit command args' do
- should eql(command_args)
+ is_expected.to eql(command_args)
end
end
context 'without deprecated options' do
let(:options) { { :environment => environment } }
- let(:environment) { { 'LC_ALL' => 'C' } }
+ let(:environment) { { 'LC_ALL' => 'C', 'LANG' => 'C', 'LANGUAGE' => 'C' } }
it 'should not edit command args' do
- should eql(command_args)
+ is_expected.to eql(command_args)
end
end
@@ -66,7 +66,7 @@ describe Chef::Mixin::ShellOut do
let(:command_log_level) { :warn }
it 'should convert :command_log_level to :log_level' do
- should eql [ cmd, { :log_level => command_log_level } ]
+ is_expected.to eql [ cmd, { :log_level => command_log_level } ]
end
should_emit_deprecation_warning_about :command_log_level, :log_level
@@ -77,7 +77,7 @@ describe Chef::Mixin::ShellOut do
let(:command_log_prepend) { 'PROVIDER:' }
it 'should convert :command_log_prepend to :log_tag' do
- should eql [ cmd, { :log_tag => command_log_prepend } ]
+ is_expected.to eql [ cmd, { :log_tag => command_log_prepend } ]
end
should_emit_deprecation_warning_about :command_log_prepend, :log_tag
@@ -88,7 +88,7 @@ describe Chef::Mixin::ShellOut do
let(:command_log_level) { :warn }
it "should convert 'command_log_level' to :log_level" do
- should eql [ cmd, { :log_level => command_log_level } ]
+ is_expected.to eql [ cmd, { :log_level => command_log_level } ]
end
should_emit_deprecation_warning_about :command_log_level, :log_level
@@ -99,7 +99,7 @@ describe Chef::Mixin::ShellOut do
let(:command_log_prepend) { 'PROVIDER:' }
it "should convert 'command_log_prepend' to :log_tag" do
- should eql [ cmd, { :log_tag => command_log_prepend } ]
+ is_expected.to eql [ cmd, { :log_tag => command_log_prepend } ]
end
should_emit_deprecation_warning_about :command_log_prepend, :log_tag
@@ -123,30 +123,40 @@ describe Chef::Mixin::ShellOut do
describe "when the last argument is a Hash" do
describe "and environment is an option" do
- it "should not change environment['LC_ALL'] when set to nil" do
- options = { :environment => { 'LC_ALL' => nil } }
+ it "should not change environment language settings when they are set to nil" do
+ options = { :environment => { 'LC_ALL' => nil, 'LANGUAGE' => nil, 'LANG' => nil } }
expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true)
shell_out_obj.shell_out(cmd, options)
end
- it "should not change environment['LC_ALL'] when set to non-nil" do
- options = { :environment => { 'LC_ALL' => 'en_US.UTF-8' } }
+ it "should not change environment language settings when they are set to non-nil" do
+ options = { :environment => { 'LC_ALL' => 'en_US.UTF-8', 'LANGUAGE' => 'en_US.UTF-8', 'LANG' => 'en_US.UTF-8' } }
expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true)
shell_out_obj.shell_out(cmd, options)
end
- it "should set environment['LC_ALL'] to 'en_US.UTF-8' when 'LC_ALL' not present" do
+ it "should set environment language settings to the configured internal locale when they are not present" do
options = { :environment => { 'HOME' => '/Users/morty' } }
expect(shell_out_obj).to receive(:shell_out_command).with(cmd, {
- :environment => { 'HOME' => '/Users/morty', 'LC_ALL' => Chef::Config[:internal_locale] },
+ :environment => {
+ 'HOME' => '/Users/morty',
+ 'LC_ALL' => Chef::Config[:internal_locale],
+ 'LANG' => Chef::Config[:internal_locale],
+ 'LANGUAGE' => Chef::Config[:internal_locale],
+ },
}).and_return(true)
shell_out_obj.shell_out(cmd, options)
end
- it "should not mutate the options hash when it adds LC_ALL" do
+ it "should not mutate the options hash when it adds language settings" do
options = { :environment => { 'HOME' => '/Users/morty' } }
expect(shell_out_obj).to receive(:shell_out_command).with(cmd, {
- :environment => { 'HOME' => '/Users/morty', 'LC_ALL' => Chef::Config[:internal_locale] },
+ :environment => {
+ 'HOME' => '/Users/morty',
+ 'LC_ALL' => Chef::Config[:internal_locale],
+ 'LANG' => Chef::Config[:internal_locale],
+ 'LANGUAGE' => Chef::Config[:internal_locale],
+ },
}).and_return(true)
shell_out_obj.shell_out(cmd, options)
expect(options[:environment].has_key?('LC_ALL')).to be false
@@ -154,30 +164,40 @@ describe Chef::Mixin::ShellOut do
end
describe "and env is an option" do
- it "should not change env when set to nil" do
- options = { :env => { 'LC_ALL' => nil } }
+ it "should not change env when langauge options are set to nil" do
+ options = { :env => { 'LC_ALL' => nil, 'LANG' => nil, 'LANGUAGE' => nil } }
expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true)
shell_out_obj.shell_out(cmd, options)
end
- it "should not change env when set to non-nil" do
- options = { :env => { 'LC_ALL' => 'de_DE.UTF-8'}}
+ it "should not change env when language options are set to non-nil" do
+ options = { :env => { 'LC_ALL' => 'de_DE.UTF-8', 'LANG' => 'de_DE.UTF-8', 'LANGUAGE' => 'de_DE.UTF-8' }}
expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true)
shell_out_obj.shell_out(cmd, options)
end
- it "should set env['LC_ALL'] to 'en_US.UTF-8' when 'LC_ALL' not present" do
+ it "should set environment language settings to the configured internal locale when they are not present" do
options = { :env => { 'HOME' => '/Users/morty' } }
expect(shell_out_obj).to receive(:shell_out_command).with(cmd, {
- :env => { 'HOME' => '/Users/morty', 'LC_ALL' => Chef::Config[:internal_locale] },
+ :env => {
+ 'HOME' => '/Users/morty',
+ 'LC_ALL' => Chef::Config[:internal_locale],
+ 'LANG' => Chef::Config[:internal_locale],
+ 'LANGUAGE' => Chef::Config[:internal_locale],
+ }
}).and_return(true)
shell_out_obj.shell_out(cmd, options)
end
- it "should not mutate the options hash when it adds LC_ALL" do
+ it "should not mutate the options hash when it adds language settings" do
options = { :env => { 'HOME' => '/Users/morty' } }
expect(shell_out_obj).to receive(:shell_out_command).with(cmd, {
- :env => { 'HOME' => '/Users/morty', 'LC_ALL' => Chef::Config[:internal_locale] },
+ :env => {
+ 'HOME' => '/Users/morty',
+ 'LC_ALL' => Chef::Config[:internal_locale],
+ 'LANG' => Chef::Config[:internal_locale],
+ 'LANGUAGE' => Chef::Config[:internal_locale],
+ }
}).and_return(true)
shell_out_obj.shell_out(cmd, options)
expect(options[:env].has_key?('LC_ALL')).to be false
@@ -185,10 +205,15 @@ describe Chef::Mixin::ShellOut do
end
describe "and no env/environment option is present" do
- it "should add environment option and set environment['LC_ALL'] to 'en_US.UTF_8'" do
+ it "should set environment language settings to the configured internal locale" do
options = { :user => 'morty' }
expect(shell_out_obj).to receive(:shell_out_command).with(cmd, {
- :user => 'morty', :environment => { 'LC_ALL' => Chef::Config[:internal_locale] },
+ :user => 'morty',
+ :environment => {
+ 'LC_ALL' => Chef::Config[:internal_locale],
+ 'LANG' => Chef::Config[:internal_locale],
+ 'LANGUAGE' => Chef::Config[:internal_locale],
+ },
}).and_return(true)
shell_out_obj.shell_out(cmd, options)
end
@@ -196,9 +221,13 @@ describe Chef::Mixin::ShellOut do
end
describe "when the last argument is not a Hash" do
- it "should add environment options and set environment['LC_ALL'] to 'en_US.UTF-8'" do
+ it "should set environment language settings to the configured internal locale" do
expect(shell_out_obj).to receive(:shell_out_command).with(cmd, {
- :environment => { 'LC_ALL' => Chef::Config[:internal_locale] },
+ :environment => {
+ 'LC_ALL' => Chef::Config[:internal_locale],
+ 'LANG' => Chef::Config[:internal_locale],
+ 'LANGUAGE' => Chef::Config[:internal_locale],
+ },
}).and_return(true)
shell_out_obj.shell_out(cmd)
end
diff --git a/spec/unit/mixin/template_spec.rb b/spec/unit/mixin/template_spec.rb
index 63fa81782e..f02bd34b8f 100644
--- a/spec/unit/mixin/template_spec.rb
+++ b/spec/unit/mixin/template_spec.rb
@@ -30,7 +30,7 @@ describe Chef::Mixin::Template, "render_template" do
it "should render the template evaluated in the given context" do
@context[:foo] = "bar"
output = @context.render_template_from_string("<%= @foo %>")
- output.should == "bar"
+ expect(output).to eq("bar")
end
template_contents = [ "Fancy\r\nTemplate\r\n\r\n",
@@ -39,14 +39,14 @@ describe Chef::Mixin::Template, "render_template" do
describe "when running on windows" do
before do
- Chef::Platform.stub(:windows?).and_return(true)
+ allow(Chef::Platform).to receive(:windows?).and_return(true)
end
it "should render the templates with windows line endings" do
template_contents.each do |template_content|
output = @context.render_template_from_string(template_content)
output.each_line do |line|
- line.should end_with("\r\n")
+ expect(line).to end_with("\r\n")
end
end
end
@@ -54,14 +54,14 @@ describe Chef::Mixin::Template, "render_template" do
describe "when running on unix" do
before do
- Chef::Platform.stub(:windows?).and_return(false)
+ allow(Chef::Platform).to receive(:windows?).and_return(false)
end
it "should render the templates with unix line endings" do
template_contents.each do |template_content|
output = @context.render_template_from_string(template_content)
output.each_line do |line|
- line.should end_with("\n")
+ expect(line).to end_with("\n")
end
end
end
@@ -70,7 +70,7 @@ describe Chef::Mixin::Template, "render_template" do
it "should provide a node method to access @node" do
@context[:node] = "tehShizzle"
output = @context.render_template_from_string("<%= @node %>")
- output.should == "tehShizzle"
+ expect(output).to eq("tehShizzle")
end
describe "with a template resource" do
@@ -100,7 +100,7 @@ describe Chef::Mixin::Template, "render_template" do
it "should provide a render method" do
output = @template_context.render_template_from_string("before {<%= render('test.erb').strip -%>} after")
- output.should == "before {We could be diving for pearls!} after"
+ expect(output).to eq("before {We could be diving for pearls!} after")
end
it "should render local files" do
@@ -110,7 +110,7 @@ describe Chef::Mixin::Template, "render_template" do
tf.rewind
output = @template_context.render_template_from_string("before {<%= render '#{tf.path}', :local => true %>} after")
- output.should == "before {test} after"
+ expect(output).to eq("before {test} after")
ensure
tf.close
end
@@ -120,7 +120,7 @@ describe Chef::Mixin::Template, "render_template" do
@template_context[:template_finder] = Chef::Provider::TemplateFinder.new(@run_context, 'apache2', @node)
output = @template_context.render_template_from_string("before {<%= render('test.erb', :cookbook => 'openldap').strip %>} after")
- output.should == "before {We could be diving for pearls!} after"
+ expect(output).to eq("before {We could be diving for pearls!} after")
end
it "should render using the source argument if provided" do
@@ -130,7 +130,7 @@ describe Chef::Mixin::Template, "render_template" do
tf.rewind
output = @template_context.render_template_from_string("before {<%= render 'something', :local => true, :source => '#{tf.path}' %>} after")
- output.should == "before {test} after"
+ expect(output).to eq("before {test} after")
ensure
tf.close
end
@@ -140,7 +140,7 @@ describe Chef::Mixin::Template, "render_template" do
@node.normal[:slappiness] = "happiness"
output = @template_context.render_template_from_string("before {<%= render 'openldap_stuff.conf.erb' %>} after")
- output.should == "before {slappiness is happiness} after"
+ expect(output).to eq("before {slappiness is happiness} after")
end
it "should pass the original variables to partials" do
@@ -152,29 +152,29 @@ describe Chef::Mixin::Template, "render_template" do
it "should pass variables to partials" do
output = @template_context.render_template_from_string("before {<%= render 'openldap_variable_stuff.conf.erb', :variables => {:secret => 'whatever' } %>} after")
- output.should == "before {super secret is whatever} after"
+ expect(output).to eq("before {super secret is whatever} after")
end
it "should pass variables to partials even if they are named the same" do
@template_context[:secret] = 'one'
output = @template_context.render_template_from_string("before {<%= render 'openldap_variable_stuff.conf.erb', :variables => {:secret => 'two' } %>} after <%= @secret %>")
- output.should == "before {super secret is two} after one"
+ expect(output).to eq("before {super secret is two} after one")
end
it "should pass nil for missing variables in partials" do
output = @template_context.render_template_from_string("before {<%= render 'openldap_variable_stuff.conf.erb', :variables => {} %>} after")
- output.should == "before {super secret is } after"
+ expect(output).to eq("before {super secret is } after")
output = @template_context.render_template_from_string("before {<%= render 'openldap_variable_stuff.conf.erb' %>} after")
- output.should == "before {super secret is } after"
+ expect(output).to eq("before {super secret is } after")
end
it "should render nested partials" do
path = File.expand_path(File.join(CHEF_SPEC_DATA, "partial_one.erb"))
output = @template_context.render_template_from_string("before {<%= render('#{path}', :local => true).strip %>} after")
- output.should == "before {partial one We could be diving for pearls! calling home} after"
+ expect(output).to eq("before {partial one We could be diving for pearls! calling home} after")
end
describe "when customizing the template context" do
@@ -187,7 +187,7 @@ describe Chef::Mixin::Template, "render_template" do
end
@template_context._extend_modules([mod])
output = @template_context.render_template_from_string("<%=hello%>")
- output.should == "ohai"
+ expect(output).to eq("ohai")
end
it "emits a warning when overriding 'core' methods" do
@@ -202,7 +202,7 @@ describe Chef::Mixin::Template, "render_template" do
end
end
['node', 'render', 'render_template', 'render_template_from_string'].each do |method_name|
- Chef::Log.should_receive(:warn).with(/^Core template method `#{method_name}' overridden by extension module/)
+ expect(Chef::Log).to receive(:warn).with(/^Core template method `#{method_name}' overridden by extension module/)
end
@template_context._extend_modules([mod])
end
@@ -216,11 +216,11 @@ describe Chef::Mixin::Template, "render_template" do
end
it "should catch and re-raise the exception as a TemplateError" do
- lambda { do_raise }.should raise_error(Chef::Mixin::Template::TemplateError)
+ expect { do_raise }.to raise_error(Chef::Mixin::Template::TemplateError)
end
it "should raise an error if an attempt is made to access node but it is nil" do
- lambda {@context.render_template_from_string("<%= node %>") {|r| r}}.should raise_error(Chef::Mixin::Template::TemplateError)
+ expect {@context.render_template_from_string("<%= node %>") {|r| r}}.to raise_error(Chef::Mixin::Template::TemplateError)
end
describe "the raised TemplateError" do
@@ -233,35 +233,35 @@ describe Chef::Mixin::Template, "render_template" do
end
it "should have the original exception" do
- @exception.original_exception.should be
- @exception.original_exception.message.should =~ /undefined local variable or method `this_is_not_defined'/
+ expect(@exception.original_exception).to be
+ expect(@exception.original_exception.message).to match(/undefined local variable or method `this_is_not_defined'/)
end
it "should determine the line number of the exception" do
- @exception.line_number.should == 4
+ expect(@exception.line_number).to eq(4)
end
it "should provide a source listing of the template around the exception" do
- @exception.source_listing.should == " 2: bar\n 3: baz\n 4: <%= this_is_not_defined %>\n 5: quin\n 6: qunx"
+ expect(@exception.source_listing).to eq(" 2: bar\n 3: baz\n 4: <%= this_is_not_defined %>\n 5: quin\n 6: qunx")
end
it "should provide the evaluation context of the template" do
- @exception.context.should == @context
+ expect(@exception.context).to eq(@context)
end
it "should defer the message to the original exception" do
- @exception.message.should =~ /undefined local variable or method `this_is_not_defined'/
+ expect(@exception.message).to match(/undefined local variable or method `this_is_not_defined'/)
end
it "should provide a nice source location" do
- @exception.source_location.should == "on line #4"
+ expect(@exception.source_location).to eq("on line #4")
end
it "should create a pretty output for the terminal" do
- @exception.to_s.should =~ /Chef::Mixin::Template::TemplateError/
- @exception.to_s.should =~ /undefined local variable or method `this_is_not_defined'/
- @exception.to_s.should include(" 2: bar\n 3: baz\n 4: <%= this_is_not_defined %>\n 5: quin\n 6: qunx")
- @exception.to_s.should include(@exception.original_exception.backtrace.first)
+ expect(@exception.to_s).to match(/Chef::Mixin::Template::TemplateError/)
+ expect(@exception.to_s).to match(/undefined local variable or method `this_is_not_defined'/)
+ expect(@exception.to_s).to include(" 2: bar\n 3: baz\n 4: <%= this_is_not_defined %>\n 5: quin\n 6: qunx")
+ expect(@exception.to_s).to include(@exception.original_exception.backtrace.first)
end
end
end
diff --git a/spec/unit/mixin/windows_architecture_helper_spec.rb b/spec/unit/mixin/windows_architecture_helper_spec.rb
index f59602d716..3803d69371 100644
--- a/spec/unit/mixin/windows_architecture_helper_spec.rb
+++ b/spec/unit/mixin/windows_architecture_helper_spec.rb
@@ -35,13 +35,13 @@ describe Chef::Mixin::WindowsArchitectureHelper do
it "returns true when valid architectures are passed to valid_windows_architecture?" do
@valid_architectures.each do | architecture |
- valid_windows_architecture?(architecture).should == true
+ expect(valid_windows_architecture?(architecture)).to eq(true)
end
end
it "returns false when invalid architectures are passed to valid_windows_architecture?" do
@invalid_architectures.each do | architecture |
- valid_windows_architecture?(architecture).should == false
+ expect(valid_windows_architecture?(architecture)).to eq(false)
end
end
@@ -54,7 +54,7 @@ describe Chef::Mixin::WindowsArchitectureHelper do
it "raises an error if an invalid architecture is passed to assert_valid_windows_architecture!" do
@invalid_architectures.each do | architecture |
begin
- assert_valid_windows_architecture!(architecture).should raise_error Chef::Exceptions::Win32ArchitectureIncorrect
+ expect(assert_valid_windows_architecture!(architecture)).to raise_error Chef::Exceptions::Win32ArchitectureIncorrect
rescue Chef::Exceptions::Win32ArchitectureIncorrect
end
end
@@ -75,8 +75,8 @@ describe Chef::Mixin::WindowsArchitectureHelper do
new_node.default["kernel"][:machine] = node_architecture.to_s
@valid_architectures.each do | supported_architecture |
- node_supports_windows_architecture?(new_node, supported_architecture).should == true if only_valid_combinations && (supported_architecture != :x86_64 && node_architecture != :i386 )
- node_supports_windows_architecture?(new_node, supported_architecture).should == false if ! only_valid_combinations && (supported_architecture == :x86_64 && node_architecture == :i386 )
+ expect(node_supports_windows_architecture?(new_node, supported_architecture)).to eq(true) if only_valid_combinations && (supported_architecture != :x86_64 && node_architecture != :i386 )
+ expect(node_supports_windows_architecture?(new_node, supported_architecture)).to eq(false) if ! only_valid_combinations && (supported_architecture == :x86_64 && node_architecture == :i386 )
end
end
end
diff --git a/spec/unit/mixin/xml_escape_spec.rb b/spec/unit/mixin/xml_escape_spec.rb
index 83debb5907..c5156cfb7b 100644
--- a/spec/unit/mixin/xml_escape_spec.rb
+++ b/spec/unit/mixin/xml_escape_spec.rb
@@ -28,27 +28,27 @@ describe Chef::Mixin::XMLEscape do
end
it "escapes ampersands to '&amp;'" do
- @escaper.xml_escape("&").should == "&amp;"
+ expect(@escaper.xml_escape("&")).to eq("&amp;")
end
it "escapes angle brackets to &lt; or &gt;" do
- @escaper.xml_escape("<").should == "&lt;"
- @escaper.xml_escape(">").should == "&gt;"
+ expect(@escaper.xml_escape("<")).to eq("&lt;")
+ expect(@escaper.xml_escape(">")).to eq("&gt;")
end
it "does not modify ASCII strings" do
- @escaper.xml_escape('foobarbaz!@#$%^*()').should == 'foobarbaz!@#$%^*()'
+ expect(@escaper.xml_escape('foobarbaz!@#$%^*()')).to eq('foobarbaz!@#$%^*()')
end
it "converts invalid bytes to asterisks" do
- @escaper.xml_escape("\x00").should == "*"
+ expect(@escaper.xml_escape("\x00")).to eq("*")
end
it "converts UTF-8 correctly" do
- @escaper.xml_escape("\xC2\xA9").should == '&#169;'
+ expect(@escaper.xml_escape("\xC2\xA9")).to eq('&#169;')
end
it "converts win 1252 characters correctly" do
- @escaper.xml_escape("\x80").should == '&#8364;'
+ expect(@escaper.xml_escape("\x80")).to eq('&#8364;')
end
end
diff --git a/spec/unit/monkey_patches/uri_spec.rb b/spec/unit/monkey_patches/uri_spec.rb
index cff252ac3b..9aca1fc9f1 100644
--- a/spec/unit/monkey_patches/uri_spec.rb
+++ b/spec/unit/monkey_patches/uri_spec.rb
@@ -26,7 +26,7 @@ describe URI do
end
it "returns the hostname without brackets" do
- ipv6_uri.hostname.should == "2a00:1450:4009:809::1008"
+ expect(ipv6_uri.hostname).to eq("2a00:1450:4009:809::1008")
end
end
diff --git a/spec/unit/monologger_spec.rb b/spec/unit/monologger_spec.rb
index 3babc29218..8689ea0aaa 100644
--- a/spec/unit/monologger_spec.rb
+++ b/spec/unit/monologger_spec.rb
@@ -23,14 +23,14 @@ describe MonoLogger do
it "should disable buffering when passed an IO stream" do
STDOUT.sync = false
MonoLogger.new(STDOUT)
- STDOUT.sync.should == true
+ expect(STDOUT.sync).to eq(true)
end
describe "when given an object that responds to write and close e.g. IO" do
it "should use the object directly" do
stream = StringIO.new
MonoLogger.new(stream).fatal("Houston, we've had a problem.")
- stream.string.should =~ /Houston, we've had a problem./
+ expect(stream.string).to match(/Houston, we've had a problem./)
end
end
@@ -39,7 +39,7 @@ describe MonoLogger do
temp_file = Tempfile.new("rspec-monologger-log")
temp_file.close
MonoLogger.new(temp_file.path).fatal("Do, or do not. There is no try.")
- File.read(temp_file.path).should =~ /Do, or do not. There is no try./
+ expect(File.read(temp_file.path)).to match(/Do, or do not. There is no try./)
end
end
end
diff --git a/spec/unit/node/attribute_spec.rb b/spec/unit/node/attribute_spec.rb
index 1eddab00ba..250b8c630c 100644
--- a/spec/unit/node/attribute_spec.rb
+++ b/spec/unit/node/attribute_spec.rb
@@ -215,22 +215,22 @@ describe Chef::Node::Attribute do
describe "initialize" do
it "should return a Chef::Node::Attribute" do
- @attributes.should be_a_kind_of(Chef::Node::Attribute)
+ expect(@attributes).to be_a_kind_of(Chef::Node::Attribute)
end
it "should take an Automatioc, Normal, Default and Override hash" do
- lambda { Chef::Node::Attribute.new({}, {}, {}, {}) }.should_not raise_error
+ expect { Chef::Node::Attribute.new({}, {}, {}, {}) }.not_to raise_error
end
[ :normal, :default, :override, :automatic ].each do |accessor|
it "should set #{accessor}" do
na = Chef::Node::Attribute.new({ :normal => true }, { :default => true }, { :override => true }, { :automatic => true })
- na.send(accessor).should == { accessor.to_s => true }
+ expect(na.send(accessor)).to eq({ accessor.to_s => true })
end
end
it "should be enumerable" do
- @attributes.should be_is_a(Enumerable)
+ expect(@attributes).to be_is_a(Enumerable)
end
end
@@ -242,7 +242,7 @@ describe Chef::Node::Attribute do
# the "strict" conversion method that should only be implemented by
# things that are truly Array-like, so NoMethodError is the right choice.
# (cf. there is no Hash#to_ary).
- lambda { @attributes.default.to_ary }.should raise_error(NoMethodError)
+ expect { @attributes.default.to_ary }.to raise_error(NoMethodError)
end
end
@@ -274,7 +274,7 @@ describe Chef::Node::Attribute do
["force_override", "force_override"],
["automatic", "automatic"]
]
- @attributes.debug_value(:foo, :bar).should == expected
+ expect(@attributes.debug_value(:foo, :bar)).to eq(expected)
end
end
@@ -288,68 +288,68 @@ describe Chef::Node::Attribute do
@attributes.force_default["default"] = "force default"
@attributes.role_default["default"] = "role default"
@attributes.env_default["default"] = "environment default"
- @attributes["default"].should == "force default"
+ expect(@attributes["default"]).to eq("force default")
end
it "prefers role_default over environment or cookbook default" do
@attributes.role_default["default"] = "role default"
@attributes.env_default["default"] = "environment default"
- @attributes["default"].should == "role default"
+ expect(@attributes["default"]).to eq("role default")
end
it "prefers environment default over cookbook default" do
@attributes.env_default["default"] = "environment default"
- @attributes["default"].should == "environment default"
+ expect(@attributes["default"]).to eq("environment default")
end
it "returns the cookbook default when no other default values are present" do
- @attributes["default"].should == "cookbook default"
+ expect(@attributes["default"]).to eq("cookbook default")
end
it "prefers 'forced overrides' over role or cookbook overrides" do
@attributes.force_override["override"] = "force override"
@attributes.env_override["override"] = "environment override"
@attributes.role_override["override"] = "role override"
- @attributes["override"].should == "force override"
+ expect(@attributes["override"]).to eq("force override")
end
it "prefers environment overrides over role or cookbook overrides" do
@attributes.env_override["override"] = "environment override"
@attributes.role_override["override"] = "role override"
- @attributes["override"].should == "environment override"
+ expect(@attributes["override"]).to eq("environment override")
end
it "prefers role overrides over cookbook overrides" do
@attributes.role_override["override"] = "role override"
- @attributes["override"].should == "role override"
+ expect(@attributes["override"]).to eq("role override")
end
it "returns cookbook overrides when no other overrides are present" do
- @attributes["override"].should == "cookbook override"
+ expect(@attributes["override"]).to eq("cookbook override")
end
it "merges arrays within the default precedence" do
@attributes.role_default["array"] = %w{role}
@attributes.env_default["array"] = %w{env}
- @attributes["array"].should == %w{env role}
+ expect(@attributes["array"]).to eq(%w{env role})
end
it "merges arrays within the override precedence" do
@attributes.role_override["array"] = %w{role}
@attributes.env_override["array"] = %w{env}
- @attributes["array"].should == %w{role env}
+ expect(@attributes["array"]).to eq(%w{role env})
end
it "does not merge arrays between default and normal" do
@attributes.role_default["array"] = %w{role}
@attributes.normal["array"] = %w{normal}
- @attributes["array"].should == %w{normal}
+ expect(@attributes["array"]).to eq(%w{normal})
end
it "does not merge arrays between normal and override" do
@attributes.normal["array"] = %w{normal}
@attributes.role_override["array"] = %w{role}
- @attributes["array"].should == %w{role}
+ expect(@attributes["array"]).to eq(%w{role})
end
it "merges nested hashes between precedence levels" do
@@ -358,9 +358,9 @@ describe Chef::Node::Attribute do
@attributes.normal = {"a" => {"b" => {"normal" => "normal"}}}
@attributes.override = {"a" => {"override" => "role"}}
@attributes.automatic = {"a" => {"automatic" => "auto"}}
- @attributes["a"].should == {"b"=>{"default"=>"default", "normal"=>"normal"},
+ expect(@attributes["a"]).to eq({"b"=>{"default"=>"default", "normal"=>"normal"},
"override"=>"role",
- "automatic"=>"auto"}
+ "automatic"=>"auto"})
end
end
@@ -377,94 +377,94 @@ describe Chef::Node::Attribute do
end
it "merges all types of overrides into a combined override" do
- @attributes.combined_override["co"].should == "cookbook override"
- @attributes.combined_override["ro"].should == "role override"
- @attributes.combined_override["eo"].should == "env override"
- @attributes.combined_override["fo"].should == "force override"
+ expect(@attributes.combined_override["co"]).to eq("cookbook override")
+ expect(@attributes.combined_override["ro"]).to eq("role override")
+ expect(@attributes.combined_override["eo"]).to eq("env override")
+ expect(@attributes.combined_override["fo"]).to eq("force override")
end
it "merges all types of defaults into a combined default" do
- @attributes.combined_default["cd"].should == "cookbook default"
- @attributes.combined_default["rd"].should == "role default"
- @attributes.combined_default["ed"].should == "env default"
- @attributes.combined_default["fd"].should == "force default"
+ expect(@attributes.combined_default["cd"]).to eq("cookbook default")
+ expect(@attributes.combined_default["rd"]).to eq("role default")
+ expect(@attributes.combined_default["ed"]).to eq("env default")
+ expect(@attributes.combined_default["fd"]).to eq("force default")
end
end
describe "[]" do
it "should return override data if it exists" do
- @attributes["macaddress"].should == "00:00:00:00:00:00"
+ expect(@attributes["macaddress"]).to eq("00:00:00:00:00:00")
end
it "should return attribute data if it is not overridden" do
- @attributes["platform"].should == "mac_os_x"
+ expect(@attributes["platform"]).to eq("mac_os_x")
end
it "should return data that doesn't have corresponding keys in every hash" do
- @attributes["command"]["ps"].should == "ps -ef"
+ expect(@attributes["command"]["ps"]).to eq("ps -ef")
end
it "should return default data if it is not overriden or in attribute data" do
- @attributes["music"]["mastodon"].should == "rocks"
+ expect(@attributes["music"]["mastodon"]).to eq("rocks")
end
it "should prefer the override data over an available default" do
- @attributes["music"]["mars_volta"].should == "cicatriz"
+ expect(@attributes["music"]["mars_volta"]).to eq("cicatriz")
end
it "should prefer the attribute data over an available default" do
- @attributes["music"]["jimmy_eat_world"].should == "nice"
+ expect(@attributes["music"]["jimmy_eat_world"]).to eq("nice")
end
it "should prefer override data over default data if there is no attribute data" do
- @attributes["hot"]["day"].should == "sunday"
+ expect(@attributes["hot"]["day"]).to eq("sunday")
end
it "should return the merged hash if all three have values" do
result = @attributes["music"]
- result["mars_volta"].should == "cicatriz"
- result["jimmy_eat_world"].should == "nice"
- result["mastodon"].should == "rocks"
+ expect(result["mars_volta"]).to eq("cicatriz")
+ expect(result["jimmy_eat_world"]).to eq("nice")
+ expect(result["mastodon"]).to eq("rocks")
end
end
describe "[]=" do
it "should error out when the type of attribute to set has not been specified" do
@attributes.normal["the_ghost"] = { }
- lambda { @attributes["the_ghost"]["exterminate"] = false }.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
+ expect { @attributes["the_ghost"]["exterminate"] = false }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
end
it "should let you set an attribute value when another hash has an intermediate value" do
@attributes.normal["the_ghost"] = { "exterminate" => "the future" }
- lambda { @attributes.normal["the_ghost"]["eviscerate"]["tomorrow"] = false }.should_not raise_error
+ expect { @attributes.normal["the_ghost"]["eviscerate"]["tomorrow"] = false }.not_to raise_error
end
it "should set the attribute value" do
@attributes.normal["longboard"] = "surfing"
- @attributes.normal["longboard"].should == "surfing"
- @attributes.normal["longboard"].should == "surfing"
+ expect(@attributes.normal["longboard"]).to eq("surfing")
+ expect(@attributes.normal["longboard"]).to eq("surfing")
end
it "should set deeply nested attribute values when a precedence level is specified" do
@attributes.normal["deftones"]["hunters"]["nap"] = "surfing"
- @attributes.normal["deftones"]["hunters"]["nap"].should == "surfing"
+ expect(@attributes.normal["deftones"]["hunters"]["nap"]).to eq("surfing")
end
it "should die if you try and do nested attributes that do not exist without read vivification" do
- lambda { @attributes["foo"]["bar"] = :baz }.should raise_error
+ expect { @attributes["foo"]["bar"] = :baz }.to raise_error
end
it "should let you set attributes manually without vivification" do
@attributes.normal["foo"] = Mash.new
@attributes.normal["foo"]["bar"] = :baz
- @attributes.normal["foo"]["bar"].should == :baz
+ expect(@attributes.normal["foo"]["bar"]).to eq(:baz)
end
it "should optionally skip setting the value if one already exists" do
@attributes.set_unless_value_present = true
@attributes.normal["hostname"] = "bar"
- @attributes["hostname"].should == "latte"
+ expect(@attributes["hostname"]).to eq("latte")
end
it "does not support ||= when setting" do
@@ -472,19 +472,47 @@ describe Chef::Node::Attribute do
# Users who need this behavior can use set_unless and friends
@attributes.normal["foo"] = Mash.new
@attributes.normal["foo"]["bar"] ||= "stop the world"
- @attributes.normal["foo"]["bar"].should == {}
+ expect(@attributes.normal["foo"]["bar"]).to eq({})
end
end
describe "to_hash" do
it "should convert to a hash" do
- @attributes.to_hash.class.should == Hash
+ expect(@attributes.to_hash.class).to eq(Hash)
end
it "should convert to a hash based on current state" do
hash = @attributes["hot"].to_hash
- hash.class.should == Hash
- hash["day"].should == "sunday"
+ expect(hash.class).to eq(Hash)
+ expect(hash["day"]).to eq("sunday")
+ end
+
+ it "should create a deep copy of the node attribute" do
+ @attributes.default['foo']['bar']['baz'] = 'fizz'
+ hash = @attributes['foo'].to_hash
+ expect(hash).to eql({"bar"=>{"baz"=>"fizz"}})
+ hash['bar']['baz'] = 'buzz'
+ expect(hash).to eql({"bar"=>{"baz"=>"buzz"}})
+ expect(@attributes.default['foo']).to eql({"bar"=>{"baz"=>"fizz"}})
+ end
+
+ it "should create a deep copy of arrays in the node attribute" do
+ @attributes.default['foo']['bar'] = ['fizz']
+ hash = @attributes['foo'].to_hash
+ expect(hash).to eql({"bar"=>[ 'fizz' ]})
+ hash['bar'].push('buzz')
+ expect(hash).to eql({"bar"=>[ 'fizz', 'buzz' ]})
+ expect(@attributes.default['foo']).to eql({"bar"=>[ 'fizz' ]})
+ end
+
+ it "mutating strings should not mutate the attributes" do
+ pending "this is a bug that should be fixed"
+ @attributes.default['foo']['bar']['baz'] = 'fizz'
+ hash = @attributes['foo'].to_hash
+ expect(hash).to eql({"bar"=>{"baz"=>"fizz"}})
+ hash['bar']['baz'] << 'buzz'
+ expect(hash).to eql({"bar"=>{"baz"=>"fizzbuzz"}})
+ expect(@attributes.default['foo']).to eql({"bar"=>{"baz"=>"fizz"}})
end
end
@@ -497,59 +525,59 @@ describe Chef::Node::Attribute do
describe "has_key?" do
it "should return true if an attribute exists" do
- @attributes.has_key?("music").should == true
+ expect(@attributes.has_key?("music")).to eq(true)
end
it "should return false if an attribute does not exist" do
- @attributes.has_key?("ninja").should == false
+ expect(@attributes.has_key?("ninja")).to eq(false)
end
it "should return false if an attribute does not exist using dot notation" do
- @attributes.has_key?("does_not_exist_at_all").should == false
+ expect(@attributes.has_key?("does_not_exist_at_all")).to eq(false)
end
it "should return true if an attribute exists but is set to nil using dot notation" do
- @attributes.music.deeper.has_key?("gates_of_ishtar").should == true
+ expect(@attributes.music.deeper.has_key?("gates_of_ishtar")).to eq(true)
end
it "should return true if an attribute exists but is set to false" do
@attributes.has_key?("music")
- @attributes["music"].has_key?("apophis").should == true
+ expect(@attributes["music"].has_key?("apophis")).to eq(true)
end
it "does not find keys above the current nesting level" do
- @attributes["music"]["this"]["apparatus"].should_not have_key("this")
+ expect(@attributes["music"]["this"]["apparatus"]).not_to have_key("this")
end
it "does not find keys below the current nesting level" do
- @attributes["music"]["this"].should_not have_key("must")
+ expect(@attributes["music"]["this"]).not_to have_key("must")
end
[:include?, :key?, :member?].each do |method|
it "should alias the method #{method} to itself" do
- @attributes.should respond_to(method)
+ expect(@attributes).to respond_to(method)
end
it "#{method} should behave like has_key?" do
- @attributes.send(method, "music").should == true
+ expect(@attributes.send(method, "music")).to eq(true)
end
end
end
describe "attribute?" do
it "should return true if an attribute exists" do
- @attributes.attribute?("music").should == true
+ expect(@attributes.attribute?("music")).to eq(true)
end
it "should return false if an attribute does not exist" do
- @attributes.attribute?("ninja").should == false
+ expect(@attributes.attribute?("ninja")).to eq(false)
end
end
describe "method_missing" do
it "should behave like a [] lookup" do
- @attributes.music.mastodon.should == "rocks"
+ expect(@attributes.music.mastodon).to eq("rocks")
end
it "should allow the last method to set a value if it has an = sign on the end" do
@@ -583,12 +611,12 @@ describe Chef::Node::Attribute do
@attributes.keys.each do |k|
collect << k
end
- collect.include?("one").should == true
- collect.include?("hut").should == true
- collect.include?("snakes").should == true
- collect.include?("snack").should == true
- collect.include?("place").should == true
- collect.length.should == 5
+ expect(collect.include?("one")).to eq(true)
+ expect(collect.include?("hut")).to eq(true)
+ expect(collect.include?("snakes")).to eq(true)
+ expect(collect.include?("snack")).to eq(true)
+ expect(collect.include?("place")).to eq(true)
+ expect(collect.length).to eq(5)
end
it "should yield lower if we go deeper" do
@@ -596,14 +624,14 @@ describe Chef::Node::Attribute do
@attributes.one.keys.each do |k|
collect << k
end
- collect.include?("two").should == true
- collect.include?("four").should == true
- collect.include?("six").should == true
- collect.length.should == 3
+ expect(collect.include?("two")).to eq(true)
+ expect(collect.include?("four")).to eq(true)
+ expect(collect.include?("six")).to eq(true)
+ expect(collect.length).to eq(3)
end
it "should not raise an exception if one of the hashes has a nil value on a deep lookup" do
- lambda { @attributes.place.keys { |k| } }.should_not raise_error
+ expect { @attributes.place.keys { |k| } }.not_to raise_error
end
end
@@ -632,15 +660,15 @@ describe Chef::Node::Attribute do
collect[k] = v
end
- collect["one"].should == "six"
- collect["hut"].should == "three"
- collect["snakes"].should == "on a plane"
- collect["snack"].should == "cookies"
+ expect(collect["one"]).to eq("six")
+ expect(collect["hut"]).to eq("three")
+ expect(collect["snakes"]).to eq("on a plane")
+ expect(collect["snack"]).to eq("cookies")
end
it "should yield as a two-element array" do
@attributes.each do |a|
- a.should be_an_instance_of(Array)
+ expect(a).to be_an_instance_of(Array)
end
end
end
@@ -665,7 +693,7 @@ describe Chef::Node::Attribute do
end
it "should respond to each_key" do
- @attributes.should respond_to(:each_key)
+ expect(@attributes).to respond_to(:each_key)
end
it "should yield each top level key, post merge rules" do
@@ -674,10 +702,10 @@ describe Chef::Node::Attribute do
collect << k
end
- collect.should include("one")
- collect.should include("snack")
- collect.should include("hut")
- collect.should include("snakes")
+ expect(collect).to include("one")
+ expect(collect).to include("snack")
+ expect(collect).to include("hut")
+ expect(collect).to include("snakes")
end
end
@@ -701,7 +729,7 @@ describe Chef::Node::Attribute do
end
it "should respond to each_pair" do
- @attributes.should respond_to(:each_pair)
+ expect(@attributes).to respond_to(:each_pair)
end
it "should yield each top level key and value pair, post merge rules" do
@@ -710,10 +738,10 @@ describe Chef::Node::Attribute do
collect[k] = v
end
- collect["one"].should == "six"
- collect["hut"].should == "three"
- collect["snakes"].should == "on a plane"
- collect["snack"].should == "cookies"
+ expect(collect["one"]).to eq("six")
+ expect(collect["hut"]).to eq("three")
+ expect(collect["snakes"]).to eq("on a plane")
+ expect(collect["snack"]).to eq("cookies")
end
end
@@ -737,7 +765,7 @@ describe Chef::Node::Attribute do
end
it "should respond to each_value" do
- @attributes.should respond_to(:each_value)
+ expect(@attributes).to respond_to(:each_value)
end
it "should yield each value, post merge rules" do
@@ -746,9 +774,9 @@ describe Chef::Node::Attribute do
collect << v
end
- collect.should include("cookies")
- collect.should include("three")
- collect.should include("on a plane")
+ expect(collect).to include("cookies")
+ expect(collect).to include("three")
+ expect(collect).to include("on a plane")
end
it "should yield four elements" do
@@ -757,7 +785,7 @@ describe Chef::Node::Attribute do
collect << v
end
- collect.length.should == 4
+ expect(collect.length).to eq(4)
end
end
@@ -782,15 +810,15 @@ describe Chef::Node::Attribute do
end
it "should respond to empty?" do
- @attributes.should respond_to(:empty?)
+ expect(@attributes).to respond_to(:empty?)
end
it "should return true when there are no keys" do
- @empty.empty?.should == true
+ expect(@empty.empty?).to eq(true)
end
it "should return false when there are keys" do
- @attributes.empty?.should == false
+ expect(@attributes.empty?).to eq(false)
end
end
@@ -815,7 +843,7 @@ describe Chef::Node::Attribute do
end
it "should respond to fetch" do
- @attributes.should respond_to(:fetch)
+ expect(@attributes).to respond_to(:fetch)
end
describe "when the key exists" do
@@ -826,7 +854,7 @@ describe Chef::Node::Attribute do
"snakes" => "on a plane",
"snack" => "cookies"
}.each do |k,v|
- @attributes.fetch(k).should == v
+ expect(@attributes.fetch(k)).to eq(v)
end
end
end
@@ -834,19 +862,19 @@ describe Chef::Node::Attribute do
describe "when the key does not exist" do
describe "and no args are passed" do
it "should raise an indexerror" do
- lambda { @attributes.fetch("lololol") }.should raise_error(IndexError)
+ expect { @attributes.fetch("lololol") }.to raise_error(IndexError)
end
end
describe "and a default arg is passed" do
it "should return the value of the default arg" do
- @attributes.fetch("lol", "blah").should == "blah"
+ expect(@attributes.fetch("lol", "blah")).to eq("blah")
end
end
describe "and a block is passed" do
it "should run the block and return its value" do
- @attributes.fetch("lol") { |x| "#{x}, blah" }.should == "lol, blah"
+ expect(@attributes.fetch("lol") { |x| "#{x}, blah" }).to eq("lol, blah")
end
end
end
@@ -872,19 +900,19 @@ describe Chef::Node::Attribute do
end
it "should respond to has_value?" do
- @attributes.should respond_to(:has_value?)
+ expect(@attributes).to respond_to(:has_value?)
end
it "should return true if any key has the value supplied" do
- @attributes.has_value?("cookies").should == true
+ expect(@attributes.has_value?("cookies")).to eq(true)
end
it "should return false no key has the value supplied" do
- @attributes.has_value?("lololol").should == false
+ expect(@attributes.has_value?("lololol")).to eq(false)
end
it "should alias value?" do
- @attributes.should respond_to(:value?)
+ expect(@attributes).to respond_to(:value?)
end
end
@@ -917,13 +945,13 @@ describe Chef::Node::Attribute do
end
it "should respond to index" do
- @attributes.should respond_to(:index)
+ expect(@attributes).to respond_to(:index)
end
describe "when the value is indexed" do
it "should return the index" do
silence do
- @attributes.index("six").should == "one"
+ expect(@attributes.index("six")).to eq("one")
end
end
end
@@ -931,7 +959,7 @@ describe Chef::Node::Attribute do
describe "when the value is not indexed" do
it "should return nil" do
silence do
- @attributes.index("lolol").should == nil
+ expect(@attributes.index("lolol")).to eq(nil)
end
end
end
@@ -958,18 +986,18 @@ describe Chef::Node::Attribute do
end
it "should respond to values" do
- @attributes.should respond_to(:values)
+ expect(@attributes).to respond_to(:values)
end
it "should return an array of values" do
- @attributes.values.length.should == 4
+ expect(@attributes.values.length).to eq(4)
end
it "should match the values output from each" do
- @attributes.values.should include("six")
- @attributes.values.should include("cookies")
- @attributes.values.should include("three")
- @attributes.values.should include("on a plane")
+ expect(@attributes.values).to include("six")
+ expect(@attributes.values).to include("cookies")
+ expect(@attributes.values).to include("three")
+ expect(@attributes.values).to include("on a plane")
end
end
@@ -994,26 +1022,26 @@ describe Chef::Node::Attribute do
end
it "should respond to select" do
- @attributes.should respond_to(:select)
+ expect(@attributes).to respond_to(:select)
end
if RUBY_VERSION >= "1.8.7"
it "should not raise a LocalJumpError if no block is given" do
- lambda { @attributes.select }.should_not raise_error
+ expect { @attributes.select }.not_to raise_error
end
else
it "should raise a LocalJumpError if no block is given" do
- lambda{ @attributes.select }.should raise_error(LocalJumpError)
+ expect{ @attributes.select }.to raise_error(LocalJumpError)
end
end
it "should return an empty hash/array (ruby-version-dependent) for a block containing nil" do
- @attributes.select { nil }.should == {}.select { nil }
+ expect(@attributes.select { nil }).to eq({}.select { nil })
end
# sorted for spec clarity
it "should return a new array of k,v pairs for which the block returns true" do
- @attributes.select { true }.sort.should == (
+ expect(@attributes.select { true }.sort).to eq(
[
["hut", "three"],
["one", "six"],
@@ -1046,37 +1074,57 @@ describe Chef::Node::Attribute do
end
it "should respond to size" do
- @attributes.should respond_to(:size)
+ expect(@attributes).to respond_to(:size)
end
it "should alias length to size" do
- @attributes.should respond_to(:length)
+ expect(@attributes).to respond_to(:length)
end
it "should return 0 for an empty attribute" do
- @empty.size.should == 0
+ expect(@empty.size).to eq(0)
end
it "should return the number of pairs" do
- @attributes.size.should == 4
+ expect(@attributes.size).to eq(4)
end
end
describe "kind_of?" do
it "should falsely inform you that it is a Hash" do
- @attributes.should be_a_kind_of(Hash)
+ expect(@attributes).to be_a_kind_of(Hash)
end
it "should falsely inform you that it is a Mash" do
- @attributes.should be_a_kind_of(Mash)
+ expect(@attributes).to be_a_kind_of(Mash)
end
it "should inform you that it is a Chef::Node::Attribute" do
- @attributes.should be_a_kind_of(Chef::Node::Attribute)
+ expect(@attributes).to be_a_kind_of(Chef::Node::Attribute)
end
it "should inform you that it is anything else" do
- @attributes.should_not be_a_kind_of(Chef::Node)
+ expect(@attributes).not_to be_a_kind_of(Chef::Node)
+ end
+ end
+
+ describe "to_s" do
+ it "should output simple attributes" do
+ attributes = Chef::Node::Attribute.new(nil, nil, nil, nil)
+ expect(attributes.to_s).to eq("{}")
+ end
+
+ it "should output merged attributes" do
+ default_hash = {
+ "a" => 1,
+ "b" => 2
+ }
+ override_hash = {
+ "b" => 3,
+ "c" => 4
+ }
+ attributes = Chef::Node::Attribute.new(nil, default_hash, override_hash, nil)
+ expect(attributes.to_s).to eq('{"a"=>1, "b"=>3, "c"=>4}')
end
end
@@ -1085,18 +1133,19 @@ describe Chef::Node::Attribute do
# NOTE: previous implementation hid the values, showing @automatic={...}
# That is nice and compact, but hides a lot of info, which seems counter
# to the point of calling #inspect...
- @attributes.inspect.should =~ /@automatic=\{.*\}/
- @attributes.inspect.should =~ /@normal=\{.*\}/
+ expect(@attributes.inspect).to match(/@automatic=\{.*\}/)
+ expect(@attributes.inspect).to match(/@normal=\{.*\}/)
end
end
+
describe "when not mutated" do
it "does not reset the cache when dup'd [CHEF-3680]" do
@attributes.default[:foo][:bar] = "set on original"
subtree = @attributes[:foo]
@attributes.default[:foo].dup[:bar] = "set on dup"
- subtree[:bar].should == "set on original"
+ expect(subtree[:bar]).to eq("set on original")
end
end
@@ -1105,25 +1154,25 @@ describe Chef::Node::Attribute do
it "converts the input in to a VividMash tree (default)" do
@attributes.default = {}
@attributes.default.foo = "bar"
- @attributes.merged_attributes[:foo].should == "bar"
+ expect(@attributes.merged_attributes[:foo]).to eq("bar")
end
it "converts the input in to a VividMash tree (normal)" do
@attributes.normal = {}
@attributes.normal.foo = "bar"
- @attributes.merged_attributes[:foo].should == "bar"
+ expect(@attributes.merged_attributes[:foo]).to eq("bar")
end
it "converts the input in to a VividMash tree (override)" do
@attributes.override = {}
@attributes.override.foo = "bar"
- @attributes.merged_attributes[:foo].should == "bar"
+ expect(@attributes.merged_attributes[:foo]).to eq("bar")
end
it "converts the input in to a VividMash tree (automatic)" do
@attributes.automatic = {}
@attributes.automatic.foo = "bar"
- @attributes.merged_attributes[:foo].should == "bar"
+ expect(@attributes.merged_attributes[:foo]).to eq("bar")
end
end
@@ -1163,11 +1212,11 @@ describe Chef::Node::Attribute do
describe "when attemping to write without specifying precedence" do
it "raises an error when using []=" do
- lambda { @attributes[:new_key] = "new value" }.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
+ expect { @attributes[:new_key] = "new value" }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
end
it "raises an error when using `attr=value`" do
- lambda { @attributes.new_key = "new value" }.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
+ expect { @attributes.new_key = "new value" }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
end
end
diff --git a/spec/unit/node/immutable_collections_spec.rb b/spec/unit/node/immutable_collections_spec.rb
index 1c216e327a..d0ec81c7f7 100644
--- a/spec/unit/node/immutable_collections_spec.rb
+++ b/spec/unit/node/immutable_collections_spec.rb
@@ -30,28 +30,28 @@ describe Chef::Node::ImmutableMash do
end
it "element references like regular hash" do
- @immutable_mash[:top][:second_level].should == "some value"
+ expect(@immutable_mash[:top][:second_level]).to eq("some value")
end
- it "elelment references like a regular Mash" do
- @immutable_mash[:top_level_2].should == %w[array of values]
+ it "element references like a regular Mash" do
+ expect(@immutable_mash[:top_level_2]).to eq(%w[array of values])
end
it "converts Hash-like inputs into ImmutableMash's" do
- @immutable_mash[:top].should be_a(Chef::Node::ImmutableMash)
+ expect(@immutable_mash[:top]).to be_a(Chef::Node::ImmutableMash)
end
it "converts array inputs into ImmutableArray's" do
- @immutable_mash[:top_level_2].should be_a(Chef::Node::ImmutableArray)
+ expect(@immutable_mash[:top_level_2]).to be_a(Chef::Node::ImmutableArray)
end
it "converts arrays of hashes to ImmutableArray's of ImmutableMashes" do
- @immutable_mash[:top_level_3].first.should be_a(Chef::Node::ImmutableMash)
+ expect(@immutable_mash[:top_level_3].first).to be_a(Chef::Node::ImmutableMash)
end
it "converts nested hashes to ImmutableMashes" do
- @immutable_mash[:top_level_4].should be_a(Chef::Node::ImmutableMash)
- @immutable_mash[:top_level_4][:level2].should be_a(Chef::Node::ImmutableMash)
+ expect(@immutable_mash[:top_level_4]).to be_a(Chef::Node::ImmutableMash)
+ expect(@immutable_mash[:top_level_4][:level2]).to be_a(Chef::Node::ImmutableMash)
end
describe "to_hash" do
@@ -60,23 +60,23 @@ describe Chef::Node::ImmutableMash do
end
it "converts an immutable mash to a new mutable hash" do
- @copy.should be_instance_of(Hash)
+ expect(@copy).to be_instance_of(Hash)
end
it "converts an immutable nested mash to a new mutable hash" do
- @copy['top_level_4']['level2'].should be_instance_of(Hash)
+ expect(@copy['top_level_4']['level2']).to be_instance_of(Hash)
end
it "converts an immutable nested array to a new mutable array" do
- @copy['top_level_2'].should be_instance_of(Array)
+ expect(@copy['top_level_2']).to be_instance_of(Array)
end
it "should create a mash with the same content" do
- @copy.should == @immutable_mash
+ expect(@copy).to eq(@immutable_mash)
end
it 'should allow mutation' do
- lambda { @copy['m'] = 'm' }.should_not raise_error
+ expect { @copy['m'] = 'm' }.not_to raise_error
end
end
@@ -97,14 +97,14 @@ describe Chef::Node::ImmutableMash do
:shift
].each do |mutator|
it "doesn't allow mutation via `#{mutator}'" do
- lambda { @immutable_mash.send(mutator) }.should raise_error
+ expect { @immutable_mash.send(mutator) }.to raise_error
end
end
it "returns a mutable version of itself when duped" do
mutable = @immutable_mash.dup
mutable[:new_key] = :value
- mutable[:new_key].should == :value
+ expect(mutable[:new_key]).to eq(:value)
end
end
@@ -154,7 +154,7 @@ describe Chef::Node::ImmutableArray do
:unshift
].each do |mutator|
it "does not allow mutation via `#{mutator}" do
- lambda { @immutable_array.send(mutator)}.should raise_error
+ expect { @immutable_array.send(mutator)}.to raise_error
end
end
@@ -165,7 +165,7 @@ describe Chef::Node::ImmutableArray do
it "returns a mutable version of itself when duped" do
mutable = @immutable_array.dup
mutable[0] = :value
- mutable[0].should == :value
+ expect(mutable[0]).to eq(:value)
end
describe "to_a" do
@@ -174,23 +174,23 @@ describe Chef::Node::ImmutableArray do
end
it "converts an immutable array to a new mutable array" do
- @copy.should be_instance_of(Array)
+ expect(@copy).to be_instance_of(Array)
end
it "converts an immutable nested array to a new mutable array" do
- @copy[1].should be_instance_of(Array)
+ expect(@copy[1]).to be_instance_of(Array)
end
it "converts an immutable nested mash to a new mutable hash" do
- @copy[2].should be_instance_of(Hash)
+ expect(@copy[2]).to be_instance_of(Hash)
end
it "should create an array with the same content" do
- @copy.should == @immutable_nested_array
+ expect(@copy).to eq(@immutable_nested_array)
end
it 'should allow mutation' do
- lambda { @copy << 'm' }.should_not raise_error
+ expect { @copy << 'm' }.not_to raise_error
end
end
diff --git a/spec/unit/node_spec.rb b/spec/unit/node_spec.rb
index 0bccc6d482..5939403ce6 100644
--- a/spec/unit/node_spec.rb
+++ b/spec/unit/node_spec.rb
@@ -28,167 +28,167 @@ describe Chef::Node do
it "creates a node and assigns it a name" do
node = Chef::Node.build('solo-node')
- node.name.should == 'solo-node'
+ expect(node.name).to eq('solo-node')
end
it "should validate the name of the node" do
- lambda{Chef::Node.build('solo node')}.should raise_error(Chef::Exceptions::ValidationFailed)
+ expect{Chef::Node.build('solo node')}.to raise_error(Chef::Exceptions::ValidationFailed)
end
it "should be sortable" do
n1 = Chef::Node.build('alpha')
n2 = Chef::Node.build('beta')
n3 = Chef::Node.build('omega')
- [n3, n1, n2].sort.should == [n1, n2, n3]
+ expect([n3, n1, n2].sort).to eq([n1, n2, n3])
end
describe "when the node does not exist on the server" do
before do
response = OpenStruct.new(:code => '404')
exception = Net::HTTPServerException.new("404 not found", response)
- Chef::Node.stub(:load).and_raise(exception)
+ allow(Chef::Node).to receive(:load).and_raise(exception)
node.name("created-node")
end
it "creates a new node for find_or_create" do
- Chef::Node.stub(:new).and_return(node)
- node.should_receive(:create).and_return(node)
+ allow(Chef::Node).to receive(:new).and_return(node)
+ expect(node).to receive(:create).and_return(node)
node = Chef::Node.find_or_create("created-node")
- node.name.should == 'created-node'
- node.should equal(node)
+ expect(node.name).to eq('created-node')
+ expect(node).to equal(node)
end
end
describe "when the node exists on the server" do
before do
node.name('existing-node')
- Chef::Node.stub(:load).and_return(node)
+ allow(Chef::Node).to receive(:load).and_return(node)
end
it "loads the node via the REST API for find_or_create" do
- Chef::Node.find_or_create('existing-node').should equal(node)
+ expect(Chef::Node.find_or_create('existing-node')).to equal(node)
end
end
describe "run_state" do
it "is an empty hash" do
- node.run_state.should respond_to(:keys)
- node.run_state.should be_empty
+ expect(node.run_state).to respond_to(:keys)
+ expect(node.run_state).to be_empty
end
end
describe "initialize" do
it "should default to the '_default' chef_environment" do
n = Chef::Node.new
- n.chef_environment.should == '_default'
+ expect(n.chef_environment).to eq('_default')
end
end
describe "name" do
it "should allow you to set a name with name(something)" do
- lambda { node.name("latte") }.should_not raise_error
+ expect { node.name("latte") }.not_to raise_error
end
it "should return the name with name()" do
node.name("latte")
- node.name.should eql("latte")
+ expect(node.name).to eql("latte")
end
it "should always have a string for name" do
- lambda { node.name(Hash.new) }.should raise_error(ArgumentError)
+ expect { node.name(Hash.new) }.to raise_error(ArgumentError)
end
it "cannot be blank" do
- lambda { node.name("")}.should raise_error(Chef::Exceptions::ValidationFailed)
+ expect { node.name("")}.to raise_error(Chef::Exceptions::ValidationFailed)
end
it "should not accept name doesn't match /^[\-[:alnum:]_:.]+$/" do
- lambda { node.name("space in it")}.should raise_error(Chef::Exceptions::ValidationFailed)
+ expect { node.name("space in it")}.to raise_error(Chef::Exceptions::ValidationFailed)
end
end
describe "chef_environment" do
it "should set an environment with chef_environment(something)" do
- lambda { node.chef_environment("latte") }.should_not raise_error
+ expect { node.chef_environment("latte") }.not_to raise_error
end
it "should return the chef_environment with chef_environment()" do
node.chef_environment("latte")
- node.chef_environment.should == "latte"
+ expect(node.chef_environment).to eq("latte")
end
it "should disallow non-strings" do
- lambda { node.chef_environment(Hash.new) }.should raise_error(ArgumentError)
- lambda { node.chef_environment(42) }.should raise_error(ArgumentError)
+ expect { node.chef_environment(Hash.new) }.to raise_error(ArgumentError)
+ expect { node.chef_environment(42) }.to raise_error(ArgumentError)
end
it "cannot be blank" do
- lambda { node.chef_environment("")}.should raise_error(Chef::Exceptions::ValidationFailed)
+ expect { node.chef_environment("")}.to raise_error(Chef::Exceptions::ValidationFailed)
end
end
describe "attributes" do
it "should have attributes" do
- node.attribute.should be_a_kind_of(Hash)
+ expect(node.attribute).to be_a_kind_of(Hash)
end
it "should allow attributes to be accessed by name or symbol directly on node[]" do
node.default["locust"] = "something"
- node[:locust].should eql("something")
- node["locust"].should eql("something")
+ expect(node[:locust]).to eql("something")
+ expect(node["locust"]).to eql("something")
end
it "should return nil if it cannot find an attribute with node[]" do
- node["secret"].should eql(nil)
+ expect(node["secret"]).to eql(nil)
end
it "does not allow you to set an attribute via node[]=" do
- lambda { node["secret"] = "shush" }.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
+ expect { node["secret"] = "shush" }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
end
it "should allow you to query whether an attribute exists with attribute?" do
node.default["locust"] = "something"
- node.attribute?("locust").should eql(true)
- node.attribute?("no dice").should eql(false)
+ expect(node.attribute?("locust")).to eql(true)
+ expect(node.attribute?("no dice")).to eql(false)
end
it "should let you go deep with attribute?" do
node.set["battles"]["people"]["wonkey"] = true
- node["battles"]["people"].attribute?("wonkey").should == true
- node["battles"]["people"].attribute?("snozzberry").should == false
+ expect(node["battles"]["people"].attribute?("wonkey")).to eq(true)
+ expect(node["battles"]["people"].attribute?("snozzberry")).to eq(false)
end
it "does not allow you to set an attribute via method_missing" do
- lambda { node.sunshine = "is bright"}.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
+ expect { node.sunshine = "is bright"}.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
end
it "should allow you get get an attribute via method_missing" do
node.default.sunshine = "is bright"
- node.sunshine.should eql("is bright")
+ expect(node.sunshine).to eql("is bright")
end
describe "normal attributes" do
it "should allow you to set an attribute with set, without pre-declaring a hash" do
node.set[:snoopy][:is_a_puppy] = true
- node[:snoopy][:is_a_puppy].should == true
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
end
it "should allow you to set an attribute with set_unless" do
node.set_unless[:snoopy][:is_a_puppy] = false
- node[:snoopy][:is_a_puppy].should == false
+ expect(node[:snoopy][:is_a_puppy]).to eq(false)
end
it "should not allow you to set an attribute with set_unless if it already exists" do
node.set[:snoopy][:is_a_puppy] = true
node.set_unless[:snoopy][:is_a_puppy] = false
- node[:snoopy][:is_a_puppy].should == true
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
end
it "should allow you to set a value after a set_unless" do
# this tests for set_unless_present state bleeding between statements CHEF-3806
node.set_unless[:snoopy][:is_a_puppy] = false
node.set[:snoopy][:is_a_puppy] = true
- node[:snoopy][:is_a_puppy].should == true
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
end
it "should let you set a value after a 'dangling' set_unless" do
@@ -196,43 +196,43 @@ describe Chef::Node do
node.set[:snoopy][:is_a_puppy] = "what"
node.set_unless[:snoopy][:is_a_puppy]
node.set[:snoopy][:is_a_puppy] = true
- node[:snoopy][:is_a_puppy].should == true
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
end
it "auto-vivifies attributes created via method syntax" do
node.set.fuu.bahrr.baz = "qux"
- node.fuu.bahrr.baz.should == "qux"
+ expect(node.fuu.bahrr.baz).to eq("qux")
end
it "should let you use tag as a convience method for the tags attribute" do
node.normal['tags'] = ['one', 'two']
node.tag('three', 'four')
- node['tags'].should == ['one', 'two', 'three', 'four']
+ expect(node['tags']).to eq(['one', 'two', 'three', 'four'])
end
end
describe "default attributes" do
it "should be set with default, without pre-declaring a hash" do
node.default[:snoopy][:is_a_puppy] = true
- node[:snoopy][:is_a_puppy].should == true
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
end
it "should allow you to set with default_unless without pre-declaring a hash" do
node.default_unless[:snoopy][:is_a_puppy] = false
- node[:snoopy][:is_a_puppy].should == false
+ expect(node[:snoopy][:is_a_puppy]).to eq(false)
end
it "should not allow you to set an attribute with default_unless if it already exists" do
node.default[:snoopy][:is_a_puppy] = true
node.default_unless[:snoopy][:is_a_puppy] = false
- node[:snoopy][:is_a_puppy].should == true
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
end
it "should allow you to set a value after a default_unless" do
# this tests for set_unless_present state bleeding between statements CHEF-3806
node.default_unless[:snoopy][:is_a_puppy] = false
node.default[:snoopy][:is_a_puppy] = true
- node[:snoopy][:is_a_puppy].should == true
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
end
it "should allow you to set a value after a 'dangling' default_unless" do
@@ -240,37 +240,37 @@ describe Chef::Node do
node.default[:snoopy][:is_a_puppy] = "what"
node.default_unless[:snoopy][:is_a_puppy]
node.default[:snoopy][:is_a_puppy] = true
- node[:snoopy][:is_a_puppy].should == true
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
end
it "auto-vivifies attributes created via method syntax" do
node.default.fuu.bahrr.baz = "qux"
- node.fuu.bahrr.baz.should == "qux"
+ expect(node.fuu.bahrr.baz).to eq("qux")
end
end
describe "override attributes" do
it "should be set with override, without pre-declaring a hash" do
node.override[:snoopy][:is_a_puppy] = true
- node[:snoopy][:is_a_puppy].should == true
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
end
it "should allow you to set with override_unless without pre-declaring a hash" do
node.override_unless[:snoopy][:is_a_puppy] = false
- node[:snoopy][:is_a_puppy].should == false
+ expect(node[:snoopy][:is_a_puppy]).to eq(false)
end
it "should not allow you to set an attribute with override_unless if it already exists" do
node.override[:snoopy][:is_a_puppy] = true
node.override_unless[:snoopy][:is_a_puppy] = false
- node[:snoopy][:is_a_puppy].should == true
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
end
it "should allow you to set a value after an override_unless" do
# this tests for set_unless_present state bleeding between statements CHEF-3806
node.override_unless[:snoopy][:is_a_puppy] = false
node.override[:snoopy][:is_a_puppy] = true
- node[:snoopy][:is_a_puppy].should == true
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
end
it "should allow you to set a value after a 'dangling' override_unless" do
@@ -278,12 +278,12 @@ describe Chef::Node do
node.override_unless[:snoopy][:is_a_puppy] = "what"
node.override_unless[:snoopy][:is_a_puppy]
node.override[:snoopy][:is_a_puppy] = true
- node[:snoopy][:is_a_puppy].should == true
+ expect(node[:snoopy][:is_a_puppy]).to eq(true)
end
it "auto-vivifies attributes created via method syntax" do
node.override.fuu.bahrr.baz = "qux"
- node.fuu.bahrr.baz.should == "qux"
+ expect(node.fuu.bahrr.baz).to eq("qux")
end
end
@@ -611,8 +611,39 @@ describe Chef::Node do
end
end
+ # In Chef-12.0 there is a deep_merge cache on the top level attribute which had a bug
+ # where it cached node[:foo] separate from node['foo']. These tests exercise those edge conditions.
+ #
+ # https://github.com/opscode/chef/issues/2700
+ # https://github.com/opscode/chef/issues/2712
+ # https://github.com/opscode/chef/issues/2745
+ #
+ describe "deep merge attribute cache edge conditions" do
+ it "does not error with complicated attribute substitution" do
+ node.default['chef_attribute_hell']['attr1'] = "attribute1"
+ node.default['chef_attribute_hell']['attr2'] = "#{node.chef_attribute_hell.attr1}/attr2"
+ expect { node.default['chef_attribute_hell']['attr3'] = "#{node.chef_attribute_hell.attr2}/attr3" }.not_to raise_error
+ end
+
+ it "caches both strings and symbols correctly" do
+ node.force_default[:solr][:version] = '4.10.2'
+ node.force_default[:solr][:data_dir] = "/opt/solr-#{node['solr'][:version]}/example/solr"
+ node.force_default[:solr][:xms] = "512M"
+ expect(node[:solr][:xms]).to eql("512M")
+ expect(node['solr'][:xms]).to eql("512M")
+ end
+
+ it "method interpolation syntax also works" do
+ node.default['passenger']['version'] = '4.0.57'
+ node.default['passenger']['root_path'] = "passenger-#{node['passenger']['version']}"
+ node.default['passenger']['root_path_2'] = "passenger-#{node.passenger['version']}"
+ expect(node['passenger']['root_path_2']).to eql("passenger-4.0.57")
+ expect(node[:passenger]['root_path_2']).to eql("passenger-4.0.57")
+ end
+ end
+
it "should raise an ArgumentError if you ask for an attribute that doesn't exist via method_missing" do
- lambda { node.sunshine }.should raise_error(NoMethodError)
+ expect { node.sunshine }.to raise_error(NoMethodError)
end
it "should allow you to iterate over attributes with each_attribute" do
@@ -622,10 +653,10 @@ describe Chef::Node do
node.each_attribute do |a,v|
seen_attributes[a] = v
end
- seen_attributes.should have_key("sunshine")
- seen_attributes.should have_key("canada")
- seen_attributes["sunshine"].should == "is bright"
- seen_attributes["canada"].should == "is a nice place"
+ expect(seen_attributes).to have_key("sunshine")
+ expect(seen_attributes).to have_key("canada")
+ expect(seen_attributes["sunshine"]).to eq("is bright")
+ expect(seen_attributes["canada"]).to eq("is a nice place")
end
end
@@ -637,62 +668,62 @@ describe Chef::Node do
it "consumes the run list portion of a collection of attributes and returns the remainder" do
attrs = {"run_list" => [ "role[base]", "recipe[chef::server]" ], "foo" => "bar"}
- node.consume_run_list(attrs).should == {"foo" => "bar"}
- node.run_list.should == [ "role[base]", "recipe[chef::server]" ]
+ expect(node.consume_run_list(attrs)).to eq({"foo" => "bar"})
+ expect(node.run_list).to eq([ "role[base]", "recipe[chef::server]" ])
end
it "should overwrites the run list with the run list it consumes" do
node.consume_run_list "recipes" => [ "one", "two" ]
node.consume_run_list "recipes" => [ "three" ]
- node.run_list.should == [ "three" ]
+ expect(node.run_list).to eq([ "three" ])
end
it "should not add duplicate recipes from the json attributes" do
node.run_list << "one"
node.consume_run_list "recipes" => [ "one", "two", "three" ]
- node.run_list.should == [ "one", "two", "three" ]
+ expect(node.run_list).to eq([ "one", "two", "three" ])
end
it "doesn't change the run list if no run_list is specified in the json" do
node.run_list << "role[database]"
node.consume_run_list "foo" => "bar"
- node.run_list.should == ["role[database]"]
+ expect(node.run_list).to eq(["role[database]"])
end
it "raises an exception if you provide both recipe and run_list attributes, since this is ambiguous" do
- lambda { node.consume_run_list "recipes" => "stuff", "run_list" => "other_stuff" }.should raise_error(Chef::Exceptions::AmbiguousRunlistSpecification)
+ expect { node.consume_run_list "recipes" => "stuff", "run_list" => "other_stuff" }.to raise_error(Chef::Exceptions::AmbiguousRunlistSpecification)
end
it "should add json attributes to the node" do
node.consume_external_attrs(@ohai_data, {"one" => "two", "three" => "four"})
- node.one.should eql("two")
- node.three.should eql("four")
+ expect(node.one).to eql("two")
+ expect(node.three).to eql("four")
end
it "should set the tags attribute to an empty array if it is not already defined" do
node.consume_external_attrs(@ohai_data, {})
- node.tags.should eql([])
+ expect(node.tags).to eql([])
end
it "should not set the tags attribute to an empty array if it is already defined" do
node.normal[:tags] = [ "radiohead" ]
node.consume_external_attrs(@ohai_data, {})
- node.tags.should eql([ "radiohead" ])
+ expect(node.tags).to eql([ "radiohead" ])
end
it "deep merges attributes instead of overwriting them" do
node.consume_external_attrs(@ohai_data, "one" => {"two" => {"three" => "four"}})
- node.one.to_hash.should == {"two" => {"three" => "four"}}
+ expect(node.one.to_hash).to eq({"two" => {"three" => "four"}})
node.consume_external_attrs(@ohai_data, "one" => {"abc" => "123"})
node.consume_external_attrs(@ohai_data, "one" => {"two" => {"foo" => "bar"}})
- node.one.to_hash.should == {"two" => {"three" => "four", "foo" => "bar"}, "abc" => "123"}
+ expect(node.one.to_hash).to eq({"two" => {"three" => "four", "foo" => "bar"}, "abc" => "123"})
end
it "gives attributes from JSON priority when deep merging" do
node.consume_external_attrs(@ohai_data, "one" => {"two" => {"three" => "four"}})
- node.one.to_hash.should == {"two" => {"three" => "four"}}
+ expect(node.one.to_hash).to eq({"two" => {"three" => "four"}})
node.consume_external_attrs(@ohai_data, "one" => {"two" => {"three" => "forty-two"}})
- node.one.to_hash.should == {"two" => {"three" => "forty-two"}}
+ expect(node.one.to_hash).to eq({"two" => {"three" => "forty-two"}})
end
end
@@ -704,21 +735,21 @@ describe Chef::Node do
it "sets its platform according to platform detection" do
node.consume_external_attrs(@ohai_data, {})
- node.automatic_attrs[:platform].should == 'foobuntu'
- node.automatic_attrs[:platform_version].should == '23.42'
+ expect(node.automatic_attrs[:platform]).to eq('foobuntu')
+ expect(node.automatic_attrs[:platform_version]).to eq('23.42')
end
it "consumes the run list from provided json attributes" do
node.consume_external_attrs(@ohai_data, {"run_list" => ['recipe[unicorn]']})
- node.run_list.should == ['recipe[unicorn]']
+ expect(node.run_list).to eq(['recipe[unicorn]'])
end
it "saves non-runlist json attrs for later" do
expansion = Chef::RunList::RunListExpansion.new('_default', [])
- node.run_list.stub(:expand).and_return(expansion)
+ allow(node.run_list).to receive(:expand).and_return(expansion)
node.consume_external_attrs(@ohai_data, {"foo" => "bar"})
node.expand!
- node.normal_attrs.should == {"foo" => "bar", "tags" => []}
+ expect(node.normal_attrs).to eq({"foo" => "bar", "tags" => []})
end
end
@@ -730,44 +761,44 @@ describe Chef::Node do
e.default_attributes("env default key" => "env default value")
e.override_attributes("env override key" => "env override value")
end
- Chef::Environment.should_receive(:load).with("rspec_env").and_return(@environment)
+ expect(Chef::Environment).to receive(:load).with("rspec_env").and_return(@environment)
@expansion = Chef::RunList::RunListExpansion.new("rspec_env", [])
node.chef_environment("rspec_env")
- node.run_list.stub(:expand).and_return(@expansion)
+ allow(node.run_list).to receive(:expand).and_return(@expansion)
end
it "sets the 'recipes' automatic attribute to the recipes in the expanded run_list" do
@expansion.recipes << 'recipe[chef::client]' << 'recipe[nginx::default]'
node.expand!
- node.automatic_attrs[:recipes].should == ['recipe[chef::client]', 'recipe[nginx::default]']
+ expect(node.automatic_attrs[:recipes]).to eq(['recipe[chef::client]', 'recipe[nginx::default]'])
end
it "sets the 'roles' automatic attribute to the expanded role list" do
@expansion.instance_variable_set(:@applied_roles, {'arf' => nil, 'countersnark' => nil})
node.expand!
- node.automatic_attrs[:roles].sort.should == ['arf', 'countersnark']
+ expect(node.automatic_attrs[:roles].sort).to eq(['arf', 'countersnark'])
end
it "applies default attributes from the environment as environment defaults" do
node.expand!
- node.attributes.env_default["env default key"].should == "env default value"
+ expect(node.attributes.env_default["env default key"]).to eq("env default value")
end
it "applies override attributes from the environment as env overrides" do
node.expand!
- node.attributes.env_override["env override key"].should == "env override value"
+ expect(node.attributes.env_override["env override key"]).to eq("env override value")
end
it "applies default attributes from roles as role defaults" do
@expansion.default_attrs["role default key"] = "role default value"
node.expand!
- node.attributes.role_default["role default key"].should == "role default value"
+ expect(node.attributes.role_default["role default key"]).to eq("role default value")
end
it "applies override attributes from roles as role overrides" do
@expansion.override_attrs["role override key"] = "role override value"
node.expand!
- node.attributes.role_override["role override key"].should == "role override value"
+ expect(node.attributes.role_override["role override key"]).to eq("role override value")
end
end
@@ -782,8 +813,8 @@ describe Chef::Node do
node.automatic_attrs[:recipes] = [ "nginx::other_module" ]
node.loaded_recipe(:nginx, "module")
expect(node.automatic_attrs[:recipes].length).to eq(2)
- expect(node.recipe?("nginx::module")).to be_true
- expect(node.recipe?("nginx::other_module")).to be_true
+ expect(node.recipe?("nginx::module")).to be true
+ expect(node.recipe?("nginx::other_module")).to be true
end
end
@@ -794,11 +825,11 @@ describe Chef::Node do
end
it "finds the recipe" do
- node.recipe?("nginx::module").should be_true
+ expect(node.recipe?("nginx::module")).to be true
end
it "does not find a recipe not in the run list" do
- node.recipe?("nginx::other_module").should be_false
+ expect(node.recipe?("nginx::other_module")).to be false
end
end
context "when a recipe is in the expanded run list only" do
@@ -808,11 +839,11 @@ describe Chef::Node do
end
it "finds a recipe in the expanded run list" do
- node.recipe?("nginx::module").should be_true
+ expect(node.recipe?("nginx::module")).to be true
end
it "does not find a recipe that's not in the run list" do
- node.recipe?("nginx::other_module").should be_false
+ expect(node.recipe?("nginx::other_module")).to be false
end
end
end
@@ -826,15 +857,15 @@ describe Chef::Node do
end
it "removes default attributes" do
- node.default.should be_empty
+ expect(node.default).to be_empty
end
it "removes override attributes" do
- node.override.should be_empty
+ expect(node.override).to be_empty
end
it "leaves normal level attributes untouched" do
- node[:foo].should == "normal"
+ expect(node[:foo]).to eq("normal")
end
end
@@ -849,32 +880,32 @@ describe Chef::Node do
@environment = Chef::Environment.new
@environment.default_attributes = {:default => "from env", :d_env => "env only" }
@environment.override_attributes = {:override => "from env", :o_env => "env only"}
- Chef::Environment.stub(:load).and_return(@environment)
+ allow(Chef::Environment).to receive(:load).and_return(@environment)
node.apply_expansion_attributes(@expansion)
end
it "does not nuke role-only default attrs" do
- node[:d_role].should == "role only"
+ expect(node[:d_role]).to eq("role only")
end
it "does not nuke role-only override attrs" do
- node[:o_role].should == "role only"
+ expect(node[:o_role]).to eq("role only")
end
it "does not nuke env-only default attrs" do
- node[:o_env].should == "env only"
+ expect(node[:o_env]).to eq("env only")
end
it "does not nuke role-only override attrs" do
- node[:o_env].should == "env only"
+ expect(node[:o_env]).to eq("env only")
end
it "gives role defaults precedence over env defaults" do
- node[:default].should == "from role"
+ expect(node[:default]).to eq("from role")
end
it "gives env overrides precedence over role overrides" do
- node[:override].should == "from env"
+ expect(node[:override]).to eq("from env")
end
end
@@ -894,60 +925,60 @@ describe Chef::Node do
end
it "sets attributes from the files" do
- node.ldap_server.should eql("ops1prod")
- node.ldap_basedn.should eql("dc=hjksolutions,dc=com")
- node.ldap_replication_password.should eql("forsure")
- node.smokey.should eql("robinson")
+ expect(node.ldap_server).to eql("ops1prod")
+ expect(node.ldap_basedn).to eql("dc=hjksolutions,dc=com")
+ expect(node.ldap_replication_password).to eql("forsure")
+ expect(node.smokey).to eql("robinson")
end
it "gives a sensible error when attempting to load a missing attributes file" do
- lambda { node.include_attribute("nope-this::doesnt-exist") }.should raise_error(Chef::Exceptions::CookbookNotFound)
+ expect { node.include_attribute("nope-this::doesnt-exist") }.to raise_error(Chef::Exceptions::CookbookNotFound)
end
end
describe "roles" do
it "should allow you to query whether or not it has a recipe applied with role?" do
node.run_list << "role[sunrise]"
- node.role?("sunrise").should eql(true)
- node.role?("not at home").should eql(false)
+ expect(node.role?("sunrise")).to eql(true)
+ expect(node.role?("not at home")).to eql(false)
end
it "should allow you to set roles with arguments" do
node.run_list << "role[one]"
node.run_list << "role[two]"
- node.role?("one").should eql(true)
- node.role?("two").should eql(true)
+ expect(node.role?("one")).to eql(true)
+ expect(node.role?("two")).to eql(true)
end
end
describe "run_list" do
it "should have a Chef::RunList of recipes and roles that should be applied" do
- node.run_list.should be_a_kind_of(Chef::RunList)
+ expect(node.run_list).to be_a_kind_of(Chef::RunList)
end
it "should allow you to query the run list with arguments" do
node.run_list "recipe[baz]"
- node.run_list?("recipe[baz]").should eql(true)
+ expect(node.run_list?("recipe[baz]")).to eql(true)
end
it "should allow you to set the run list with arguments" do
node.run_list "recipe[baz]", "role[foo]"
- node.run_list?("recipe[baz]").should eql(true)
- node.run_list?("role[foo]").should eql(true)
+ expect(node.run_list?("recipe[baz]")).to eql(true)
+ expect(node.run_list?("role[foo]")).to eql(true)
end
end
describe "from file" do
it "should load a node from a ruby file" do
node.from_file(File.expand_path(File.join(CHEF_SPEC_DATA, "nodes", "test.rb")))
- node.name.should eql("test.example.com-short")
- node.sunshine.should eql("in")
- node.something.should eql("else")
- node.run_list.should == ["operations-master", "operations-monitoring"]
+ expect(node.name).to eql("test.example.com-short")
+ expect(node.sunshine).to eql("in")
+ expect(node.something).to eql("else")
+ expect(node.run_list).to eq(["operations-master", "operations-monitoring"])
end
it "should raise an exception if the file cannot be found or read" do
- lambda { node.from_file("/tmp/monkeydiving") }.should raise_error(IOError)
+ expect { node.from_file("/tmp/monkeydiving") }.to raise_error(IOError)
end
end
@@ -975,16 +1006,16 @@ describe Chef::Node do
it "allows update of everything except name" do
node.update_from!(@example)
- node.name.should == "orig"
- node.chef_environment.should == @example.chef_environment
- node.default_attrs.should == @example.default_attrs
- node.override_attrs.should == @example.override_attrs
- node.normal_attrs.should == @example.normal_attrs
- node.run_list.should == @example.run_list
+ expect(node.name).to eq("orig")
+ expect(node.chef_environment).to eq(@example.chef_environment)
+ expect(node.default_attrs).to eq(@example.default_attrs)
+ expect(node.override_attrs).to eq(@example.override_attrs)
+ expect(node.normal_attrs).to eq(@example.normal_attrs)
+ expect(node.run_list).to eq(@example.run_list)
end
it "should not update the name of the node" do
- node.should_not_receive(:name).with(@example.name)
+ expect(node).not_to receive(:name).with(@example.name)
node.update_from!(@example)
end
end
@@ -999,19 +1030,19 @@ describe Chef::Node do
node.run_list << "role[leninist]"
node.run_list << "recipe[stalinist]"
h = node.to_hash
- h["one"]["two"].should == "three"
- h["one"]["four"].should == "six"
- h["one"]["eight"].should == "nine"
- h["role"].should be_include("marxist")
- h["role"].should be_include("leninist")
- h["run_list"].should be_include("role[marxist]")
- h["run_list"].should be_include("role[leninist]")
- h["run_list"].should be_include("recipe[stalinist]")
- h["chef_environment"].should == "dev"
+ expect(h["one"]["two"]).to eq("three")
+ expect(h["one"]["four"]).to eq("six")
+ expect(h["one"]["eight"]).to eq("nine")
+ expect(h["role"]).to be_include("marxist")
+ expect(h["role"]).to be_include("leninist")
+ expect(h["run_list"]).to be_include("role[marxist]")
+ expect(h["run_list"]).to be_include("role[leninist]")
+ expect(h["run_list"]).to be_include("recipe[stalinist]")
+ expect(h["chef_environment"]).to eq("dev")
end
it 'should return an empty array for empty run_list' do
- node.to_hash["run_list"].should == []
+ expect(node.to_hash["run_list"]).to eq([])
end
end
@@ -1019,13 +1050,13 @@ describe Chef::Node do
it "should serialize itself as json", :json => true do
node.from_file(File.expand_path("nodes/test.example.com.rb", CHEF_SPEC_DATA))
json = Chef::JSONCompat.to_json(node)
- json.should =~ /json_class/
- json.should =~ /name/
- json.should =~ /chef_environment/
- json.should =~ /normal/
- json.should =~ /default/
- json.should =~ /override/
- json.should =~ /run_list/
+ expect(json).to match(/json_class/)
+ expect(json).to match(/name/)
+ expect(json).to match(/chef_environment/)
+ expect(json).to match(/normal/)
+ expect(json).to match(/default/)
+ expect(json).to match(/override/)
+ expect(json).to match(/run_list/)
end
it 'should serialize valid json with a run list', :json => true do
@@ -1034,45 +1065,45 @@ describe Chef::Node do
node.run_list << {"type" => "role", "name" => 'Cthulu'}
node.run_list << {"type" => "role", "name" => 'Hastur'}
json = Chef::JSONCompat.to_json(node)
- json.should =~ /\"run_list\":\[\"role\[Cthulu\]\",\"role\[Hastur\]\"\]/
+ expect(json).to match(/\"run_list\":\[\"role\[Cthulu\]\",\"role\[Hastur\]\"\]/)
end
it "should serialize the correct run list", :json => true do
node.run_list << "role[marxist]"
node.run_list << "role[leninist]"
node.override_runlist << "role[stalinist]"
- node.run_list.should be_include("role[stalinist]")
+ expect(node.run_list).to be_include("role[stalinist]")
json = Chef::JSONCompat.to_json(node)
- json.should =~ /\"run_list\":\[\"role\[marxist\]\",\"role\[leninist\]\"\]/
+ expect(json).to match(/\"run_list\":\[\"role\[marxist\]\",\"role\[leninist\]\"\]/)
end
it "merges the override components into a combined override object" do
node.attributes.role_override["role override"] = "role override"
node.attributes.env_override["env override"] = "env override"
node_for_json = node.for_json
- node_for_json["override"]["role override"].should == "role override"
- node_for_json["override"]["env override"].should == "env override"
+ expect(node_for_json["override"]["role override"]).to eq("role override")
+ expect(node_for_json["override"]["env override"]).to eq("env override")
end
it "merges the default components into a combined default object" do
node.attributes.role_default["role default"] = "role default"
node.attributes.env_default["env default"] = "env default"
node_for_json = node.for_json
- node_for_json["default"]["role default"].should == "role default"
- node_for_json["default"]["env default"].should == "env default"
+ expect(node_for_json["default"]["role default"]).to eq("role default")
+ expect(node_for_json["default"]["env default"]).to eq("env default")
end
it "should deserialize itself from json", :json => true do
node.from_file(File.expand_path("nodes/test.example.com.rb", CHEF_SPEC_DATA))
json = Chef::JSONCompat.to_json(node)
serialized_node = Chef::JSONCompat.from_json(json)
- serialized_node.should be_a_kind_of(Chef::Node)
- serialized_node.name.should eql(node.name)
- serialized_node.chef_environment.should eql(node.chef_environment)
+ expect(serialized_node).to be_a_kind_of(Chef::Node)
+ expect(serialized_node.name).to eql(node.name)
+ expect(serialized_node.chef_environment).to eql(node.chef_environment)
node.each_attribute do |k,v|
- serialized_node[k].should eql(v)
+ expect(serialized_node[k]).to eql(v)
end
- serialized_node.run_list.should == node.run_list
+ expect(serialized_node.run_list).to eq(node.run_list)
end
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
@@ -1086,45 +1117,45 @@ describe Chef::Node do
describe "to_s" do
it "should turn into a string like node[name]" do
node.name("airplane")
- node.to_s.should eql("node[airplane]")
+ expect(node.to_s).to eql("node[airplane]")
end
end
describe "api model" do
before(:each) do
@rest = double("Chef::REST")
- Chef::REST.stub(:new).and_return(@rest)
+ allow(Chef::REST).to receive(:new).and_return(@rest)
@query = double("Chef::Search::Query")
- Chef::Search::Query.stub(:new).and_return(@query)
+ allow(Chef::Search::Query).to receive(:new).and_return(@query)
end
describe "list" do
describe "inflated" do
it "should return a hash of node names and objects" do
n1 = double("Chef::Node", :name => "one")
- @query.should_receive(:search).with(:node).and_yield(n1)
+ expect(@query).to receive(:search).with(:node).and_yield(n1)
r = Chef::Node.list(true)
- r["one"].should == n1
+ expect(r["one"]).to eq(n1)
end
end
it "should return a hash of node names and urls" do
- @rest.should_receive(:get_rest).and_return({ "one" => "http://foo" })
+ expect(@rest).to receive(:get_rest).and_return({ "one" => "http://foo" })
r = Chef::Node.list
- r["one"].should == "http://foo"
+ expect(r["one"]).to eq("http://foo")
end
end
describe "load" do
it "should load a node by name" do
- @rest.should_receive(:get_rest).with("nodes/monkey").and_return("foo")
- Chef::Node.load("monkey").should == "foo"
+ expect(@rest).to receive(:get_rest).with("nodes/monkey").and_return("foo")
+ expect(Chef::Node.load("monkey")).to eq("foo")
end
end
describe "destroy" do
it "should destroy a node" do
- @rest.should_receive(:delete_rest).with("nodes/monkey").and_return("foo")
+ expect(@rest).to receive(:delete_rest).with("nodes/monkey").and_return("foo")
node.name("monkey")
node.destroy
end
@@ -1133,25 +1164,25 @@ describe Chef::Node do
describe "save" do
it "should update a node if it already exists" do
node.name("monkey")
- node.stub(:data_for_save).and_return({})
- @rest.should_receive(:put_rest).with("nodes/monkey", {}).and_return("foo")
+ allow(node).to receive(:data_for_save).and_return({})
+ expect(@rest).to receive(:put_rest).with("nodes/monkey", {}).and_return("foo")
node.save
end
it "should not try and create if it can update" do
node.name("monkey")
- node.stub(:data_for_save).and_return({})
- @rest.should_receive(:put_rest).with("nodes/monkey", {}).and_return("foo")
- @rest.should_not_receive(:post_rest)
+ allow(node).to receive(:data_for_save).and_return({})
+ expect(@rest).to receive(:put_rest).with("nodes/monkey", {}).and_return("foo")
+ expect(@rest).not_to receive(:post_rest)
node.save
end
it "should create if it cannot update" do
node.name("monkey")
- node.stub(:data_for_save).and_return({})
+ allow(node).to receive(:data_for_save).and_return({})
exception = double("404 error", :code => "404")
- @rest.should_receive(:put_rest).and_raise(Net::HTTPServerException.new("foo", exception))
- @rest.should_receive(:post_rest).with("nodes", {})
+ expect(@rest).to receive(:put_rest).and_raise(Net::HTTPServerException.new("foo", exception))
+ expect(@rest).to receive(:post_rest).with("nodes", {})
node.save
end
@@ -1164,8 +1195,8 @@ describe Chef::Node do
end
it "should not save" do
node.name("monkey")
- @rest.should_not_receive(:put_rest)
- @rest.should_not_receive(:post_rest)
+ expect(@rest).not_to receive(:put_rest)
+ expect(@rest).not_to receive(:post_rest)
node.save
end
end
@@ -1208,8 +1239,8 @@ describe Chef::Node do
}
node.name("picky-monkey")
- node.stub(:for_json).and_return(data)
- @rest.should_receive(:put_rest).with("nodes/picky-monkey", selected_data).and_return("foo")
+ allow(node).to receive(:for_json).and_return(data)
+ expect(@rest).to receive(:put_rest).with("nodes/picky-monkey", selected_data).and_return("foo")
node.save
end
@@ -1265,8 +1296,8 @@ describe Chef::Node do
}
node.name("picky-monkey")
- node.stub(:for_json).and_return(data)
- @rest.should_receive(:put_rest).with("nodes/picky-monkey", selected_data).and_return("foo")
+ allow(node).to receive(:for_json).and_return(data)
+ expect(@rest).to receive(:put_rest).with("nodes/picky-monkey", selected_data).and_return("foo")
node.save
end
end
diff --git a/spec/unit/org_spec.rb b/spec/unit/org_spec.rb
new file mode 100644
index 0000000000..cd6cc94d91
--- /dev/null
+++ b/spec/unit/org_spec.rb
@@ -0,0 +1,196 @@
+#
+# Author:: Steven Danna (steve@opscode.com)
+# Copyright:: Copyright (c) 2014 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 'spec_helper'
+
+require 'chef/org'
+require 'tempfile'
+
+describe Chef::Org do
+ let(:org) { Chef::Org.new("an_org") }
+
+ describe "initialize" do
+ it "is a Chef::Org" do
+ expect(org).to be_a_kind_of(Chef::Org)
+ end
+ end
+
+ describe "name" do
+ it "lets you set the name to a string" do
+ org.name "sg1"
+ expect(org.name).to eq("sg1")
+ end
+
+ # It is not feasible to check all invalid characters. Here are a few
+ # that we probably care about.
+ it "raises on invalid characters" do
+ # capital letters
+ expect { org.name "Bar" }.to raise_error(ArgumentError)
+ # slashes
+ expect { org.name "foo/bar" }.to raise_error(ArgumentError)
+ # ?
+ expect { org.name "foo?" }.to raise_error(ArgumentError)
+ # &
+ expect { org.name "foo&" }.to raise_error(ArgumentError)
+ # spaces
+ expect { org.name "foo " }.to raise_error(ArgumentError)
+ end
+
+ it "raises an ArgumentError if you feed it anything but a string" do
+ expect { org.name Hash.new }.to raise_error(ArgumentError)
+ end
+ end
+
+ describe "full_name" do
+ it "lets you set the full name" do
+ org.full_name "foo"
+ expect(org.full_name).to eq("foo")
+ end
+
+ it "raises an ArgumentError if you feed it anything but a string" do
+ expect { org.name Hash.new }.to raise_error(ArgumentError)
+ end
+ end
+
+ describe "private_key" do
+ it "returns the private key" do
+ org.private_key("super private")
+ expect(org.private_key).to eq("super private")
+ end
+
+ it "raises an ArgumentError if you feed it something lame" do
+ expect { org.private_key Hash.new }.to raise_error(ArgumentError)
+ end
+ end
+
+ describe "when serializing to JSON" do
+ let(:json) do
+ org.name("black")
+ org.full_name("black crowes")
+ org.to_json
+ end
+
+ it "serializes as a JSON object" do
+ expect(json).to match(/^\{.+\}$/)
+ end
+
+ it "includes the name value" do
+ expect(json).to include(%q{"name":"black"})
+ end
+
+ it "includes the full name value" do
+ expect(json).to include(%q{"full_name":"black crowes"})
+ end
+
+ it "includes the private key when present" do
+ org.private_key("monkeypants")
+ expect(org.to_json).to include(%q{"private_key":"monkeypants"})
+ end
+
+ it "does not include the private key if not present" do
+ expect(json).to_not include("private_key")
+ end
+ end
+
+ describe "when deserializing from JSON" do
+ let(:org) do
+ o = { "name" => "turtle",
+ "full_name" => "turtle_club",
+ "private_key" => "pandas" }
+ Chef::Org.from_json(o.to_json)
+ end
+
+ it "deserializes to a Chef::Org object" do
+ expect(org).to be_a_kind_of(Chef::Org)
+ end
+
+ it "preserves the name" do
+ expect(org.name).to eq("turtle")
+ end
+
+ it "preserves the full_name" do
+ expect(org.full_name).to eq("turtle_club")
+ end
+
+ it "includes the private key if present" do
+ expect(org.private_key).to eq("pandas")
+ end
+ end
+
+ describe "API Interactions" do
+ let(:rest) do
+ Chef::Config[:chef_server_root] = "http://www.example.com"
+ r = double('rest')
+ allow(Chef::REST).to receive(:new).and_return(r)
+ r
+ end
+
+ let(:org) do
+ o = Chef::Org.new("foobar")
+ o.full_name "foo bar bat"
+ o
+ end
+
+ describe "list" do
+ let(:response) { {"foobar" => "http://www.example.com/organizations/foobar"} }
+ let(:inflated_response) { {"foobar" => org } }
+
+ it "lists all orgs" do
+ expect(rest).to receive(:get_rest).with("organizations").and_return(response)
+ expect(Chef::Org.list).to eq(response)
+ end
+
+ it "inflate all orgs" do
+ allow(Chef::Org).to receive(:load).with("foobar").and_return(org)
+ expect(rest).to receive(:get_rest).with("organizations").and_return(response)
+ expect(Chef::Org.list(true)).to eq(inflated_response)
+ end
+ end
+
+ describe "create" do
+ it "creates a new org via the API" do
+ expect(rest).to receive(:post_rest).with("organizations", {:name => "foobar", :full_name => "foo bar bat"}).and_return({})
+ org.create
+ end
+ end
+
+ describe "read" do
+ it "loads a named org from the API" do
+ expect(rest).to receive(:get_rest).with("organizations/foobar").and_return({"name" => "foobar", "full_name" => "foo bar bat", "private_key" => "private"})
+ org = Chef::Org.load("foobar")
+ expect(org.name).to eq("foobar")
+ expect(org.full_name).to eq("foo bar bat")
+ expect(org.private_key).to eq("private")
+ end
+ end
+
+ describe "update" do
+ it "updates an existing org on via the API" do
+ expect(rest).to receive(:put_rest).with("organizations/foobar", {:name => "foobar", :full_name => "foo bar bat"}).and_return({})
+ org.update
+ end
+ end
+
+ describe "destroy" do
+ it "deletes the specified org via the API" do
+ expect(rest).to receive(:delete_rest).with("organizations/foobar")
+ org.destroy
+ end
+ end
+ end
+end
diff --git a/spec/unit/platform/query_helpers_spec.rb b/spec/unit/platform/query_helpers_spec.rb
index 6adea5eecf..7aafc287ea 100644
--- a/spec/unit/platform/query_helpers_spec.rb
+++ b/spec/unit/platform/query_helpers_spec.rb
@@ -20,9 +20,9 @@ require 'spec_helper'
describe "Chef::Platform#windows_server_2003?" do
it "returns false early when not on windows" do
- Chef::Platform.stub(:windows?).and_return(false)
+ allow(Chef::Platform).to receive(:windows?).and_return(false)
expect(Chef::Platform).not_to receive(:require)
- expect(Chef::Platform.windows_server_2003?).to be_false
+ expect(Chef::Platform.windows_server_2003?).to be_falsey
end
# CHEF-4888: Need to call WIN32OLE.ole_initialize in new threads
@@ -34,14 +34,14 @@ end
describe 'Chef::Platform#supports_dsc?' do
it 'returns false if powershell is not present' do
node = Chef::Node.new
- Chef::Platform.supports_dsc?(node).should be_false
+ expect(Chef::Platform.supports_dsc?(node)).to be_falsey
end
['1.0', '2.0', '3.0'].each do |version|
it "returns false for Powershell #{version}" do
node = Chef::Node.new
node.automatic[:languages][:powershell][:version] = version
- Chef::Platform.supports_dsc?(node).should be_false
+ expect(Chef::Platform.supports_dsc?(node)).to be_falsey
end
end
@@ -49,7 +49,7 @@ describe 'Chef::Platform#supports_dsc?' do
it "returns true for Powershell #{version}" do
node = Chef::Node.new
node.automatic[:languages][:powershell][:version] = version
- Chef::Platform.supports_dsc?(node).should be_true
+ expect(Chef::Platform.supports_dsc?(node)).to be_truthy
end
end
end
diff --git a/spec/unit/platform_spec.rb b/spec/unit/platform_spec.rb
index 9a65cbe878..fb65ef0fea 100644
--- a/spec/unit/platform_spec.rb
+++ b/spec/unit/platform_spec.rb
@@ -41,7 +41,7 @@ describe "Chef::Platform supports" do
:ibm_powerkvm
].each do |platform|
it "#{platform}" do
- Chef::Platform.platforms.should have_key(platform)
+ expect(Chef::Platform.platforms).to have_key(platform)
end
end
end
@@ -86,57 +86,57 @@ describe Chef::Platform do
it "should allow you to look up a platform by name and version, returning the provider map for it" do
pmap = Chef::Platform.find("Darwin", "9.2.2")
- pmap.should be_a_kind_of(Hash)
- pmap[:file].should eql("darwinian")
+ expect(pmap).to be_a_kind_of(Hash)
+ expect(pmap[:file]).to eql("darwinian")
end
it "should allow you to look up a platform by name and version using \"greater than\" style operators" do
pmap = Chef::Platform.find("Darwin", "11.1.0")
- pmap.should be_a_kind_of(Hash)
- pmap[:file].should eql("new_darwinian")
+ expect(pmap).to be_a_kind_of(Hash)
+ expect(pmap[:file]).to eql("new_darwinian")
end
it "should use the default providers for an os if the specific version does not exist" do
pmap = Chef::Platform.find("Darwin", "1")
- pmap.should be_a_kind_of(Hash)
- pmap[:file].should eql("old school")
+ expect(pmap).to be_a_kind_of(Hash)
+ expect(pmap[:file]).to eql("old school")
end
it "should use the default providers if the os doesn't give me a default, but does exist" do
pmap = Chef::Platform.find("mars_volta", "1")
- pmap.should be_a_kind_of(Hash)
- pmap[:file].should eql(Chef::Provider::File)
+ expect(pmap).to be_a_kind_of(Hash)
+ expect(pmap[:file]).to eql(Chef::Provider::File)
end
it "should use the default provider if the os does not exist" do
pmap = Chef::Platform.find("AIX", "1")
- pmap.should be_a_kind_of(Hash)
- pmap[:file].should eql(Chef::Provider::File)
+ expect(pmap).to be_a_kind_of(Hash)
+ expect(pmap[:file]).to eql(Chef::Provider::File)
end
it "should merge the defaults for an os with the specific version" do
pmap = Chef::Platform.find("Darwin", "9.2.2")
- pmap[:file].should eql("darwinian")
- pmap[:snicker].should eql("snack")
+ expect(pmap[:file]).to eql("darwinian")
+ expect(pmap[:snicker]).to eql("snack")
end
it "should merge the defaults for an os with the universal defaults" do
pmap = Chef::Platform.find("Darwin", "9.2.2")
- pmap[:file].should eql("darwinian")
- pmap[:pax].should eql("brittania")
+ expect(pmap[:file]).to eql("darwinian")
+ expect(pmap[:pax]).to eql("brittania")
end
it "should allow you to look up a provider for a platform directly by symbol" do
- Chef::Platform.find_provider("Darwin", "9.2.2", :file).should eql("darwinian")
+ expect(Chef::Platform.find_provider("Darwin", "9.2.2", :file)).to eql("darwinian")
end
it "should raise an exception if a provider cannot be found for a resource type" do
- lambda { Chef::Platform.find_provider("Darwin", "9.2.2", :coffee) }.should raise_error(ArgumentError)
+ expect { Chef::Platform.find_provider("Darwin", "9.2.2", :coffee) }.to raise_error(ArgumentError)
end
it "should look up a provider for a resource with a Chef::Resource object" do
kitty = Chef::Resource::Cat.new("loulou")
- Chef::Platform.find_provider("Darwin", "9.2.2", kitty).should eql("nice")
+ expect(Chef::Platform.find_provider("Darwin", "9.2.2", kitty)).to eql("nice")
end
it "should look up a provider with a node and a Chef::Resource object" do
@@ -145,21 +145,21 @@ describe Chef::Platform do
node.name("Intel")
node.automatic_attrs[:platform] = "mac_os_x"
node.automatic_attrs[:platform_version] = "9.2.2"
- Chef::Platform.find_provider_for_node(node, kitty).should eql("nice")
+ expect(Chef::Platform.find_provider_for_node(node, kitty)).to eql("nice")
end
it "should not throw an exception when the platform version has an unknown format" do
- Chef::Platform.find_provider(:darwin, "bad-version", :file).should eql("old school")
+ expect(Chef::Platform.find_provider(:darwin, "bad-version", :file)).to eql("old school")
end
it "should prefer an explicit provider" do
kitty = Chef::Resource::Cat.new("loulou")
- kitty.stub(:provider).and_return(Chef::Provider::File)
+ allow(kitty).to receive(:provider).and_return(Chef::Provider::File)
node = Chef::Node.new
node.name("Intel")
node.automatic_attrs[:platform] = "mac_os_x"
node.automatic_attrs[:platform_version] = "9.2.2"
- Chef::Platform.find_provider_for_node(node, kitty).should eql(Chef::Provider::File)
+ expect(Chef::Platform.find_provider_for_node(node, kitty)).to eql(Chef::Provider::File)
end
it "should look up a provider based on the resource name if nothing else matches" do
@@ -170,7 +170,7 @@ describe Chef::Platform do
node.name("Intel")
node.automatic_attrs[:platform] = "mac_os_x"
node.automatic_attrs[:platform_version] = "8.5"
- Chef::Platform.find_provider_for_node(node, kitty).should eql(Chef::Provider::Cat)
+ expect(Chef::Platform.find_provider_for_node(node, kitty)).to eql(Chef::Provider::Cat)
end
def setup_file_resource
@@ -184,26 +184,26 @@ describe Chef::Platform do
it "returns a provider object given a Chef::Resource object which has a valid run context and an action" do
file, run_context = setup_file_resource
provider = Chef::Platform.provider_for_resource(file, :foo)
- provider.should be_an_instance_of(Chef::Provider::File)
- provider.new_resource.should equal(file)
- provider.run_context.should equal(run_context)
+ expect(provider).to be_an_instance_of(Chef::Provider::File)
+ expect(provider.new_resource).to equal(file)
+ expect(provider.run_context).to equal(run_context)
end
it "returns a provider object given a Chef::Resource object which has a valid run context without an action" do
file, run_context = setup_file_resource
provider = Chef::Platform.provider_for_resource(file)
- provider.should be_an_instance_of(Chef::Provider::File)
- provider.new_resource.should equal(file)
- provider.run_context.should equal(run_context)
+ expect(provider).to be_an_instance_of(Chef::Provider::File)
+ expect(provider.new_resource).to equal(file)
+ expect(provider.run_context).to equal(run_context)
end
it "raises an error when trying to find the provider for a resource with no run context" do
file = Chef::Resource::File.new("whateva")
- lambda {Chef::Platform.provider_for_resource(file)}.should raise_error(ArgumentError)
+ expect {Chef::Platform.provider_for_resource(file)}.to raise_error(ArgumentError)
end
it "does not support finding a provider by resource and node -- a run context is required" do
- lambda {Chef::Platform.provider_for_node('node', 'resource')}.should raise_error(NotImplementedError)
+ expect {Chef::Platform.provider_for_node('node', 'resource')}.to raise_error(NotImplementedError)
end
it "should update the provider map with map" do
@@ -213,18 +213,18 @@ describe Chef::Platform do
:resource => :file,
:provider => "masterful"
)
- Chef::Platform.platforms[:darwin]["9.2.2"][:file].should eql("masterful")
+ expect(Chef::Platform.platforms[:darwin]["9.2.2"][:file]).to eql("masterful")
Chef::Platform.set(
:platform => :darwin,
:resource => :file,
:provider => "masterful"
)
- Chef::Platform.platforms[:darwin][:default][:file].should eql("masterful")
+ expect(Chef::Platform.platforms[:darwin][:default][:file]).to eql("masterful")
Chef::Platform.set(
:resource => :file,
:provider => "masterful"
)
- Chef::Platform.platforms[:default][:file].should eql("masterful")
+ expect(Chef::Platform.platforms[:default][:file]).to eql("masterful")
Chef::Platform.set(
:platform => :hero,
@@ -232,13 +232,13 @@ describe Chef::Platform do
:resource => :file,
:provider => "masterful"
)
- Chef::Platform.platforms[:hero]["9.2.2"][:file].should eql("masterful")
+ expect(Chef::Platform.platforms[:hero]["9.2.2"][:file]).to eql("masterful")
Chef::Platform.set(
:resource => :file,
:provider => "masterful"
)
- Chef::Platform.platforms[:default][:file].should eql("masterful")
+ expect(Chef::Platform.platforms[:default][:file]).to eql("masterful")
Chef::Platform.platforms = {}
@@ -246,11 +246,11 @@ describe Chef::Platform do
:resource => :file,
:provider => "masterful"
)
- Chef::Platform.platforms[:default][:file].should eql("masterful")
+ expect(Chef::Platform.platforms[:default][:file]).to eql("masterful")
Chef::Platform.platforms = { :neurosis => {} }
Chef::Platform.set(:platform => :neurosis, :resource => :package, :provider => "masterful")
- Chef::Platform.platforms[:neurosis][:default][:package].should eql("masterful")
+ expect(Chef::Platform.platforms[:neurosis][:default][:package]).to eql("masterful")
end
@@ -260,8 +260,8 @@ describe Chef::Platform do
:platform => :default,
:provider => "new school"
)
- Chef::Platform.platforms[:default][:file].should eql("new school")
- Chef::Platform.platforms[:default][:cat].should eql("nice")
+ expect(Chef::Platform.platforms[:default][:file]).to eql("new school")
+ expect(Chef::Platform.platforms[:default][:cat]).to eql("nice")
end
end
@@ -270,36 +270,36 @@ describe Chef::Platform do
it "should use the solaris package provider on Solaris <11" do
pmap = Chef::Platform.find("Solaris2", "5.9")
- pmap[:package].should eql(Chef::Provider::Package::Solaris)
+ expect(pmap[:package]).to eql(Chef::Provider::Package::Solaris)
end
it "should use the IPS package provider on Solaris 11" do
pmap = Chef::Platform.find("Solaris2", "5.11")
- pmap[:package].should eql(Chef::Provider::Package::Ips)
+ expect(pmap[:package]).to eql(Chef::Provider::Package::Ips)
end
it "should use the Redhat service provider on SLES11" do
1.upto(3) do |sp|
pmap = Chef::Platform.find("SUSE", "11.#{sp}")
- pmap[:service].should eql(Chef::Provider::Service::Redhat)
+ expect(pmap[:service]).to eql(Chef::Provider::Service::Redhat)
end
end
it "should use the Systemd service provider on SLES12" do
pmap = Chef::Platform.find("SUSE", "12.0")
- pmap[:service].should eql(Chef::Provider::Service::Systemd)
+ expect(pmap[:service]).to eql(Chef::Provider::Service::Systemd)
end
it "should use the SUSE group provider on SLES11" do
1.upto(3) do |sp|
pmap = Chef::Platform.find("SUSE", "11.#{sp}")
- pmap[:group].should eql(Chef::Provider::Group::Suse)
+ expect(pmap[:group]).to eql(Chef::Provider::Group::Suse)
end
end
it "should use the Gpasswd group provider on SLES12" do
pmap = Chef::Platform.find("SUSE", "12.0")
- pmap[:group].should eql(Chef::Provider::Group::Gpasswd)
+ expect(pmap[:group]).to eql(Chef::Provider::Group::Gpasswd)
end
end
diff --git a/spec/unit/policy_builder/expand_node_object_spec.rb b/spec/unit/policy_builder/expand_node_object_spec.rb
index a1e0b881d5..8e9fdc305e 100644
--- a/spec/unit/policy_builder/expand_node_object_spec.rb
+++ b/spec/unit/policy_builder/expand_node_object_spec.rb
@@ -73,7 +73,7 @@ describe Chef::PolicyBuilder::ExpandNodeObject do
it "creates a new in-memory node object with the given name" do
policy_builder.load_node
- policy_builder.node.name.should == node_name
+ expect(policy_builder.node.name).to eq(node_name)
end
end
@@ -83,9 +83,9 @@ describe Chef::PolicyBuilder::ExpandNodeObject do
let(:node) { Chef::Node.new.tap { |n| n.name(node_name) } }
it "loads or creates a node on the server" do
- Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
policy_builder.load_node
- policy_builder.node.should == node
+ expect(policy_builder.node).to eq(node)
end
end
@@ -95,7 +95,7 @@ describe Chef::PolicyBuilder::ExpandNodeObject do
# XXX: Chef::Client just needs to be able to call this, it doesn't depend on the return value.
it "builds the node and returns the updated node object" do
- pending
+ skip
end
end
@@ -133,7 +133,7 @@ describe Chef::PolicyBuilder::ExpandNodeObject do
end
before do
- Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
policy_builder.load_node
end
@@ -167,7 +167,7 @@ describe Chef::PolicyBuilder::ExpandNodeObject do
before do
Chef::Config[:environment] = configured_environment
- Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
policy_builder.load_node
policy_builder.build_node
end
@@ -186,7 +186,7 @@ describe Chef::PolicyBuilder::ExpandNodeObject do
end
it "reports that a temporary_policy is not being used" do
- expect(policy_builder.temporary_policy?).to be_false
+ expect(policy_builder.temporary_policy?).to be_falsey
end
describe "when the given run list is not in expanded form" do
@@ -210,7 +210,7 @@ describe Chef::PolicyBuilder::ExpandNodeObject do
node.override_attrs = original_override_attrs
node.run_list(primary_runlist)
- node.should_receive(:expand!).with("server") do
+ expect(node).to receive(:expand!).with("server") do
node.run_list("recipe[from_role::default]")
expansion
end
@@ -248,7 +248,7 @@ describe Chef::PolicyBuilder::ExpandNodeObject do
end
it "reports that a temporary policy is being used" do
- expect(policy_builder.temporary_policy?).to be_true
+ expect(policy_builder.temporary_policy?).to be_truthy
end
end
@@ -267,7 +267,7 @@ describe Chef::PolicyBuilder::ExpandNodeObject do
let(:environment) do
environment = Chef::Environment.new.tap {|e| e.name("prod") }
- Chef::Environment.should_receive(:load).with("prod").and_return(environment)
+ expect(Chef::Environment).to receive(:load).with("prod").and_return(environment)
environment
end
@@ -302,27 +302,27 @@ describe Chef::PolicyBuilder::ExpandNodeObject do
let(:cookbook_synchronizer) { double("CookbookSynchronizer") }
before do
- Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
- policy_builder.stub(:api_service).and_return(chef_http)
+ allow(policy_builder).to receive(:api_service).and_return(chef_http)
policy_builder.load_node
policy_builder.build_node
run_list_expansion = policy_builder.run_list_expansion
- chef_http.should_receive(:post).with(cookbook_resolve_url, cookbook_resolve_post_data).and_return(cookbook_hash)
- Chef::CookbookSynchronizer.should_receive(:new).with(cookbook_hash, events).and_return(cookbook_synchronizer)
- cookbook_synchronizer.should_receive(:sync_cookbooks)
+ expect(chef_http).to receive(:post).with(cookbook_resolve_url, cookbook_resolve_post_data).and_return(cookbook_hash)
+ expect(Chef::CookbookSynchronizer).to receive(:new).with(cookbook_hash, events).and_return(cookbook_synchronizer)
+ expect(cookbook_synchronizer).to receive(:sync_cookbooks)
- Chef::RunContext.any_instance.should_receive(:load).with(run_list_expansion)
+ expect_any_instance_of(Chef::RunContext).to receive(:load).with(run_list_expansion)
policy_builder.setup_run_context
end
it "configures FileVendor to fetch files remotely" do
manifest = double("cookbook manifest")
- Chef::Cookbook::RemoteFileVendor.should_receive(:new).with(manifest, chef_http)
+ expect(Chef::Cookbook::RemoteFileVendor).to receive(:new).with(manifest, chef_http)
Chef::Cookbook::FileVendor.create_from_manifest(manifest)
end
@@ -333,4 +333,3 @@ describe Chef::PolicyBuilder::ExpandNodeObject do
end
end
-
diff --git a/spec/unit/policy_builder/policyfile_spec.rb b/spec/unit/policy_builder/policyfile_spec.rb
index f02c79ef12..8b6e928a46 100644
--- a/spec/unit/policy_builder/policyfile_spec.rb
+++ b/spec/unit/policy_builder/policyfile_spec.rb
@@ -96,7 +96,7 @@ describe Chef::PolicyBuilder::Policyfile do
http = double("Chef::REST")
server_url = "https://api.opscode.com/organizations/example"
Chef::Config[:chef_server_url] = server_url
- Chef::REST.should_receive(:new).with(server_url).and_return(http)
+ expect(Chef::REST).to receive(:new).with(server_url).and_return(http)
expect(policy_builder.http_api).to eq(http)
end
@@ -107,7 +107,7 @@ describe Chef::PolicyBuilder::Policyfile do
end
it "always gives `false` for #temporary_policy?" do
- expect(initialize_pb.temporary_policy?).to be_false
+ expect(initialize_pb.temporary_policy?).to be_falsey
end
context "chef-solo" do
@@ -144,7 +144,7 @@ describe Chef::PolicyBuilder::Policyfile do
end
- describe "when using compatibility mode" do
+ describe "loading policy data" do
let(:http_api) { double("Chef::REST") }
@@ -168,52 +168,116 @@ describe Chef::PolicyBuilder::Policyfile do
before do
# TODO: agree on this name and logic.
Chef::Config[:deployment_group] = "example-policy-stage"
- policy_builder.stub(:http_api).and_return(http_api)
+ allow(policy_builder).to receive(:http_api).and_return(http_api)
end
- context "when the deployment group cannot be loaded" do
- let(:error404) { Net::HTTPServerException.new("404 message", :body) }
+ describe "when using compatibility mode (policy_document_native_api == false)" do
- before do
- Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
- http_api.should_receive(:get).
- with("data/policyfiles/example-policy-stage").
- and_raise(error404)
- end
+ context "when the deployment group cannot be loaded" do
+ let(:error404) { Net::HTTPServerException.new("404 message", :body) }
+
+ before do
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
+ expect(http_api).to receive(:get).
+ with("data/policyfiles/example-policy-stage").
+ and_raise(error404)
+ end
+
+ it "raises an error" do
+ expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ end
+
+ it "sends error message to the event system" do
+ expect(events).to receive(:node_load_failed).with(node_name, an_instance_of(err_namespace::ConfigurationError), Chef::Config)
+ expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ end
- it "raises an error" do
- expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
end
- it "sends error message to the event system" do
- events.should_receive(:node_load_failed).with(node_name, an_instance_of(err_namespace::ConfigurationError), Chef::Config)
- expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ context "when the deployment_group is not configured" do
+ before do
+ Chef::Config[:deployment_group] = nil
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
+ end
+
+ it "errors while loading the node" do
+ expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ end
+
+
+ it "passes error information to the event system" do
+ # TODO: also make sure something acceptable happens with the error formatters
+ err_class = err_namespace::ConfigurationError
+ expect(events).to receive(:node_load_failed).with(node_name, an_instance_of(err_class), Chef::Config)
+ expect { policy_builder.load_node }.to raise_error(err_class)
+ end
end
+ context "when deployment_group is correctly configured" do
+
+ let(:policy_relative_url) { "data/policyfiles/example-policy-stage" }
+
+ before do
+ expect(http_api).to receive(:get).with(policy_relative_url).and_return(parsed_policyfile_json)
+ end
+
+ it "fetches the policy file from a data bag item" do
+ expect(policy_builder.policy).to eq(parsed_policyfile_json)
+ end
+
+ it "extracts the run_list from the policyfile" do
+ expect(policy_builder.run_list).to eq(policyfile_run_list)
+ end
+
+ end
end
- describe "when the deployment_group is not configured" do
+ context "and policy_document_native_api is configured" do
+
before do
- Chef::Config[:deployment_group] = nil
- Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ Chef::Config[:policy_document_native_api] = true
+ Chef::Config[:policy_group] = "policy-stage"
+ Chef::Config[:policy_name] = "example"
end
- it "errors while loading the node" do
- expect { policy_builder.load_node }.to raise_error(err_namespace::ConfigurationError)
+ context "and policy_name or policy_group are not configured" do
+
+ it "raises a Configuration error for policy_group" do
+ Chef::Config[:policy_group] = nil
+ expect { policy_builder.policy }.to raise_error(err_namespace::ConfigurationError)
+ end
+
+ it "raises a Configuration error for policy_name" do
+ Chef::Config[:policy_name] = nil
+ expect { policy_builder.policy }.to raise_error(err_namespace::ConfigurationError)
+ end
+
end
+ context "and policy_name and policy_group are configured" do
+
+ let(:policy_relative_url) { "policies/policy-stage/example" }
- it "passes error information to the event system" do
- # TODO: also make sure something acceptable happens with the error formatters
- err_class = err_namespace::ConfigurationError
- events.should_receive(:node_load_failed).with(node_name, an_instance_of(err_class), Chef::Config)
- expect { policy_builder.load_node }.to raise_error(err_class)
+ before do
+ expect(http_api).to receive(:get).with(policy_relative_url).and_return(parsed_policyfile_json)
+ end
+
+ it "fetches the policy file from a data bag item" do
+ expect(policy_builder.policy).to eq(parsed_policyfile_json)
+ end
+
+ it "extracts the run_list from the policyfile" do
+ expect(policy_builder.run_list).to eq(policyfile_run_list)
+ end
end
+
end
- context "and a deployment_group is configured" do
+
+ describe "building policy from the policyfile" do
+
before do
- http_api.should_receive(:get).with("data/policyfiles/example-policy-stage").and_return(parsed_policyfile_json)
+ allow(policy_builder).to receive(:policy).and_return(parsed_policyfile_json)
end
it "fetches the policy file from a data bag item" do
@@ -239,7 +303,7 @@ describe Chef::PolicyBuilder::Policyfile do
end
it "implements #expand_run_list in a manner compatible with ExpandNodeObject" do
- Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
policy_builder.load_node
expect(policy_builder.expand_run_list).to respond_to(:recipes)
expect(policy_builder.expand_run_list.recipes).to eq(["example1::default", "example2::server"])
@@ -278,7 +342,7 @@ describe Chef::PolicyBuilder::Policyfile do
describe "building the node object" do
before do
- Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
policy_builder.load_node
policy_builder.build_node
@@ -334,67 +398,91 @@ describe Chef::PolicyBuilder::Policyfile do
let(:cookbook_synchronizer) { double("Chef::CookbookSynchronizer") }
- context "and a cookbook is missing" do
+ shared_examples_for "fetching cookbooks" do
+ context "and a cookbook is missing" do
- let(:error404) { Net::HTTPServerException.new("404 message", :body) }
+ let(:error404) { Net::HTTPServerException.new("404 message", :body) }
- before do
- Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ before do
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
- # Remove references to example2 cookbook because we're iterating
- # over a Hash data structure and on ruby 1.8.7 iteration order will
- # not be stable.
- parsed_policyfile_json["cookbook_locks"].delete("example2")
- parsed_policyfile_json["run_list"].delete("recipe[example2::server]")
+ policy_builder.load_node
+ policy_builder.build_node
- policy_builder.load_node
- policy_builder.build_node
+ expect(http_api).to receive(:get).with(cookbook1_url).
+ and_raise(error404)
+ end
- http_api.should_receive(:get).with("cookbooks/example1/#{example1_xyz_version}").
- and_raise(error404)
- end
+ it "raises an error indicating which cookbook is missing" do
+ expect { policy_builder.cookbooks_to_sync }.to raise_error(Chef::Exceptions::CookbookNotFound)
+ end
- it "raises an error indicating which cookbook is missing" do
- expect { policy_builder.cookbooks_to_sync }.to raise_error(Chef::Exceptions::CookbookNotFound)
end
- end
+ context "and the cookbooks can be fetched" do
+ before do
+ expect(Chef::Node).to receive(:find_or_create).with(node_name).and_return(node)
- context "and the cookbooks can be fetched" do
- before do
- Chef::Node.should_receive(:find_or_create).with(node_name).and_return(node)
+ policy_builder.load_node
+ policy_builder.build_node
+
+ expect(http_api).to receive(:get).with(cookbook1_url).
+ and_return(example1_cookbook_object)
+ expect(http_api).to receive(:get).with(cookbook2_url).
+ and_return(example2_cookbook_object)
+
+ allow(Chef::CookbookSynchronizer).to receive(:new).
+ with(expected_cookbook_hash, events).
+ and_return(cookbook_synchronizer)
+ end
- policy_builder.load_node
- policy_builder.build_node
+ it "builds a Hash of the form 'cookbook_name' => Chef::CookbookVersion" do
+ expect(policy_builder.cookbooks_to_sync).to eq(expected_cookbook_hash)
+ end
- http_api.should_receive(:get).with("cookbooks/example1/#{example1_xyz_version}").
- and_return(example1_cookbook_object)
- http_api.should_receive(:get).with("cookbooks/example2/#{example2_xyz_version}").
- and_return(example2_cookbook_object)
+ it "syncs the desired cookbooks via CookbookSynchronizer" do
+ expect(cookbook_synchronizer).to receive(:sync_cookbooks)
+ policy_builder.sync_cookbooks
+ end
+
+ it "builds a run context" do
+ expect(cookbook_synchronizer).to receive(:sync_cookbooks)
+ expect_any_instance_of(Chef::RunContext).to receive(:load).with(policy_builder.run_list_expansion_ish)
+ run_context = policy_builder.setup_run_context
+ expect(run_context.node).to eq(node)
+ expect(run_context.cookbook_collection.keys).to match_array(["example1", "example2"])
+ end
- Chef::CookbookSynchronizer.stub(:new).
- with(expected_cookbook_hash, events).
- and_return(cookbook_synchronizer)
end
+ end # shared_examples_for "fetching cookbooks"
+
+ context "when using compatibility mode (policy_document_native_api == false)" do
+ include_examples "fetching cookbooks" do
+
+ let(:cookbook1_url) { "cookbooks/example1/#{example1_xyz_version}" }
+ let(:cookbook2_url) { "cookbooks/example2/#{example2_xyz_version}" }
- it "builds a Hash of the form 'cookbook_name' => Chef::CookbookVersion" do
- expect(policy_builder.cookbooks_to_sync).to eq(expected_cookbook_hash)
end
- it "syncs the desired cookbooks via CookbookSynchronizer" do
- cookbook_synchronizer.should_receive(:sync_cookbooks)
- policy_builder.sync_cookbooks
+ end
+
+ context "when using native API mode (policy_document_native_api == true)" do
+
+ before do
+ Chef::Config[:policy_document_native_api] = true
+ Chef::Config[:policy_group] = "policy-stage"
+ Chef::Config[:policy_name] = "example"
end
- it "builds a run context" do
- cookbook_synchronizer.should_receive(:sync_cookbooks)
- Chef::RunContext.any_instance.should_receive(:load).with(policy_builder.run_list_expansion_ish)
- run_context = policy_builder.setup_run_context
- expect(run_context.node).to eq(node)
- expect(run_context.cookbook_collection.keys).to match_array(["example1", "example2"])
+ include_examples "fetching cookbooks" do
+
+ let(:cookbook1_url) { "cookbook_artifacts/example1/#{example1_xyz_version}" }
+ let(:cookbook2_url) { "cookbook_artifacts/example2/#{example2_xyz_version}" }
+
end
end
+
end
end
diff --git a/spec/unit/provider/directory_spec.rb b/spec/unit/provider/directory_spec.rb
index 33df776ed4..13c57bfe56 100644
--- a/spec/unit/provider/directory_spec.rb
+++ b/spec/unit/provider/directory_spec.rb
@@ -42,7 +42,7 @@ describe Chef::Provider::Directory do
end
it "describes the directory's access rights" do
- pending
+ skip
end
end
@@ -112,7 +112,7 @@ describe Chef::Provider::Directory do
expect(File).to receive(:exists?).with('/path/to').ordered.and_return(false)
expect(File).to receive(:exists?).with('/path').ordered.and_return(true)
- expect(File).to receive(:writable?).with('/path').ordered.and_return(true)
+ expect(Chef::FileAccessControl).to receive(:writable?).with('/path').ordered.and_return(true)
expect(File).to receive(:exists?).with(@new_resource.path).ordered.and_return(false)
expect(FileUtils).to receive(:mkdir_p).with(@new_resource.path).and_return(true)
@@ -137,7 +137,7 @@ describe Chef::Provider::Directory do
stub_file_cstats
@new_resource.path "/tmp/foo"
expect(File).to receive(:directory?).at_least(:once).and_return(true)
- expect(File).to receive(:writable?).with("/tmp").and_return(true)
+ expect(Chef::FileAccessControl).to receive(:writable?).with("/tmp").and_return(true)
expect(File).to receive(:exists?).at_least(:once).and_return(true)
expect(Dir).not_to receive(:mkdir).with(@new_resource.path)
expect(@directory).to receive(:do_acl_changes)
@@ -146,14 +146,14 @@ describe Chef::Provider::Directory do
it "should delete the directory if it exists, and is writable with action_delete" do
expect(File).to receive(:directory?).and_return(true)
- expect(File).to receive(:writable?).once.and_return(true)
+ expect(Chef::FileAccessControl).to receive(:writable?).once.and_return(true)
expect(Dir).to receive(:delete).with(@new_resource.path).once.and_return(true)
@directory.run_action(:delete)
end
it "should raise an exception if it cannot delete the directory due to bad permissions" do
allow(File).to receive(:exists?).and_return(true)
- allow(File).to receive(:writable?).and_return(false)
+ allow(Chef::FileAccessControl).to receive(:writable?).and_return(false)
expect { @directory.run_action(:delete) }.to raise_error(RuntimeError)
end
diff --git a/spec/unit/provider/dsc_script_spec.rb b/spec/unit/provider/dsc_script_spec.rb
index dab2007920..d4b2eb3b22 100644
--- a/spec/unit/provider/dsc_script_spec.rb
+++ b/spec/unit/provider/dsc_script_spec.rb
@@ -39,21 +39,21 @@ describe Chef::Provider::DscScript 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
- expect(provider.instance_variable_get('@resource_converged')).to be_true
+ expect(provider.instance_variable_get('@resource_converged')).to be_truthy
end
it "describes the resource as not converged if there is 1 DSC resources that is converged" do
dsc_resource_info = Chef::Util::DSC::ResourceInfo.new('resource', false, ['nothing will change something'])
allow(provider).to receive(:run_configuration).with(:test).and_return([dsc_resource_info])
provider.load_current_resource
- expect(provider.instance_variable_get('@resource_converged')).to be_true
+ expect(provider.instance_variable_get('@resource_converged')).to be_truthy
end
it "describes the resource as not converged if there is 1 DSC resources that is not converged" do
dsc_resource_info = Chef::Util::DSC::ResourceInfo.new('resource', true, ['will change something'])
allow(provider).to receive(:run_configuration).with(:test).and_return([dsc_resource_info])
provider.load_current_resource
- expect(provider.instance_variable_get('@resource_converged')).to be_false
+ expect(provider.instance_variable_get('@resource_converged')).to be_falsey
end
it "describes the resource as not converged if there are any DSC resources that are not converged" do
@@ -62,7 +62,7 @@ describe Chef::Provider::DscScript do
allow(provider).to receive(:run_configuration).with(:test).and_return([dsc_resource_info1, dsc_resource_info2])
provider.load_current_resource
- expect(provider.instance_variable_get('@resource_converged')).to be_false
+ expect(provider.instance_variable_get('@resource_converged')).to be_falsey
end
it "describes the resource as converged if all DSC resources that are converged" do
@@ -71,7 +71,7 @@ describe Chef::Provider::DscScript do
allow(provider).to receive(:run_configuration).with(:test).and_return([dsc_resource_info1, dsc_resource_info2])
provider.load_current_resource
- expect(provider.instance_variable_get('@resource_converged')).to be_true
+ expect(provider.instance_variable_get('@resource_converged')).to be_truthy
end
end
@@ -99,7 +99,7 @@ describe Chef::Provider::DscScript do
it 'should noop if neither code or command are provided' do
allow(provider).to receive(:load_current_resource)
generator = double('Chef::Util::DSC::ConfigurationGenerator')
- expect(generator).to receive(:configuration_document_from_script_code).with('', anything(), anything())
+ expect(generator).to receive(:configuration_document_from_script_code).with('', anything(), anything(), anything())
allow(Chef::Util::DSC::ConfigurationGenerator).to receive(:new).and_return(generator)
provider.send(:generate_configuration_document, 'tmp', nil)
end
diff --git a/spec/unit/provider/env_spec.rb b/spec/unit/provider/env_spec.rb
index 22fed4b7ac..230603dcb3 100644
--- a/spec/unit/provider/env_spec.rb
+++ b/spec/unit/provider/env_spec.rb
@@ -30,7 +30,7 @@ describe Chef::Provider::Env do
end
it "assumes the key_name exists by default" do
- expect(@provider.key_exists).to be_true
+ expect(@provider.key_exists).to be_truthy
end
describe "when loading the current status" do
@@ -55,13 +55,13 @@ describe Chef::Provider::Env do
it "should check if the key_name exists" do
expect(@provider).to receive(:env_key_exists).with("FOO").and_return(true)
@provider.load_current_resource
- expect(@provider.key_exists).to be_true
+ expect(@provider.key_exists).to be_truthy
end
it "should flip the value of exists if the key does not exist" do
expect(@provider).to receive(:env_key_exists).with("FOO").and_return(false)
@provider.load_current_resource
- expect(@provider.key_exists).to be_false
+ expect(@provider.key_exists).to be_falsey
end
it "should return the current resource" do
@@ -230,40 +230,47 @@ describe Chef::Provider::Env do
end
it "should return false if the values are equal" do
- expect(@provider.requires_modify_or_create?).to be_false
+ expect(@provider.requires_modify_or_create?).to be_falsey
end
it "should return true if the values not are equal" do
@new_resource.value("C:/elsewhere")
- expect(@provider.requires_modify_or_create?).to be_true
+ expect(@provider.requires_modify_or_create?).to be_truthy
end
it "should return false if the current value contains the element" do
@new_resource.delim(";")
@current_resource.value("C:/bar;C:/foo;C:/baz")
- expect(@provider.requires_modify_or_create?).to be_false
+ expect(@provider.requires_modify_or_create?).to be_falsey
end
it "should return true if the current value does not contain the element" do
@new_resource.delim(";")
@current_resource.value("C:/biz;C:/foo/bin;C:/baz")
- expect(@provider.requires_modify_or_create?).to be_true
+ expect(@provider.requires_modify_or_create?).to be_truthy
end
context "when new_resource's value contains the delimiter" do
- it "should return false if all the current values are contained" do
+ it "should return false if all the current values are contained in specified order" do
@new_resource.value("C:/biz;C:/baz")
@new_resource.delim(";")
@current_resource.value("C:/biz;C:/foo/bin;C:/baz")
- expect(@provider.requires_modify_or_create?).to be_false
+ expect(@provider.requires_modify_or_create?).to be_falsey
end
it "should return true if any of the new values are not contained" do
@new_resource.value("C:/biz;C:/baz;C:/bin")
@new_resource.delim(";")
@current_resource.value("C:/biz;C:/foo/bin;C:/baz")
- expect(@provider.requires_modify_or_create?).to be_true
+ expect(@provider.requires_modify_or_create?).to be_truthy
+ end
+
+ it "should return true if values are contained in different order" do
+ @new_resource.value("C:/biz;C:/baz")
+ @new_resource.delim(";")
+ @current_resource.value("C:/baz;C:/foo/bin;C:/biz")
+ expect(@provider.requires_modify_or_create?).to be_truthy
end
end
end
@@ -286,12 +293,18 @@ describe Chef::Provider::Env do
expect(passed_value).to eq(new_value)
end
- it "should only add values not already contained when a delimiter is provided" do
+ it "should only add values not already contained" do
@new_resource.value("C:/foo;C:/bar;C:/baz")
- @new_resource.delim(";")
- @current_resource.value("C:/foo/bar;C:/bar;C:/baz")
+ @current_resource.value("C:/bar;C:/baz;C:/foo/bar")
+ @provider.modify_env
+ expect(@new_resource.value).to eq("C:/foo;C:/bar;C:/baz;C:/foo/bar")
+ end
+
+ it "should reorder values to keep order which asked" do
+ @new_resource.value("C:/foo;C:/bar;C:/baz")
+ @current_resource.value("C:/foo/bar;C:/baz;C:/bar")
@provider.modify_env
- expect(@new_resource.value).to eq("C:/foo;C:/foo/bar;C:/bar;C:/baz")
+ expect(@new_resource.value).to eq("C:/foo;C:/bar;C:/baz;C:/foo/bar")
end
end
end
diff --git a/spec/unit/provider/execute_spec.rb b/spec/unit/provider/execute_spec.rb
index ea16d8cf54..51305b6225 100644
--- a/spec/unit/provider/execute_spec.rb
+++ b/spec/unit/provider/execute_spec.rb
@@ -15,91 +15,162 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
-#require 'spec_helper'
+
+require 'spec_helper'
describe Chef::Provider::Execute do
- before do
- @node = Chef::Node.new
- @cookbook_collection = Chef::CookbookCollection.new([])
- @events = Chef::EventDispatch::Dispatcher.new
- @run_context = Chef::RunContext.new(@node, @cookbook_collection, @events)
- @new_resource = Chef::Resource::Execute.new("foo_resource", @run_context)
- @new_resource.timeout 3600
- @new_resource.returns 0
- @new_resource.creates "/foo_resource"
- @provider = Chef::Provider::Execute.new(@new_resource, @run_context)
- @current_resource = Chef::Resource::Ifconfig.new("foo_resource", @run_context)
- @provider.current_resource = @current_resource
- Chef::Log.level = :info
- # FIXME: There should be a test for how STDOUT.tty? changes the live_stream option being passed
- allow(STDOUT).to receive(:tty?).and_return(true)
- end
+
+ let(:node) { Chef::Node.new }
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
+ let(:run_context) { Chef::RunContext.new(node, {}, events) }
+ let(:provider) { Chef::Provider::Execute.new(new_resource, run_context) }
+ let(:current_resource) { Chef::Resource::Ifconfig.new("foo_resource", run_context) }
let(:opts) do
{
- timeout: @new_resource.timeout,
- returns: @new_resource.returns,
- log_level: :info,
- log_tag: @new_resource.to_s,
- live_stream: STDOUT
+ timeout: 3600,
+ returns: 0,
+ log_level: :info,
+ log_tag: new_resource.to_s,
+ live_stream: STDOUT,
}
end
- it "should execute foo_resource" do
- allow(@provider).to receive(:load_current_resource)
- expect(@provider).to receive(:shell_out!).with(@new_resource.command, opts)
- expect(@provider).to receive(:converge_by).with("execute foo_resource").and_call_original
- expect(Chef::Log).not_to receive(:warn)
+ let(:new_resource) { Chef::Resource::Execute.new("foo_resource", run_context) }
- @provider.run_action(:run)
- expect(@new_resource).to be_updated
+ before do
+ allow(Chef::Platform).to receive(:windows?) { false }
+ @original_log_level = Chef::Log.level
+ Chef::Log.level = :info
+ allow(STDOUT).to receive(:tty?).and_return(true)
end
- it "should honor sensitive attribute" do
- @new_resource.sensitive true
- @provider = Chef::Provider::Execute.new(@new_resource, @run_context)
- allow(@provider).to receive(:load_current_resource)
- # Since the resource is sensitive, it should not have :live_stream set
- expect(@provider).to receive(:shell_out!).with(@new_resource.command, opts.reject { |k| k == :live_stream })
- expect(Chef::Log).not_to receive(:warn)
- expect(@provider).to receive(:converge_by).with("execute sensitive resource").and_call_original
- @provider.run_action(:run)
- expect(@new_resource).to be_updated
+ after do
+ Chef::Log.level = @original_log_level
end
- it "should do nothing if the sentinel file exists" do
- allow(@provider).to receive(:load_current_resource)
- expect(File).to receive(:exists?).with(@new_resource.creates).and_return(true)
- expect(@provider).not_to receive(:shell_out!)
- expect(Chef::Log).not_to receive(:warn)
-
- @provider.run_action(:run)
- expect(@new_resource).not_to be_updated
+ describe "#initialize" do
+ it "should return a Chef::Provider::Execute provider" do
+ expect(provider.class).to eql(Chef::Provider::Execute)
+ end
end
- it "should respect cwd options for 'creates'" do
- @new_resource.cwd "/tmp"
- @new_resource.creates "foo_resource"
- allow(@provider).to receive(:load_current_resource)
- expect(File).to receive(:exists?).with(@new_resource.creates).and_return(false)
- expect(File).to receive(:exists?).with(File.join("/tmp", @new_resource.creates)).and_return(true)
- expect(Chef::Log).not_to receive(:warn)
- expect(@provider).not_to receive(:shell_out!)
-
- @provider.run_action(:run)
- expect(@new_resource).not_to be_updated
+ describe "#load_current_resource" do
+ before do
+ expect(Chef::Resource::Execute).to receive(:new).with(new_resource.name).and_return(current_resource)
+ end
+
+ it "should return the current resource" do
+ expect(provider.load_current_resource).to eql(current_resource)
+ end
+
+ it "our timeout should default to 3600" do
+ provider.load_current_resource
+ expect(provider.timeout).to eql(3600)
+ end
end
- it "should warn if user specified relative path without cwd" do
- @new_resource.creates "foo_resource"
- allow(@provider).to receive(:load_current_resource)
- expect(Chef::Log).to receive(:warn).with(/relative path/)
- expect(File).to receive(:exists?).with(@new_resource.creates).and_return(true)
- expect(@provider).not_to receive(:shell_out!)
+ describe "#action_run" do
+ it "runs shell_out with the default options" do
+ expect(provider).to receive(:shell_out!).with(new_resource.name, opts)
+ expect(provider).to receive(:converge_by).with("execute foo_resource").and_call_original
+ expect(Chef::Log).not_to receive(:warn)
+ provider.run_action(:run)
+ expect(new_resource).to be_updated
+ end
- @provider.run_action(:run)
- expect(@new_resource).not_to be_updated
+ it "if you pass a command attribute, it runs the command" do
+ new_resource.command "/usr/argelbargle/bin/oogachacka 12345"
+ expect(provider).to receive(:shell_out!).with(new_resource.command, opts)
+ expect(provider).to receive(:converge_by).with("execute #{new_resource.command}").and_call_original
+ expect(Chef::Log).not_to receive(:warn)
+ provider.run_action(:run)
+ expect(new_resource).to be_updated
+ end
+
+ it "should honor sensitive attribute" do
+ new_resource.sensitive true
+ # Since the resource is sensitive, it should not have :live_stream set
+ opts.delete(:live_stream)
+ expect(provider).to receive(:shell_out!).with(new_resource.name, opts)
+ expect(provider).to receive(:converge_by).with("execute sensitive resource").and_call_original
+ expect(Chef::Log).not_to receive(:warn)
+ provider.run_action(:run)
+ expect(new_resource).to be_updated
+ end
+
+ it "should do nothing if the sentinel file exists" do
+ new_resource.creates "/foo_resource"
+ expect(FileTest).to receive(:exist?).with(new_resource.creates).and_return(true)
+ expect(provider).not_to receive(:shell_out!)
+ expect(Chef::Log).not_to receive(:warn)
+ provider.run_action(:run)
+ expect(new_resource).not_to be_updated
+ end
+
+ describe "when the user specifies a relative path without cwd" do
+ before do
+ expect(new_resource.cwd).to be_falsey
+ new_resource.creates "foo_resource"
+ end
+
+ it "should warn in Chef-12", :chef_lt_13_only do
+ expect(Chef::Log).to receive(:warn).with(/relative path/)
+ expect(FileTest).to receive(:exist?).with(new_resource.creates).and_return(true)
+ expect(provider).not_to receive(:shell_out!)
+ provider.run_action(:run)
+ expect(new_resource).not_to be_updated
+ end
+
+ it "should raise if user specified relative path without cwd for Chef-13", :chef_gte_13_only do
+ expect(Chef::Log).to receive(:warn).with(/relative path/)
+ expect(FileTest).to receive(:exist?).with(new_resource.creates).and_return(true)
+ expect(provider).not_to receive(:shell_out!)
+ expect { provider.run_action(:run) }.to raise_error # @todo: add a real error for Chef-13
+ end
+ end
+
+ it "should respect cwd options for 'creates'" do
+ new_resource.cwd "/tmp"
+ new_resource.creates "foo_resource"
+ expect(FileTest).not_to receive(:exist?).with(new_resource.creates)
+ expect(FileTest).to receive(:exist?).with(File.join("/tmp", new_resource.creates)).and_return(true)
+ expect(Chef::Log).not_to receive(:warn)
+ expect(provider).not_to receive(:shell_out!)
+
+ provider.run_action(:run)
+ expect(new_resource).not_to be_updated
+ end
+
+ it "should unset the live_stream if STDOUT is not a tty" do
+ expect(STDOUT).to receive(:tty?).and_return(false)
+ opts.delete(:live_stream)
+ expect(provider).to receive(:shell_out!).with(new_resource.name, opts)
+ expect(provider).to receive(:converge_by).with("execute foo_resource").and_call_original
+ expect(Chef::Log).not_to receive(:warn)
+ provider.run_action(:run)
+ expect(new_resource).to be_updated
+ end
+
+ it "should unset the live_stream if chef is running as a daemon" do
+ allow(Chef::Config).to receive(:[]).and_call_original
+ expect(Chef::Config).to receive(:[]).with(:daemon).and_return(true)
+ opts.delete(:live_stream)
+ expect(provider).to receive(:shell_out!).with(new_resource.name, opts)
+ expect(provider).to receive(:converge_by).with("execute foo_resource").and_call_original
+ expect(Chef::Log).not_to receive(:warn)
+ provider.run_action(:run)
+ expect(new_resource).to be_updated
+ end
+
+ it "should unset the live_stream if we are not running with a log level of at least :info" do
+ expect(Chef::Log).to receive(:info?).and_return(false)
+ opts.delete(:live_stream)
+ expect(provider).to receive(:shell_out!).with(new_resource.name, opts)
+ expect(provider).to receive(:converge_by).with("execute foo_resource").and_call_original
+ expect(Chef::Log).not_to receive(:warn)
+ provider.run_action(:run)
+ expect(new_resource).to be_updated
+ end
end
end
-
diff --git a/spec/unit/provider/file/content_spec.rb b/spec/unit/provider/file/content_spec.rb
index 284474290f..0a45d15bc9 100644
--- a/spec/unit/provider/file/content_spec.rb
+++ b/spec/unit/provider/file/content_spec.rb
@@ -66,14 +66,14 @@ describe Chef::Provider::File::Content do
it "returns a tempfile in the tempdir when :file_staging_uses_destdir is not set" do
Chef::Config[:file_staging_uses_destdir] = false
- expect(content.tempfile.path.start_with?(Dir::tmpdir)).to be_true
- expect(canonicalize_path(content.tempfile.path).start_with?(enclosing_directory)).to be_false
+ expect(content.tempfile.path.start_with?(Dir::tmpdir)).to be_truthy
+ expect(canonicalize_path(content.tempfile.path).start_with?(enclosing_directory)).to be_falsey
end
it "returns a tempfile in the destdir when :file_deployment_uses_destdir is set" do
Chef::Config[:file_staging_uses_destdir] = true
- expect(content.tempfile.path.start_with?(Dir::tmpdir)).to be_false
- expect(canonicalize_path(content.tempfile.path).start_with?(enclosing_directory)).to be_true
+ expect(content.tempfile.path.start_with?(Dir::tmpdir)).to be_falsey
+ expect(canonicalize_path(content.tempfile.path).start_with?(enclosing_directory)).to be_truthy
end
context "when creating a tempfiles in destdir fails" do
@@ -83,8 +83,8 @@ describe Chef::Provider::File::Content do
it "returns a tempfile in the tempdir when :file_deployment_uses_destdir is set to :auto" do
Chef::Config[:file_staging_uses_destdir] = :auto
- expect(content.tempfile.path.start_with?(Dir::tmpdir)).to be_true
- expect(canonicalize_path(content.tempfile.path).start_with?(enclosing_directory)).to be_false
+ expect(content.tempfile.path.start_with?(Dir::tmpdir)).to be_truthy
+ expect(canonicalize_path(content.tempfile.path).start_with?(enclosing_directory)).to be_falsey
end
it "fails when :file_desployment_uses_destdir is set" do
@@ -93,8 +93,8 @@ describe Chef::Provider::File::Content do
end
it "returns a tempfile in the tempdir when :file_desployment_uses_destdir is not set" do
- expect(content.tempfile.path.start_with?(Dir::tmpdir)).to be_true
- expect(canonicalize_path(content.tempfile.path).start_with?(enclosing_directory)).to be_false
+ expect(content.tempfile.path.start_with?(Dir::tmpdir)).to be_truthy
+ expect(canonicalize_path(content.tempfile.path).start_with?(enclosing_directory)).to be_falsey
end
end
diff --git a/spec/unit/provider/git_spec.rb b/spec/unit/provider/git_spec.rb
index bfbf531389..0106244665 100644
--- a/spec/unit/provider/git_spec.rb
+++ b/spec/unit/provider/git_spec.rb
@@ -22,6 +22,7 @@ describe Chef::Provider::Git do
before(:each) do
allow(STDOUT).to receive(:tty?).and_return(true)
+ @original_log_level = Chef::Log.level
Chef::Log.level = :info
@current_resource = Chef::Resource::Git.new("web2.0 app")
@@ -38,6 +39,10 @@ describe Chef::Provider::Git do
@provider.current_resource = @current_resource
end
+ after(:each) do
+ Chef::Log.level = @original_log_level
+ end
+
context "determining the revision of the currently deployed checkout" do
before do
@@ -621,21 +626,21 @@ SHAS
describe "when check remote command returns with status 2" do
it "returns true" do
allow(@command_response).to receive(:exitstatus) { 2 }
- expect(@provider.multiple_remotes?(@command_response)).to be_true
+ expect(@provider.multiple_remotes?(@command_response)).to be_truthy
end
end
describe "when check remote command returns with status 0" do
it "returns false" do
allow(@command_response).to receive(:exitstatus) { 0 }
- expect(@provider.multiple_remotes?(@command_response)).to be_false
+ expect(@provider.multiple_remotes?(@command_response)).to be_falsey
end
end
describe "when check remote command returns with status 0" do
it "returns false" do
allow(@command_response).to receive(:exitstatus) { 1 }
- expect(@provider.multiple_remotes?(@command_response)).to be_false
+ expect(@provider.multiple_remotes?(@command_response)).to be_falsey
end
end
end
@@ -649,7 +654,7 @@ SHAS
it "returns true" do
allow(@command_response).to receive(:exitstatus) { 0 }
allow(@command_response).to receive(:stdout) { @resource.repository }
- expect(@provider.remote_matches?(@resource.repository, @command_response)).to be_true
+ expect(@provider.remote_matches?(@resource.repository, @command_response)).to be_truthy
end
end
@@ -657,7 +662,7 @@ SHAS
it "returns false" do
allow(@command_response).to receive(:exitstatus) { 0 }
allow(@command_response).to receive(:stdout) { @resource.repository + "test" }
- expect(@provider.remote_matches?(@resource.repository, @command_response)).to be_false
+ expect(@provider.remote_matches?(@resource.repository, @command_response)).to be_falsey
end
end
end
diff --git a/spec/unit/provider/group/dscl_spec.rb b/spec/unit/provider/group/dscl_spec.rb
index acd1ba3859..d84e4e1d57 100644
--- a/spec/unit/provider/group/dscl_spec.rb
+++ b/spec/unit/provider/group/dscl_spec.rb
@@ -27,16 +27,13 @@ describe Chef::Provider::Group::Dscl do
@current_resource = Chef::Resource::Group.new("aj")
@provider = Chef::Provider::Group::Dscl.new(@new_resource, @run_context)
@provider.current_resource = @current_resource
- @status = double("Process::Status", :exitstatus => 0)
- @pid = 2342
- @stdin = StringIO.new
- @stdout = StringIO.new("\n")
- @stderr = StringIO.new("")
- allow(@provider).to receive(:popen4).and_yield(@pid,@stdin,@stdout,@stderr).and_return(@status)
+
+ @status = double(:stdout => "\n", :stderr => "", :exitstatus => 0)
+ allow(@provider).to receive(:shell_out).and_return(@status)
end
- it "should run popen4 with the supplied array of arguments appended to the dscl command" do
- expect(@provider).to receive(:popen4).with("dscl . -cmd /Path arg1 arg2")
+ it "should run shell_out with the supplied array of arguments appended to the dscl command" do
+ expect(@provider).to receive(:shell_out).with("dscl . -cmd /Path arg1 arg2")
@provider.dscl("cmd", "/Path", "arg1", "arg2")
end
@@ -129,15 +126,15 @@ describe Chef::Provider::Group::Dscl do
end
it "should return true for a used gid number" do
- expect(@provider.gid_used?(500)).to be_true
+ expect(@provider.gid_used?(500)).to be_truthy
end
it "should return false for an unused gid number" do
- expect(@provider.gid_used?(501)).to be_false
+ expect(@provider.gid_used?(501)).to be_falsey
end
it "should return false if not given any valid gid number" do
- expect(@provider.gid_used?(nil)).to be_false
+ expect(@provider.gid_used?(nil)).to be_falsey
end
end
diff --git a/spec/unit/provider/group_spec.rb b/spec/unit/provider/group_spec.rb
index e20486fd4a..b36bfe364b 100644
--- a/spec/unit/provider/group_spec.rb
+++ b/spec/unit/provider/group_spec.rb
@@ -45,7 +45,7 @@ describe Chef::Provider::User do
end
it "assumes the group exists by default" do
- expect(@provider.group_exists).to be_true
+ expect(@provider.group_exists).to be_truthy
end
describe "when establishing the current state of the group" do
@@ -76,7 +76,7 @@ describe Chef::Provider::User do
it "should flip the value of exists if it cannot be found in /etc/group" do
allow(Etc).to receive(:getgrnam).and_raise(ArgumentError)
@provider.load_current_resource
- expect(@provider.group_exists).to be_false
+ expect(@provider.group_exists).to be_falsey
end
it "should return the current resource" do
@@ -88,42 +88,42 @@ describe Chef::Provider::User do
[ :gid, :members ].each do |attribute|
it "should return true if #{attribute} doesn't match" do
allow(@current_resource).to receive(attribute).and_return("looooooooooooooooooool")
- expect(@provider.compare_group).to be_true
+ expect(@provider.compare_group).to be_truthy
end
end
it "should return false if gid and members are equal" do
- expect(@provider.compare_group).to be_false
+ expect(@provider.compare_group).to be_falsey
end
it "should coerce an integer to a string for comparison" do
allow(@current_resource).to receive(:gid).and_return("500")
- expect(@provider.compare_group).to be_false
+ expect(@provider.compare_group).to be_falsey
end
it "should return false if append is true and the group member(s) already exists" do
@current_resource.members << "extra_user"
allow(@new_resource).to receive(:append).and_return(true)
- expect(@provider.compare_group).to be_false
+ expect(@provider.compare_group).to be_falsey
end
it "should return true if append is true and the group member(s) do not already exist" do
@new_resource.members << "extra_user"
allow(@new_resource).to receive(:append).and_return(true)
- expect(@provider.compare_group).to be_true
+ expect(@provider.compare_group).to be_truthy
end
it "should return false if append is true and excluded_members include a non existing member" do
@new_resource.excluded_members << "extra_user"
allow(@new_resource).to receive(:append).and_return(true)
- expect(@provider.compare_group).to be_false
+ expect(@provider.compare_group).to be_falsey
end
it "should return true if the append is true and excluded_members include an existing user" do
@new_resource.members.each {|m| @new_resource.excluded_members << m }
@new_resource.members.clear
allow(@new_resource).to receive(:append).and_return(true)
- expect(@provider.compare_group).to be_true
+ expect(@provider.compare_group).to be_truthy
end
end
@@ -259,26 +259,26 @@ describe Chef::Provider::User do
@new_resource.members << "user1"
@new_resource.members << "user2"
allow(@new_resource).to receive(:append).and_return true
- expect(@provider.compare_group).to be_true
+ expect(@provider.compare_group).to be_truthy
expect(@provider.change_desc).to eq([ "add missing member(s): user1, user2" ])
end
it "should report that the group members will be overwritten if not appending" do
@new_resource.members << "user1"
allow(@new_resource).to receive(:append).and_return false
- expect(@provider.compare_group).to be_true
+ expect(@provider.compare_group).to be_truthy
expect(@provider.change_desc).to eq([ "replace group members with new list of members" ])
end
it "should report the gid will be changed when it does not match" do
allow(@current_resource).to receive(:gid).and_return("BADF00D")
- expect(@provider.compare_group).to be_true
+ expect(@provider.compare_group).to be_truthy
expect(@provider.change_desc).to eq([ "change gid #{@current_resource.gid} to #{@new_resource.gid}" ])
end
it "should report no change reason when no change is required" do
- expect(@provider.compare_group).to be_false
+ expect(@provider.compare_group).to be_falsey
expect(@provider.change_desc).to eq([ ])
end
end
diff --git a/spec/unit/provider/ifconfig/aix_spec.rb b/spec/unit/provider/ifconfig/aix_spec.rb
index 6e685823ac..0b6fa33614 100644
--- a/spec/unit/provider/ifconfig/aix_spec.rb
+++ b/spec/unit/provider/ifconfig/aix_spec.rb
@@ -49,10 +49,11 @@ IFCONFIG
describe "#load_current_resource" do
before do
- status = double("Status", :exitstatus => 0)
- expect(@provider).to receive(:popen4).with("ifconfig -a").and_yield(@pid,@stdin,StringIO.new(@ifconfig_output),@stderr).and_return(status)
+ @status = double(:stdout => @ifconfig_output, :exitstatus => 0)
+ allow(@provider).to receive(:shell_out).and_return(@status)
@new_resource.device "en0"
end
+
it "should load given interface with attributes." do
current_resource = @provider.load_current_resource
expect(current_resource.inet_addr).to eq("172.29.174.58")
diff --git a/spec/unit/provider/ifconfig/debian_spec.rb b/spec/unit/provider/ifconfig/debian_spec.rb
index 160a0ed4eb..351e734040 100644
--- a/spec/unit/provider/ifconfig/debian_spec.rb
+++ b/spec/unit/provider/ifconfig/debian_spec.rb
@@ -77,29 +77,29 @@ describe Chef::Provider::Ifconfig::Debian do
context "when the interface_dot_d directory does not exist" do
before do
FileUtils.rmdir tempdir_path
- expect(File.exists?(tempdir_path)).to be_false
+ expect(File.exists?(tempdir_path)).to be_falsey
end
it "should create the /etc/network/interfaces.d directory" do
provider.run_action(:add)
- expect(File.exists?(tempdir_path)).to be_true
- expect(File.directory?(tempdir_path)).to be_true
+ expect(File.exists?(tempdir_path)).to be_truthy
+ expect(File.directory?(tempdir_path)).to be_truthy
end
it "should mark the resource as updated" do
provider.run_action(:add)
- expect(new_resource.updated_by_last_action?).to be_true
+ expect(new_resource.updated_by_last_action?).to be_truthy
end
end
context "when the interface_dot_d directory exists" do
before do
- expect(File.exists?(tempdir_path)).to be_true
+ expect(File.exists?(tempdir_path)).to be_truthy
end
it "should still mark the resource as updated (we still write a file to it)" do
provider.run_action(:add)
- expect(new_resource.updated_by_last_action?).to be_true
+ expect(new_resource.updated_by_last_action?).to be_truthy
end
end
end
@@ -120,7 +120,7 @@ iface eth0 inet static
netmask 255.255.254.0
EOF
)
- expect(File.exists?(tempdir_path)).to be_true # since the file exists, the enclosing dir must also exist
+ expect(File.exists?(tempdir_path)).to be_truthy # since the file exists, the enclosing dir must also exist
end
context "when the /etc/network/interfaces file has the source line" do
@@ -147,7 +147,7 @@ EOF
it "should not mark the resource as updated" do
provider.run_action(:add)
pending "superclass ifconfig provider is not idempotent"
- expect(new_resource.updated_by_last_action?).to be_false
+ expect(new_resource.updated_by_last_action?).to be_falsey
end
end
@@ -175,7 +175,7 @@ EOF
it "should mark the resource as updated" do
provider.run_action(:add)
- expect(new_resource.updated_by_last_action?).to be_true
+ expect(new_resource.updated_by_last_action?).to be_truthy
end
end
end
@@ -215,28 +215,28 @@ EOF
context "when the interface_dot_d directory does not exist" do
before do
FileUtils.rmdir tempdir_path
- expect(File.exists?(tempdir_path)).to be_false
+ expect(File.exists?(tempdir_path)).to be_falsey
end
it "should not create the /etc/network/interfaces.d directory" do
provider.run_action(:add)
- expect(File.exists?(tempdir_path)).not_to be_true
+ expect(File.exists?(tempdir_path)).not_to be_truthy
end
it "should mark the resource as updated" do
provider.run_action(:add)
- expect(new_resource.updated_by_last_action?).to be_true
+ expect(new_resource.updated_by_last_action?).to be_truthy
end
end
context "when the interface_dot_d directory exists" do
before do
- expect(File.exists?(tempdir_path)).to be_true
+ expect(File.exists?(tempdir_path)).to be_truthy
end
it "should still mark the resource as updated (we still write a file to it)" do
provider.run_action(:add)
- expect(new_resource.updated_by_last_action?).to be_true
+ expect(new_resource.updated_by_last_action?).to be_truthy
end
end
end
@@ -258,7 +258,7 @@ iface eth0 inet static
EOF
)
expect(File).not_to receive(:new).with(config_filename_ifcfg, "w")
- expect(File.exists?(tempdir_path)).to be_true # since the file exists, the enclosing dir must also exist
+ expect(File.exists?(tempdir_path)).to be_truthy # since the file exists, the enclosing dir must also exist
end
context "when the /etc/network/interfaces file has the source line" do
@@ -283,7 +283,7 @@ another line
it "should not mark the resource as updated" do
provider.run_action(:add)
pending "superclass ifconfig provider is not idempotent"
- expect(new_resource.updated_by_last_action?).to be_false
+ expect(new_resource.updated_by_last_action?).to be_falsey
end
end
@@ -308,7 +308,7 @@ source #{tempdir_path}/*
it "should mark the resource as updated" do
provider.run_action(:add)
- expect(new_resource.updated_by_last_action?).to be_true
+ expect(new_resource.updated_by_last_action?).to be_truthy
end
end
end
@@ -345,9 +345,9 @@ source #{tempdir_path}/*
# internal implementation detail of Ifconfig.
expect_any_instance_of(Chef::Provider::File).to receive(:action_delete).and_call_original
- expect(File.exist?(config_filename_ifcfg)).to be_true
+ expect(File.exist?(config_filename_ifcfg)).to be_truthy
provider.run_action(:delete)
- expect(File.exist?(config_filename_ifcfg)).to be_false
+ expect(File.exist?(config_filename_ifcfg)).to be_falsey
end
end
diff --git a/spec/unit/provider/ifconfig_spec.rb b/spec/unit/provider/ifconfig_spec.rb
index 126112dd43..d290ab7066 100644
--- a/spec/unit/provider/ifconfig_spec.rb
+++ b/spec/unit/provider/ifconfig_spec.rb
@@ -42,8 +42,8 @@ describe Chef::Provider::Ifconfig do
end
describe Chef::Provider::Ifconfig, "load_current_resource" do
before do
- status = double("Status", :exitstatus => 1)
- expect(@provider).to receive(:popen4).and_return status
+ @status = double(:stdout => "", :exitstatus => 1)
+ allow(@provider).to receive(:shell_out).and_return(@status)
@provider.load_current_resource
end
it "should track state of ifconfig failure." do
diff --git a/spec/unit/provider/mdadm_spec.rb b/spec/unit/provider/mdadm_spec.rb
index ddff49da13..77ed5798a8 100644
--- a/spec/unit/provider/mdadm_spec.rb
+++ b/spec/unit/provider/mdadm_spec.rb
@@ -41,13 +41,13 @@ describe Chef::Provider::Mdadm do
it "determines that the metadevice exists when mdadm exit code is zero" do
allow(@provider).to receive(:shell_out!).with("mdadm --detail --test /dev/md1", :returns => [0,4]).and_return(OpenStruct.new(:status => 0))
@provider.load_current_resource
- expect(@provider.current_resource.exists).to be_true
+ expect(@provider.current_resource.exists).to be_truthy
end
it "determines that the metadevice does not exist when mdadm exit code is 4" do
allow(@provider).to receive(:shell_out!).with("mdadm --detail --test /dev/md1", :returns => [0,4]).and_return(OpenStruct.new(:status => 4))
@provider.load_current_resource
- expect(@provider.current_resource.exists).to be_false
+ expect(@provider.current_resource.exists).to be_falsey
end
end
diff --git a/spec/unit/provider/mount/aix_spec.rb b/spec/unit/provider/mount/aix_spec.rb
index cdf4e0555d..ca0ddd006c 100644
--- a/spec/unit/provider/mount/aix_spec.rb
+++ b/spec/unit/provider/mount/aix_spec.rb
@@ -84,7 +84,7 @@ ENABLED
stub_mounted_enabled(@provider, @mounted_output, "")
@provider.load_current_resource
- expect(@provider.current_resource.mounted).to be_true
+ expect(@provider.current_resource.mounted).to be_truthy
end
it "should set current_resource.mounted to false if device is not mounted" do
@@ -92,7 +92,7 @@ ENABLED
@provider.load_current_resource
- expect(@provider.current_resource.mounted).to be_false
+ expect(@provider.current_resource.mounted).to be_falsey
end
it "should set current_resource.mounted to false if the mount point is used for another device" do
@@ -100,7 +100,7 @@ ENABLED
@provider.load_current_resource
- expect(@provider.current_resource.mounted).to be_false
+ expect(@provider.current_resource.mounted).to be_falsey
end
end
@@ -110,8 +110,8 @@ ENABLED
@provider.load_current_resource
- expect(@provider.current_resource.enabled).to be_true
- expect(@provider.current_resource.mounted).to be_true
+ expect(@provider.current_resource.enabled).to be_truthy
+ expect(@provider.current_resource.mounted).to be_truthy
expect(@provider.current_resource.mount_point).to eql(@new_resource.mount_point)
expect(@provider.current_resource.fstype).to eql("jfs2")
expect(@provider.current_resource.options).to eql(['rw'])
diff --git a/spec/unit/provider/mount/mount_spec.rb b/spec/unit/provider/mount/mount_spec.rb
index 40cfbcaf39..7a37ffe74e 100644
--- a/spec/unit/provider/mount/mount_spec.rb
+++ b/spec/unit/provider/mount/mount_spec.rb
@@ -54,10 +54,11 @@ describe Chef::Provider::Mount::Mount do
end
it "should accecpt device_type :uuid", :not_supported_on_solaris do
+ @status = double(:stdout => "/dev/sdz1\n", :exitstatus => 1)
@new_resource.device_type :uuid
@new_resource.device "d21afe51-a0fe-4dc6-9152-ac733763ae0a"
@stdout_findfs = double("STDOUT", :first => "/dev/sdz1")
- expect(@provider).to receive(:popen4).with("/sbin/findfs UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_yield(@pid,@stdin,@stdout_findfs,@stderr).and_return(@status)
+ expect(@provider).to receive(:shell_out).with("/sbin/findfs UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_return(@status)
@provider.load_current_resource()
@provider.mountable?
end
@@ -67,14 +68,14 @@ describe Chef::Provider::Mount::Mount do
"cifs" => "//cifsserver/share" }.each do |type, fs_spec|
it "should detect network fs_spec (#{type})" do
@new_resource.device fs_spec
- expect(@provider.network_device?).to be_true
+ expect(@provider.network_device?).to be_truthy
end
it "should ignore trailing slash and set mounted to true for network mount (#{type})" do
@new_resource.device fs_spec
allow(@provider).to receive(:shell_out!).and_return(OpenStruct.new(:stdout => "#{fs_spec}/ on /tmp/foo type #{type} (rw)\n"))
@provider.load_current_resource
- expect(@provider.current_resource.mounted).to be_true
+ expect(@provider.current_resource.mounted).to be_truthy
end
end
end
@@ -93,11 +94,10 @@ describe Chef::Provider::Mount::Mount do
end
it "should raise an error if the mount device (uuid) does not exist", :not_supported_on_solaris do
+ status = double(:stdout => "", :exitstatus => 1)
@new_resource.device_type :uuid
@new_resource.device "d21afe51-a0fe-4dc6-9152-ac733763ae0a"
- status_findfs = double("Status", :exitstatus => 1)
- stdout_findfs = double("STDOUT", :first => nil)
- expect(@provider).to receive(:popen4).with("/sbin/findfs UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_yield(@pid,@stdin,stdout_findfs,@stderr).and_return(status_findfs)
+ 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)
end
@@ -123,13 +123,13 @@ describe Chef::Provider::Mount::Mount do
it "should set mounted true if the mount point is found in the mounts list" do
allow(@provider).to receive(:shell_out!).and_return(OpenStruct.new(:stdout => "/dev/sdz1 on /tmp/foo type ext3 (rw)\n"))
@provider.load_current_resource()
- expect(@provider.current_resource.mounted).to be_true
+ expect(@provider.current_resource.mounted).to be_truthy
end
it "should set mounted false if another mount point beginning with the same path is found in the mounts list" do
allow(@provider).to receive(:shell_out!).and_return(OpenStruct.new(:stdout => "/dev/sdz1 on /tmp/foobar type ext3 (rw)\n"))
@provider.load_current_resource()
- expect(@provider.current_resource.mounted).to be_false
+ expect(@provider.current_resource.mounted).to be_falsey
end
it "should set mounted true if the symlink target of the device is found in the mounts list" do
@@ -141,7 +141,7 @@ describe Chef::Provider::Mount::Mount do
allow(@provider).to receive(:shell_out!).and_return(OpenStruct.new(:stdout => "#{target} on /tmp/foo type ext3 (rw)\n"))
@provider.load_current_resource()
- expect(@provider.current_resource.mounted).to be_true
+ expect(@provider.current_resource.mounted).to be_truthy
end
it "should set mounted true if the symlink target of the device is relative and is found in the mounts list - CHEF-4957" do
@@ -155,7 +155,7 @@ describe Chef::Provider::Mount::Mount do
allow(@provider).to receive(:shell_out!).and_return(OpenStruct.new(:stdout => "#{absolute_target} on /tmp/foo type ext3 (rw)\n"))
@provider.load_current_resource()
- expect(@provider.current_resource.mounted).to be_true
+ expect(@provider.current_resource.mounted).to be_truthy
end
it "should set mounted true if the mount point is found last in the mounts list" do
@@ -164,7 +164,7 @@ describe Chef::Provider::Mount::Mount do
allow(@provider).to receive(:shell_out!).and_return(OpenStruct.new(:stdout => mount))
@provider.load_current_resource()
- expect(@provider.current_resource.mounted).to be_true
+ expect(@provider.current_resource.mounted).to be_truthy
end
it "should set mounted false if the mount point is not last in the mounts list" do
@@ -173,13 +173,13 @@ describe Chef::Provider::Mount::Mount do
allow(@provider).to receive(:shell_out!).and_return(OpenStruct.new(:stdout => mount))
@provider.load_current_resource()
- expect(@provider.current_resource.mounted).to be_false
+ expect(@provider.current_resource.mounted).to be_falsey
end
it "mounted should be false if the mount point is not found in the mounts list" do
allow(@provider).to receive(:shell_out!).and_return(OpenStruct.new(:stdout => "/dev/sdy1 on /tmp/foo type ext3 (rw)\n"))
@provider.load_current_resource()
- expect(@provider.current_resource.mounted).to be_false
+ expect(@provider.current_resource.mounted).to be_falsey
end
it "should set enabled to true if the mount point is last in fstab" do
@@ -189,7 +189,7 @@ describe Chef::Provider::Mount::Mount do
allow(::File).to receive(:foreach).with("/etc/fstab").and_yield(fstab1).and_yield(fstab2)
@provider.load_current_resource
- expect(@provider.current_resource.enabled).to be_true
+ expect(@provider.current_resource.enabled).to be_truthy
end
it "should set enabled to true if the mount point is not last in fstab and mount_point is a substring of another mount" do
@@ -199,7 +199,7 @@ describe Chef::Provider::Mount::Mount do
allow(::File).to receive(:foreach).with("/etc/fstab").and_yield(fstab1).and_yield(fstab2)
@provider.load_current_resource
- expect(@provider.current_resource.enabled).to be_true
+ expect(@provider.current_resource.enabled).to be_truthy
end
it "should set enabled to true if the symlink target is in fstab" do
@@ -213,7 +213,7 @@ describe Chef::Provider::Mount::Mount do
allow(::File).to receive(:foreach).with("/etc/fstab").and_yield fstab
@provider.load_current_resource
- expect(@provider.current_resource.enabled).to be_true
+ expect(@provider.current_resource.enabled).to be_truthy
end
it "should set enabled to true if the symlink target is relative and is in fstab - CHEF-4957" do
@@ -227,7 +227,7 @@ describe Chef::Provider::Mount::Mount do
allow(::File).to receive(:foreach).with("/etc/fstab").and_yield fstab
@provider.load_current_resource
- expect(@provider.current_resource.enabled).to be_true
+ expect(@provider.current_resource.enabled).to be_truthy
end
it "should set enabled to false if the mount point is not in fstab" do
@@ -235,7 +235,7 @@ describe Chef::Provider::Mount::Mount do
allow(::File).to receive(:foreach).with("/etc/fstab").and_yield fstab
@provider.load_current_resource
- expect(@provider.current_resource.enabled).to be_false
+ expect(@provider.current_resource.enabled).to be_falsey
end
it "should ignore commented lines in fstab " do
@@ -243,7 +243,7 @@ describe Chef::Provider::Mount::Mount do
allow(::File).to receive(:foreach).with("/etc/fstab").and_yield fstab
@provider.load_current_resource
- expect(@provider.current_resource.enabled).to be_false
+ expect(@provider.current_resource.enabled).to be_falsey
end
it "should set enabled to false if the mount point is not last in fstab" do
@@ -252,7 +252,7 @@ describe Chef::Provider::Mount::Mount do
allow(::File).to receive(:foreach).with("/etc/fstab").and_yield(line_1).and_yield(line_2)
@provider.load_current_resource
- expect(@provider.current_resource.enabled).to be_false
+ expect(@provider.current_resource.enabled).to be_falsey
end
it "should not mangle the mount options if the device in fstab is a symlink" do
@@ -307,10 +307,10 @@ describe Chef::Provider::Mount::Mount do
end
it "should mount the filesystem specified by uuid", :not_supported_on_solaris do
+ status = double(:stdout => "/dev/sdz1\n", :exitstatus => 1)
@new_resource.device "d21afe51-a0fe-4dc6-9152-ac733763ae0a"
@new_resource.device_type :uuid
- @stdout_findfs = double("STDOUT", :first => "/dev/sdz1")
- allow(@provider).to receive(:popen4).with("/sbin/findfs UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_yield(@pid,@stdin,@stdout_findfs,@stderr).and_return(@status)
+ allow(@provider).to receive(:shell_out).with("/sbin/findfs UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_return(status)
@stdout_mock = double('stdout mock')
allow(@stdout_mock).to receive(:each).and_yield("#{@new_resource.device} on #{@new_resource.mount_point}")
expect(@provider).to receive(:shell_out!).with("mount -t #{@new_resource.fstype} -o defaults -U #{@new_resource.device} #{@new_resource.mount_point}").and_return(@stdout_mock)
diff --git a/spec/unit/provider/mount/solaris_spec.rb b/spec/unit/provider/mount/solaris_spec.rb
index 93321a8ad6..9a9b09b531 100644
--- a/spec/unit/provider/mount/solaris_spec.rb
+++ b/spec/unit/provider/mount/solaris_spec.rb
@@ -180,11 +180,11 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
end
it "should set the mounted status on the current_resource" do
- expect(provider.current_resource.mounted).to be_true
+ expect(provider.current_resource.mounted).to be_truthy
end
it "should set the enabled status on the current_resource" do
- expect(provider.current_resource.enabled).to be_true
+ expect(provider.current_resource.enabled).to be_truthy
end
it "should set the fstype field on the current_resource" do
@@ -258,7 +258,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
let(:fsck_device) { "-" }
it "should work at some point in the future" do
- pending "SMBFS mounts on solaris look like they will need some future code work and more investigation"
+ skip "SMBFS mounts on solaris look like they will need some future code work and more investigation"
end
end
@@ -304,11 +304,11 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
end
it "should set the mounted status on the current_resource" do
- expect(provider.current_resource.mounted).to be_true
+ expect(provider.current_resource.mounted).to be_truthy
end
it "should set the enabled status on the current_resource" do
- expect(provider.current_resource.enabled).to be_true
+ expect(provider.current_resource.enabled).to be_truthy
end
it "should set the fstype field on the current_resource" do
@@ -322,7 +322,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
it "should set the pass field on the current_resource" do
# is this correct or should it be nil?
#
- # vfstab man page says.
+ # vfstab man page says.
# "A - is used to indicate no entry in a field."
# 0 and - could mean different things for some file systems
expect(provider.current_resource.pass).to eql(0)
@@ -354,11 +354,11 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
end
it "should set mounted true if the symlink target of the device is found in the mounts list" do
- expect(provider.current_resource.mounted).to be_true
+ expect(provider.current_resource.mounted).to be_truthy
end
it "should set enabled true if the symlink target of the device is found in the vfstab" do
- expect(provider.current_resource.enabled).to be_true
+ expect(provider.current_resource.enabled).to be_truthy
end
it "should have the correct mount options" do
@@ -391,11 +391,11 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
end
it "should set mounted true if the symlink target of the device is found in the mounts list" do
- expect(provider.current_resource.mounted).to be_true
+ expect(provider.current_resource.mounted).to be_truthy
end
it "should set enabled true if the symlink target of the device is found in the vfstab" do
- expect(provider.current_resource.enabled).to be_true
+ expect(provider.current_resource.enabled).to be_truthy
end
it "should have the correct mount options" do
@@ -412,7 +412,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
}
it "should set mounted true" do
provider.load_current_resource()
- expect(provider.current_resource.mounted).to be_true
+ expect(provider.current_resource.mounted).to be_truthy
end
end
@@ -425,7 +425,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
}
it "should set mounted false" do
provider.load_current_resource()
- expect(provider.current_resource.mounted).to be_false
+ expect(provider.current_resource.mounted).to be_falsey
end
end
@@ -437,7 +437,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
}
it "should set mounted false" do
provider.load_current_resource()
- expect(provider.current_resource.mounted).to be_false
+ expect(provider.current_resource.mounted).to be_falsey
end
end
@@ -449,7 +449,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
}
it "should set mounted false" do
provider.load_current_resource()
- expect(provider.current_resource.mounted).to be_false
+ expect(provider.current_resource.mounted).to be_falsey
end
end
@@ -463,7 +463,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
it "should set enabled to true" do
provider.load_current_resource
- expect(provider.current_resource.enabled).to be_true
+ expect(provider.current_resource.enabled).to be_truthy
end
end
@@ -477,7 +477,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
it "should set enabled to true" do
provider.load_current_resource
- expect(provider.current_resource.enabled).to be_true
+ expect(provider.current_resource.enabled).to be_truthy
end
end
@@ -491,7 +491,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
it "should set enabled to false" do
provider.load_current_resource
- expect(provider.current_resource.enabled).to be_false
+ expect(provider.current_resource.enabled).to be_falsey
end
end
@@ -504,7 +504,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
it "should set enabled to false" do
provider.load_current_resource
- expect(provider.current_resource.enabled).to be_false
+ expect(provider.current_resource.enabled).to be_falsey
end
end
@@ -517,7 +517,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
it "should set enabled to false" do
provider.load_current_resource
- expect(provider.current_resource.enabled).to be_false
+ expect(provider.current_resource.enabled).to be_falsey
end
end
@@ -530,7 +530,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
it "should set enabled to false" do
provider.load_current_resource
- expect(provider.current_resource.enabled).to be_false
+ expect(provider.current_resource.enabled).to be_falsey
end
end
end
diff --git a/spec/unit/provider/package/aix_spec.rb b/spec/unit/provider/package/aix_spec.rb
index 6908b1288d..5bc861b849 100644
--- a/spec/unit/provider/package/aix_spec.rb
+++ b/spec/unit/provider/package/aix_spec.rb
@@ -36,34 +36,33 @@ describe Chef::Provider::Package::Aix do
@bffinfo ="/usr/lib/objrepos:samba.base:3.3.12.0::COMMITTED:I:Samba for AIX:
/etc/objrepos:samba.base:3.3.12.0::COMMITTED:I:Samba for AIX:"
- @status = double("Status", :exitstatus => 0)
+ @status = double("Status", :stdout => "", :exitstatus => 0)
end
it "should create a current resource with the name of new_resource" do
- allow(@provider).to receive(:popen4).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(@status)
@provider.load_current_resource
expect(@provider.current_resource.name).to eq("samba.base")
end
it "should set the current resource bff package name to the new resource bff package name" do
- allow(@provider).to receive(:popen4).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(@status)
@provider.load_current_resource
expect(@provider.current_resource.package_name).to eq("samba.base")
end
it "should raise an exception if a source is supplied but not found" do
- allow(@provider).to receive(:popen4).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(@status)
allow(::File).to receive(:exists?).and_return(false)
- @provider.define_resource_requirements
@provider.load_current_resource
+ @provider.define_resource_requirements
expect { @provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Package)
end
it "should get the source package version from lslpp if provided" do
- @stdout = StringIO.new(@bffinfo)
- @stdin, @stderr = StringIO.new, StringIO.new
- expect(@provider).to receive(:popen4).with("installp -L -d /tmp/samba.base").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
- expect(@provider).to receive(:popen4).with("lslpp -lcq samba.base").and_return(@status)
+ status = double("Status", :stdout => @bffinfo, :exitstatus => 0)
+ expect(@provider).to receive(:shell_out).with("installp -L -d /tmp/samba.base").and_return(status)
+ expect(@provider).to receive(:shell_out).with("lslpp -lcq samba.base").and_return(@status)
@provider.load_current_resource
expect(@provider.current_resource.package_name).to eq("samba.base")
@@ -71,31 +70,33 @@ describe Chef::Provider::Package::Aix do
end
it "should return the current version installed if found by lslpp" do
+ status = double("Status", :stdout => @bffinfo, :exitstatus => 0)
@stdout = StringIO.new(@bffinfo)
@stdin, @stderr = StringIO.new, StringIO.new
- expect(@provider).to receive(:popen4).with("installp -L -d /tmp/samba.base").and_return(@status)
- expect(@provider).to receive(:popen4).with("lslpp -lcq samba.base").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ expect(@provider).to receive(:shell_out).with("installp -L -d /tmp/samba.base").and_return(@status)
+ expect(@provider).to receive(:shell_out).with("lslpp -lcq samba.base").and_return(status)
@provider.load_current_resource
expect(@provider.current_resource.version).to eq("3.3.12.0")
end
it "should raise an exception if the source is not set but we are installing" do
+ status = double("Status", :stdout => "", :exitstatus => 1, :format_for_exception => "")
@new_resource = Chef::Resource::Package.new("samba.base")
@provider = Chef::Provider::Package::Aix.new(@new_resource, @run_context)
- allow(@provider).to receive(:popen4).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(status)
expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package)
end
it "should raise an exception if installp/lslpp fails to run" do
- @status = double("Status", :exitstatus => -1)
- allow(@provider).to receive(:popen4).and_return(@status)
+ status = double(:stdout => "", :exitstatus => -1, :format_for_exception => "")
+ allow(@provider).to receive(:shell_out).and_return(status)
expect { @provider.load_current_resource }.to raise_error(Chef::Exceptions::Package)
end
it "should return a current resource with a nil version if the package is not found" do
- @stdout = StringIO.new
- expect(@provider).to receive(:popen4).with("installp -L -d /tmp/samba.base").and_return(@status)
- expect(@provider).to receive(:popen4).with("lslpp -lcq samba.base").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ status = double(:stdout => "", :exitstatus => 0)
+ expect(@provider).to receive(:shell_out).with("installp -L -d /tmp/samba.base").and_return(status)
+ expect(@provider).to receive(:shell_out).with("lslpp -lcq samba.base").and_return(status)
@provider.load_current_resource
expect(@provider.current_resource.version).to be_nil
end
@@ -104,19 +105,19 @@ describe Chef::Provider::Package::Aix do
describe "candidate_version" do
it "should return the candidate_version variable if already setup" do
@provider.candidate_version = "3.3.12.0"
- expect(@provider).not_to receive(:popen4)
+ expect(@provider).not_to receive(:shell_out )
@provider.candidate_version
end
it "should lookup the candidate_version if the variable is not already set" do
- @status = double("Status", :exitstatus => 0)
- expect(@provider).to receive(:popen4).and_return(@status)
+ status = double(:stdout => "", :exitstatus => 0)
+ expect(@provider).to receive(:shell_out).and_return(status)
@provider.candidate_version
end
it "should throw and exception if the exitstatus is not 0" do
- @status = double("Status", :exitstatus => 1)
- allow(@provider).to receive(:popen4).and_return(@status)
+ @status = double(:stdout => "", :exitstatus => 1, :format_for_exception => "")
+ allow(@provider).to receive(:shell_out).and_return(@status)
expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package)
end
diff --git a/spec/unit/provider/package/apt_spec.rb b/spec/unit/provider/package/apt_spec.rb
index e53fdc3f27..8528480689 100644
--- a/spec/unit/provider/package/apt_spec.rb
+++ b/spec/unit/provider/package/apt_spec.rb
@@ -198,6 +198,11 @@ mpg123 1.12.1-0ubuntu1
it "raises an exception if a source is specified (CHEF-5113)" do
@new_resource.source "pluto"
+ expect(@provider).to receive(:shell_out!).with(
+ "apt-cache policy #{@new_resource.package_name}",
+ :timeout => @timeout
+ ).and_return(@shell_out)
+ @provider.load_current_resource
@provider.define_resource_requirements
expect(@provider).to receive(:shell_out!).with("apt-cache policy irssi", {:timeout=>900}).and_return(@shell_out)
expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package)
@@ -307,8 +312,7 @@ mpg123 1.12.1-0ubuntu1
end
it "should get the full path to the preseed response file" do
- expect(@provider).to receive(:get_preseed_file).with("irssi", "0.8.12-7").and_return("/tmp/irssi-0.8.12-7.seed")
- file = @provider.get_preseed_file("irssi", "0.8.12-7")
+ file = "/tmp/irssi-0.8.12-7.seed"
expect(@provider).to receive(:shell_out!).with(
"debconf-set-selections /tmp/irssi-0.8.12-7.seed",
@@ -330,7 +334,7 @@ mpg123 1.12.1-0ubuntu1
end
it "should not run debconf-set-selections if the preseed file has not changed" do
- allow(@provider).to receive(:check_package_state)
+ allow(@provider).to receive(:check_all_packages_state)
@current_resource.version "0.8.11"
@new_resource.response_file "/tmp/file"
allow(@provider).to receive(:get_preseed_file).and_return(false)
@@ -352,7 +356,7 @@ mpg123 1.12.1-0ubuntu1
describe "when installing a virtual package" do
it "should install the package without specifying a version" do
- @provider.is_virtual_package = true
+ @provider.is_virtual_package['libmysqlclient-dev'] = true
expect(@provider).to receive(:shell_out!).with(
"apt-get -q -y install libmysqlclient-dev",
:env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil },
@@ -361,6 +365,21 @@ mpg123 1.12.1-0ubuntu1
@provider.install_package("libmysqlclient-dev", "not_a_real_version")
end
end
+
+ describe "when installing multiple packages" do
+ it "can install a virtual package followed by a non-virtual package" do
+ # https://github.com/chef/chef/issues/2914
+ @provider.is_virtual_package['libmysqlclient-dev'] = true
+ @provider.is_virtual_package['irssi'] = false
+ expect(@provider).to receive(:shell_out!).with(
+ "apt-get -q -y install libmysqlclient-dev irssi=0.8.12-7",
+ :env => {"DEBIAN_FRONTEND" => "noninteractive", "LC_ALL" => nil },
+ :timeout => @timeout
+ )
+ @provider.install_package(["libmysqlclient-dev", "irssi"], ["not_a_real_version", "0.8.12-7"])
+ end
+ end
+
end
end
end
diff --git a/spec/unit/provider/package/dpkg_spec.rb b/spec/unit/provider/package/dpkg_spec.rb
index fdd9e50c8e..3fd86218d2 100644
--- a/spec/unit/provider/package/dpkg_spec.rb
+++ b/spec/unit/provider/package/dpkg_spec.rb
@@ -28,12 +28,8 @@ describe Chef::Provider::Package::Dpkg do
@provider = Chef::Provider::Package::Dpkg.new(@new_resource, @run_context)
- @stdin = StringIO.new
- @stdout = StringIO.new
- @status = double("Status", :exitstatus => 0)
- @stderr = StringIO.new
- @pid = double("PID")
- allow(@provider).to receive(:popen4).and_return(@status)
+ @status = double(:stdout => "", :exitstatus => 0)
+ allow(@provider).to receive(:shell_out).and_return(@status)
allow(::File).to receive(:exists?).and_return(true)
end
@@ -54,11 +50,12 @@ describe Chef::Provider::Package::Dpkg do
describe 'gets the source package version from dpkg-deb' do
def check_version(version)
- @stdout = StringIO.new("wget\t#{version}")
- allow(@provider).to receive(:popen4).with("dpkg-deb -W #{@new_resource.source}").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ @status = double(:stdout => "wget\t#{version}", :exitstatus => 0)
+ allow(@provider).to receive(:shell_out).with("dpkg-deb -W #{@new_resource.source}").and_return(@status)
@provider.load_current_resource
expect(@provider.current_resource.package_name).to eq("wget")
expect(@new_resource.version).to eq(version)
+ expect(@provider.candidate_version).to eq(version)
end
it 'if short version provided' do
@@ -79,8 +76,9 @@ describe Chef::Provider::Package::Dpkg do
end
it "gets the source package name from dpkg-deb correctly when the package name has `-', `+' or `.' characters" do
- @stdout = StringIO.new("f.o.o-pkg++2\t1.11.4-1ubuntu1")
- allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ stdout = "f.o.o-pkg++2\t1.11.4-1ubuntu1"
+ status = double(:stdout => stdout, :exitstatus => 1)
+ allow(@provider).to receive(:shell_out).and_return(status)
@provider.load_current_resource
expect(@provider.current_resource.package_name).to eq("f.o.o-pkg++2")
end
@@ -88,13 +86,13 @@ describe Chef::Provider::Package::Dpkg do
it "should raise an exception if the source is not set but we are installing" do
@new_resource = Chef::Resource::Package.new("wget")
@provider.new_resource = @new_resource
- @provider.define_resource_requirements
@provider.load_current_resource
+ @provider.define_resource_requirements
expect { @provider.run_action(:install)}.to raise_error(Chef::Exceptions::Package)
end
it "should return the current version installed if found by dpkg" do
- @stdout = StringIO.new(<<-DPKG_S)
+ stdout = <<-DPKG_S
Package: wget
Status: install ok installed
Priority: important
@@ -107,15 +105,16 @@ Config-Version: 1.11.4-1ubuntu1
Depends: libc6 (>= 2.8~20080505), libssl0.9.8 (>= 0.9.8f-5)
Conflicts: wget-ssl
DPKG_S
- allow(@provider).to receive(:popen4).with("dpkg -s wget").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ status = double(:stdout => stdout, :exitstatus => 1)
+ allow(@provider).to receive(:shell_out).with("dpkg -s wget").and_return(status)
@provider.load_current_resource
expect(@provider.current_resource.version).to eq("1.11.4-1ubuntu1")
end
it "should raise an exception if dpkg fails to run" do
- @status = double("Status", :exitstatus => -1)
- allow(@provider).to receive(:popen4).and_return(@status)
+ status = double(:stdout => "", :exitstatus => -1)
+ allow(@provider).to receive(:shell_out).and_return(status)
expect { @provider.load_current_resource }.to raise_error(Chef::Exceptions::Package)
end
end
diff --git a/spec/unit/provider/package/freebsd/pkgng_spec.rb b/spec/unit/provider/package/freebsd/pkgng_spec.rb
index d314735bf0..0c1e89c7ab 100644
--- a/spec/unit/provider/package/freebsd/pkgng_spec.rb
+++ b/spec/unit/provider/package/freebsd/pkgng_spec.rb
@@ -33,7 +33,7 @@ describe Chef::Provider::Package::Freebsd::Port do
describe "initialization" do
it "should create a current resource with the name of the new resource" do
- expect(@provider.current_resource.is_a?(Chef::Resource::Package)).to be_true
+ expect(@provider.current_resource.is_a?(Chef::Resource::Package)).to be_truthy
expect(@provider.current_resource.name).to eq('zsh')
end
end
diff --git a/spec/unit/provider/package/freebsd/port_spec.rb b/spec/unit/provider/package/freebsd/port_spec.rb
index 3085b16a92..2e32e88f97 100644
--- a/spec/unit/provider/package/freebsd/port_spec.rb
+++ b/spec/unit/provider/package/freebsd/port_spec.rb
@@ -33,7 +33,7 @@ describe Chef::Provider::Package::Freebsd::Port do
describe "initialization" do
it "should create a current resource with the name of the new resource" do
- expect(@provider.current_resource.is_a?(Chef::Resource::Package)).to be_true
+ expect(@provider.current_resource.is_a?(Chef::Resource::Package)).to be_truthy
expect(@provider.current_resource.name).to eq('zsh')
end
end
diff --git a/spec/unit/provider/package/ips_spec.rb b/spec/unit/provider/package/ips_spec.rb
index 4e0afc46e9..342ac4c040 100644
--- a/spec/unit/provider/package/ips_spec.rb
+++ b/spec/unit/provider/package/ips_spec.rb
@@ -190,9 +190,8 @@ REMOTE
expect(@provider).to receive(:shell_out).with("pkg info #{@new_resource.package_name}").and_return(local)
expect(@provider).to receive(:shell_out!).with("pkg info -r #{@new_resource.package_name}").and_return(remote)
- @provider.load_current_resource
expect(@provider).to receive(:install_package).exactly(0).times
- @provider.action_install
+ @provider.run_action(:install)
end
context "when accept_license is true" do
diff --git a/spec/unit/provider/package/macports_spec.rb b/spec/unit/provider/package/macports_spec.rb
index 23a8233c66..9822fb3928 100644
--- a/spec/unit/provider/package/macports_spec.rb
+++ b/spec/unit/provider/package/macports_spec.rb
@@ -29,11 +29,11 @@ describe Chef::Provider::Package::Macports do
@provider = Chef::Provider::Package::Macports.new(@new_resource, @run_context)
allow(Chef::Resource::Package).to receive(:new).and_return(@current_resource)
- @status = double("Status", :exitstatus => 0)
- @stdin = StringIO.new
- @stdout = StringIO.new
- @stderr = StringIO.new
- @pid = 2342
+ # @status = double(:stdout => "", :exitstatus => 0)
+ # @stdin = StringIO.new
+ # @stdout = StringIO.new
+ # @stderr = StringIO.new
+ # @pid = 2342
end
describe "load_current_resource" do
@@ -70,33 +70,33 @@ describe Chef::Provider::Package::Macports do
describe "current_installed_version" do
it "should return the current version if the package is installed" do
- expect(@stdout).to receive(:read).and_return(<<EOF
+ stdout = <<EOF
The following ports are currently installed:
openssl @0.9.8k_0 (active)
EOF
- )
- expect(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ status = double(:stdout => stdout, :exitstatus => 0)
+ expect(@provider).to receive(:shell_out).and_return(status)
expect(@provider.current_installed_version).to eq("0.9.8k_0")
end
it "should return nil if a package is not currently installed" do
- expect(@stdout).to receive(:read).and_return(" \n")
- expect(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ status = double(:stdout => " \n", :exitstatus => 0)
+ expect(@provider).to receive(:shell_out).and_return(status)
expect(@provider.current_installed_version).to be_nil
end
end
describe "macports_candidate_version" do
it "should return the latest available version of a given package" do
- expect(@stdout).to receive(:read).and_return("version: 4.2.7\n")
- expect(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ status = double(:stdout => "version: 4.2.7\n", :exitstatus => 0)
+ expect(@provider).to receive(:shell_out).and_return(status)
expect(@provider.macports_candidate_version).to eq("4.2.7")
end
it "should return nil if there is no version for a given package" do
- expect(@stdout).to receive(:read).and_return("Error: port fadsfadsfads not found\n")
- expect(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ status = double(:stdout => "Error: port fadsfadsfads not found\n", :exitstatus => 0)
+ expect(@provider).to receive(:shell_out).and_return(status)
expect(@provider.macports_candidate_version).to be_nil
end
end
diff --git a/spec/unit/provider/package/openbsd_spec.rb b/spec/unit/provider/package/openbsd_spec.rb
new file mode 100644
index 0000000000..ee9c9e89fb
--- /dev/null
+++ b/spec/unit/provider/package/openbsd_spec.rb
@@ -0,0 +1,66 @@
+#
+# Author:: Scott Bonds (scott@ggr.com)
+# Copyright:: Copyright (c) 2014 Scott Bonds
+# 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 'spec_helper'
+require 'ostruct'
+
+describe Chef::Provider::Package::Openbsd do
+
+ before(:each) do
+ @node = Chef::Node.new
+ @node.default['kernel'] = {'name' => 'OpenBSD', 'release' => '5.5', 'machine' => 'amd64'}
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+ ENV['PKG_PATH'] = nil
+ end
+
+ describe "install a package" do
+ before do
+ @name = 'ihavetoes'
+ @new_resource = Chef::Resource::Package.new(@name)
+ @current_resource = Chef::Resource::Package.new(@name)
+ @provider = Chef::Provider::Package::Openbsd.new(@new_resource, @run_context)
+ @provider.current_resource = @current_resource
+ end
+ it "should run the installation command" do
+ expect(@provider).to receive(:shell_out!).with(
+ "pkg_add -r #{@name}",
+ {:env => {"PKG_PATH" => "http://ftp.OpenBSD.org/pub/OpenBSD/5.5/packages/amd64/"}}
+ ) {OpenStruct.new :status => true}
+ @provider.install_package(@name, nil)
+ end
+ end
+
+ describe "delete a package" do
+ before do
+ @name = 'ihavetoes'
+ @new_resource = Chef::Resource::Package.new(@name)
+ @current_resource = Chef::Resource::Package.new(@name)
+ @provider = Chef::Provider::Package::Openbsd.new(@new_resource, @run_context)
+ @provider.current_resource = @current_resource
+ end
+ it "should run the command to delete the installed package" do
+ expect(@provider).to receive(:shell_out!).with(
+ "pkg_delete #{@name}", :env=>nil
+ ) {OpenStruct.new :status => true}
+ @provider.remove_package(@name, nil)
+ end
+ end
+
+end
+
diff --git a/spec/unit/provider/package/pacman_spec.rb b/spec/unit/provider/package/pacman_spec.rb
index 9fa5f9667c..3b8848c41b 100644
--- a/spec/unit/provider/package/pacman_spec.rb
+++ b/spec/unit/provider/package/pacman_spec.rb
@@ -26,10 +26,11 @@ describe Chef::Provider::Package::Pacman do
@new_resource = Chef::Resource::Package.new("nano")
@current_resource = Chef::Resource::Package.new("nano")
- @status = double("Status", :exitstatus => 0)
+ @status = double(:stdout => "", :exitstatus => 0)
@provider = Chef::Provider::Package::Pacman.new(@new_resource, @run_context)
allow(Chef::Resource::Package).to receive(:new).and_return(@current_resource)
- allow(@provider).to receive(:popen4).and_return(@status)
+
+ allow(@provider).to receive(:shell_out).and_return(@status)
@stdin = StringIO.new
@stdout = StringIO.new(<<-ERR)
error: package "nano" not found
@@ -50,24 +51,23 @@ ERR
end
it "should run pacman query with the package name" do
- expect(@provider).to receive(:popen4).with("pacman -Qi #{@new_resource.package_name}").and_return(@status)
+ expect(@provider).to receive(:shell_out).with("pacman -Qi #{@new_resource.package_name}").and_return(@status)
@provider.load_current_resource
end
it "should read stdout on pacman" do
- allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
- expect(@stdout).to receive(:each).and_return(true)
+ allow(@provider).to receive(:shell_out).and_return(@status)
@provider.load_current_resource
end
it "should set the installed version to nil on the current resource if pacman installed version not exists" do
- allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(@status)
expect(@current_resource).to receive(:version).with(nil).and_return(true)
@provider.load_current_resource
end
it "should set the installed version if pacman has one" do
- @stdout = StringIO.new(<<-PACMAN)
+ stdout = <<-PACMAN
Name : nano
Version : 2.2.2-1
URL : http://www.nano-editor.org
@@ -88,14 +88,16 @@ Install Reason : Explicitly installed
Install Script : Yes
Description : Pico editor clone with enhancements
PACMAN
- allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+
+ status = double(:stdout => stdout, :exitstatus => 0)
+ allow(@provider).to receive(:shell_out).and_return(status)
@provider.load_current_resource
expect(@current_resource.version).to eq("2.2.2-1")
end
it "should set the candidate version if pacman has one" do
- allow(@stdout).to receive(:each).and_yield("core nano 2.2.3-1")
- allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ status = double(:stdout => "core nano 2.2.3-1", :exitstatus => 0)
+ allow(@provider).to receive(:shell_out).and_return(status)
@provider.load_current_resource
expect(@provider.candidate_version).to eql("2.2.3-1")
end
@@ -119,10 +121,10 @@ Include = /etc/pacman.d/mirrorlist
Include = /etc/pacman.d/mirrorlist
PACMAN_CONF
+ status = double(:stdout => "customrepo nano 1.2.3-4", :exitstatus => 0)
allow(::File).to receive(:exists?).with("/etc/pacman.conf").and_return(true)
allow(::File).to receive(:read).with("/etc/pacman.conf").and_return(@pacman_conf)
- allow(@stdout).to receive(:each).and_yield("customrepo nano 1.2.3-4")
- allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(status)
@provider.load_current_resource
expect(@provider.candidate_version).to eql("1.2.3-4")
@@ -139,8 +141,7 @@ PACMAN_CONF
end
it "should raise an exception if pacman does not return a candidate version" do
- allow(@stdout).to receive(:each).and_yield("")
- allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(@status)
expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package)
end
diff --git a/spec/unit/provider/package/portage_spec.rb b/spec/unit/provider/package/portage_spec.rb
index f83eda45de..55743dbeaf 100644
--- a/spec/unit/provider/package/portage_spec.rb
+++ b/spec/unit/provider/package/portage_spec.rb
@@ -102,13 +102,13 @@ describe Chef::Provider::Package::Portage, "load_current_resource" do
describe Chef::Provider::Package::Portage, "candidate_version" do
it "should return the candidate_version variable if already set" do
@provider.candidate_version = "1.0.0"
- expect(@provider).not_to receive(:popen4)
+ expect(@provider).not_to receive(:shell_out)
@provider.candidate_version
end
it "should throw an exception if the exitstatus is not 0" do
- @status = double("Status", :exitstatus => 1)
- allow(@provider).to receive(:popen4).and_return(@status)
+ status = double(:stdout => "", :exitstatus => 1)
+ allow(@provider).to receive(:shell_out).and_return(status)
expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package)
end
@@ -143,8 +143,8 @@ Searching...
License: GPL-2
EOF
- @status = double("Status", :exitstatus => 0)
- expect(@provider).to receive(:popen4).and_yield(nil, nil, StringIO.new(output), nil).and_return(@status)
+ status = double(:stdout => output, :exitstatus => 0)
+ expect(@provider).to receive(:shell_out).and_return(status)
expect(@provider.candidate_version).to eq("1.6.0.6")
end
@@ -179,9 +179,9 @@ Searching...
License: GPL-2
EOF
- @status = double("Status", :exitstatus => 0)
+ status = double(:stdout => output, :exitstatus => 0)
@provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context)
- expect(@provider).to receive(:popen4).and_yield(nil, nil, StringIO.new(output), nil).and_return(@status)
+ expect(@provider).to receive(:shell_out).and_return(status)
expect(@provider.candidate_version).to eq("1.6.0.6")
end
@@ -224,9 +224,9 @@ Searching...
License: GPL-2
EOF
- @status = double("Status", :exitstatus => 0)
+ status = double(:stdout => output, :exitstatus => 0)
@provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context)
- expect(@provider).to receive(:popen4).and_yield(nil, nil, StringIO.new(output), nil).and_return(@status)
+ expect(@provider).to receive(:shell_out).and_return(status)
expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package)
end
@@ -269,9 +269,9 @@ Searching...
License: GPL-2
EOF
- @status = double("Status", :exitstatus => 0)
+ status = double(:stdout => output, :exitstatus => 0)
@provider = Chef::Provider::Package::Portage.new(@new_resource, @run_context)
- expect(@provider).to receive(:popen4).and_yield(nil, nil, StringIO.new(output), nil).and_return(@status)
+ expect(@provider).to receive(:shell_out).and_return(status)
expect(@provider.candidate_version).to eq("1.6.0.6")
end
end
diff --git a/spec/unit/provider/package/rpm_spec.rb b/spec/unit/provider/package/rpm_spec.rb
index 2aceee59a5..411afd3755 100644
--- a/spec/unit/provider/package/rpm_spec.rb
+++ b/spec/unit/provider/package/rpm_spec.rb
@@ -19,138 +19,186 @@
require 'spec_helper'
describe Chef::Provider::Package::Rpm do
- before(:each) do
- @node = Chef::Node.new
- @events = Chef::EventDispatch::Dispatcher.new
- @run_context = Chef::RunContext.new(@node, {}, @events)
-
- @new_resource = Chef::Resource::Package.new("ImageMagick-c++")
- @new_resource.source "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
-
- @provider = Chef::Provider::Package::Rpm.new(@new_resource, @run_context)
+ let(:provider) { Chef::Provider::Package::Rpm.new(new_resource, run_context) }
+ let(:node) { Chef::Node.new }
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
+ let(:run_context) { Chef::RunContext.new(node, {}, events) }
+ let(:new_resource) do
+ Chef::Resource::Package.new("ImageMagick-c++").tap do |resource|
+ resource.source "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
+ end
+ end
+ let(:exitstatus) { 0 }
+ let(:stdout) { String.new('') }
+ let(:status) { double('Process::Status', exitstatus: exitstatus, stdout: stdout) }
- @status = double("Status", :exitstatus => 0)
+ before(:each) do
allow(::File).to receive(:exists?).and_return(true)
+ allow(provider).to receive(:shell_out!).and_return(status)
end
describe "when determining the current state of the package" do
-
it "should create a current resource with the name of new_resource" do
- allow(@provider).to receive(:popen4).and_return(@status)
- @provider.load_current_resource
- expect(@provider.current_resource.name).to eq("ImageMagick-c++")
+ provider.load_current_resource
+ expect(provider.current_resource.name).to eq("ImageMagick-c++")
end
it "should set the current reource package name to the new resource package name" do
- allow(@provider).to receive(:popen4).and_return(@status)
- @provider.load_current_resource
- expect(@provider.current_resource.package_name).to eq('ImageMagick-c++')
+ provider.load_current_resource
+ expect(provider.current_resource.package_name).to eq('ImageMagick-c++')
end
it "should raise an exception if a source is supplied but not found" do
allow(::File).to receive(:exists?).and_return(false)
- expect { @provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
+ expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
end
- it "should get the source package version from rpm if provided" do
- @stdout = StringIO.new("ImageMagick-c++ 6.5.4.7-7.el6_5")
- expect(@provider).to receive(:popen4).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
- expect(@provider).to receive(:popen4).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' ImageMagick-c++").and_return(@status)
- @provider.load_current_resource
- expect(@provider.current_resource.package_name).to eq("ImageMagick-c++")
- expect(@provider.new_resource.version).to eq("6.5.4.7-7.el6_5")
- end
+ context "installation exists" do
+ let(:stdout) { "ImageMagick-c++ 6.5.4.7-7.el6_5" }
+
+ it "should get the source package version from rpm if provided" do
+ expect(provider).to receive(:shell_out!).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm").and_return(status)
+ expect(provider).to receive(:shell_out).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' ImageMagick-c++").and_return(status)
+ provider.load_current_resource
+ expect(provider.current_resource.package_name).to eq("ImageMagick-c++")
+ expect(provider.new_resource.version).to eq("6.5.4.7-7.el6_5")
+ end
- it "should return the current version installed if found by rpm" do
- @stdout = StringIO.new("ImageMagick-c++ 6.5.4.7-7.el6_5")
- expect(@provider).to receive(:popen4).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm").and_return(@status)
- expect(@provider).to receive(:popen4).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' ImageMagick-c++").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
- @provider.load_current_resource
- expect(@provider.current_resource.version).to eq("6.5.4.7-7.el6_5")
+ it "should return the current version installed if found by rpm" do
+ expect(provider).to receive(:shell_out!).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm").and_return(status)
+ expect(provider).to receive(:shell_out).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' ImageMagick-c++").and_return(status)
+ provider.load_current_resource
+ expect(provider.current_resource.version).to eq("6.5.4.7-7.el6_5")
+ end
end
- it "should raise an exception if the source is not set but we are installing" do
- new_resource = Chef::Resource::Package.new("ImageMagick-c++")
- provider = Chef::Provider::Package::Rpm.new(new_resource, @run_context)
- expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
+ context "source is uri formed" do
+ before(:each) do
+ allow(::File).to receive(:exists?).and_return(false)
+ end
+
+ %w(http HTTP https HTTPS ftp FTP).each do |scheme|
+ it "should accept uri formed source (#{scheme})" do
+ new_resource.source "#{scheme}://example.com/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
+ expect(provider.load_current_resource).not_to be_nil
+ end
+ end
+
+ %w(file FILE).each do |scheme|
+ it "should accept uri formed source (#{scheme})" do
+ new_resource.source "#{scheme}:///ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
+ expect(provider.load_current_resource).not_to be_nil
+ end
+ end
+
+ it "should raise an exception if an uri formed source is non-supported scheme" do
+ new_resource.source "foobar://example.com/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
+ expect(provider.load_current_resource).to be_nil
+ expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
+ end
end
- it "should raise an exception if rpm fails to run" do
- status = double("Status", :exitstatus => -1)
- allow(@provider).to receive(:popen4).and_return(status)
- expect { @provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
+ context "source is not defiend" do
+ let(:new_resource) { Chef::Resource::Package.new("ImageMagick-c++") }
+
+ it "should raise an exception if the source is not set but we are installing" do
+ expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
+ end
end
- it "should not detect the package name as version when not installed" do
- @status = double("Status", :exitstatus => -1)
- @stdout = StringIO.new("package openssh-askpass is not installed")
- @new_resource = Chef::Resource::Package.new("openssh-askpass")
- @new_resource.source 'openssh-askpass'
- @provider = Chef::Provider::Package::Rpm.new(@new_resource, @run_context)
- expect(@provider).to receive(:popen4).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' openssh-askpass").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
- expect(@provider).to receive(:popen4).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' openssh-askpass").and_return(@status)
- @provider.load_current_resource
- expect(@provider.current_resource.version).to be_nil
+ context "installation does not exist" do
+ let(:stdout) { String.new("package openssh-askpass is not installed") }
+ let(:exitstatus) { -1 }
+ let(:new_resource) do
+ Chef::Resource::Package.new("openssh-askpass").tap do |resource|
+ resource.source "openssh-askpass"
+ end
+ end
+
+ it "should raise an exception if rpm fails to run" do
+ allow(provider).to receive(:shell_out).and_return(status)
+ expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "should not detect the package name as version when not installed" do
+ expect(provider).to receive(:shell_out!).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' openssh-askpass").and_return(status)
+ expect(provider).to receive(:shell_out).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' openssh-askpass").and_return(status)
+ provider.load_current_resource
+ expect(provider.current_resource.version).to be_nil
+ end
end
end
describe "after the current resource is loaded" do
- before do
- @current_resource = Chef::Resource::Package.new("ImageMagick-c++")
- @provider.current_resource = @current_resource
+ let(:current_resource) { Chef::Resource::Package.new("ImageMagick-c++") }
+ let(:provider) do
+ Chef::Provider::Package::Rpm.new(new_resource, run_context).tap do |provider|
+ provider.current_resource = current_resource
+ end
end
describe "when installing or upgrading" do
it "should run rpm -i with the package source to install" do
- expect(@provider).to receive(:shell_out!).with("rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider.install_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
+ expect(provider).to receive(:shell_out!).with("rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.install_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
end
it "should run rpm -U with the package source to upgrade" do
- @current_resource.version("21.4-19.el5")
- expect(@provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
+ current_resource.version("21.4-19.el5")
+ expect(provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
end
it "should install package if missing and set to upgrade" do
- @current_resource.version("ImageMagick-c++")
- expect(@provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
+ current_resource.version("ImageMagick-c++")
+ expect(provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
end
- it "should install from a path when the package is a path and the source is nil" do
- @new_resource = Chef::Resource::Package.new("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider = Chef::Provider::Package::Rpm.new(@new_resource, @run_context)
- expect(@new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @current_resource = Chef::Resource::Package.new("ImageMagick-c++")
- @provider.current_resource = @current_resource
- expect(@provider).to receive(:shell_out!).with("rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider.install_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
+ context "allowing downgrade" do
+ let(:new_resource) { Chef::Resource::RpmPackage.new("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm") }
+ let(:current_resource) { Chef::Resource::RpmPackage.new("ImageMagick-c++") }
+
+ it "should run rpm -U --oldpackage with the package source to downgrade" do
+ new_resource.allow_downgrade(true)
+ current_resource.version("21.4-19.el5")
+ expect(provider).to receive(:shell_out!).with("rpm -U --oldpackage /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
+ end
end
- it "should uprgrade from a path when the package is a path and the source is nil" do
- @new_resource = Chef::Resource::Package.new("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider = Chef::Provider::Package::Rpm.new(@new_resource, @run_context)
- expect(@new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @current_resource = Chef::Resource::Package.new("ImageMagick-c++")
- @current_resource.version("21.4-19.el5")
- @provider.current_resource = @current_resource
- expect(@provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider.upgrade_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
+ context "installing when the name is a path" do
+ let(:new_resource) { Chef::Resource::Package.new("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm") }
+ let(:current_resource) { Chef::Resource::Package.new("ImageMagick-c++") }
+
+ it "should install from a path when the package is a path and the source is nil" do
+ expect(new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.current_resource = current_resource
+ expect(provider).to receive(:shell_out!).with("rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.install_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
+ end
+
+ it "should uprgrade from a path when the package is a path and the source is nil" do
+ expect(new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ current_resource.version("21.4-19.el5")
+ provider.current_resource = current_resource
+ expect(provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.upgrade_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
+ end
end
it "installs with custom options specified in the resource" do
- @provider.candidate_version = '11'
- @new_resource.options("--dbpath /var/lib/rpm")
- expect(@provider).to receive(:shell_out!).with("rpm --dbpath /var/lib/rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
- @provider.install_package(@new_resource.name, @provider.candidate_version)
+ provider.candidate_version = '11'
+ new_resource.options("--dbpath /var/lib/rpm")
+ expect(provider).to receive(:shell_out!).with("rpm --dbpath /var/lib/rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
+ provider.install_package(new_resource.name, provider.candidate_version)
end
end
describe "when removing the package" do
it "should run rpm -e to remove the package" do
- expect(@provider).to receive(:shell_out!).with("rpm -e ImageMagick-c++-6.5.4.7-7.el6_5")
- @provider.remove_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
+ expect(provider).to receive(:shell_out!).with("rpm -e ImageMagick-c++-6.5.4.7-7.el6_5")
+ provider.remove_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
end
end
end
diff --git a/spec/unit/provider/package/rubygems_spec.rb b/spec/unit/provider/package/rubygems_spec.rb
index bce0054220..b17c216ddd 100644
--- a/spec/unit/provider/package/rubygems_spec.rb
+++ b/spec/unit/provider/package/rubygems_spec.rb
@@ -90,7 +90,7 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment 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")), "http://rubygems.org/"]]
+ 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
@@ -121,6 +121,7 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do
Gem.const_set(:Format, Object.new)
@remove_gem_format = true
end
+ allow(Gem::Package).to receive(:respond_to?).and_call_original
allow(Gem::Package).to receive(:respond_to?).with(:open).and_return(false)
end
@@ -155,7 +156,7 @@ describe Chef::Provider::Package::Rubygems::CurrentGemEnvironment do
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")), "http://rubygems.org/"]]
+ 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
@@ -290,9 +291,9 @@ RubyGems Environment:
- "install" => "--env-shebang"
- "update" => "--env-shebang"
- "gem" => "--no-rdoc --no-ri"
- - :sources => ["http://rubygems.org/", "http://gems.github.com/"]
+ - :sources => ["https://rubygems.org/", "http://gems.github.com/"]
- REMOTE SOURCES:
- - http://rubygems.org/
+ - https://rubygems.org/
- http://gems.github.com/
JRUBY_GEM_ENV
expect(@gem_env).to receive(:shell_out!).with('/usr/weird/bin/gem env').and_return(double('jruby_gem_env', :stdout => gem_env_out))
@@ -331,10 +332,10 @@ RubyGems Environment:
- :benchmark => false
- :backtrace => false
- :bulk_threshold => 1000
- - :sources => ["http://rubygems.org/", "http://gems.github.com/"]
+ - :sources => ["https://rubygems.org/", "http://gems.github.com/"]
- "gem" => "--no-rdoc --no-ri"
- REMOTE SOURCES:
- - http://rubygems.org/
+ - https://rubygems.org/
- http://gems.github.com/
RBX_GEM_ENV
expect(@gem_env).to receive(:shell_out!).with('/usr/weird/bin/gem env').and_return(double('rbx_gem_env', :stdout => gem_env_out))
@@ -370,6 +371,8 @@ describe Chef::Provider::Package::Rubygems do
# We choose detect omnibus via RbConfig::CONFIG['bindir'] in Chef::Provider::Package::Rubygems.new
allow(RbConfig::CONFIG).to receive(:[]).with('bindir').and_return("/usr/bin/ruby")
+ # Rubygems uses this interally
+ allow(RbConfig::CONFIG).to receive(:[]).with('arch').and_call_original
@provider = Chef::Provider::Package::Rubygems.new(@new_resource, @run_context)
end
@@ -378,7 +381,7 @@ describe Chef::Provider::Package::Rubygems do
it "target_version_already_installed? should return false so that we can search for candidates" do
@provider.load_current_resource
- expect(@provider.target_version_already_installed?).to be_false
+ expect(@provider.target_version_already_installed?(@provider.current_resource.version, @new_resource.version)).to be_falsey
end
end
@@ -468,6 +471,8 @@ describe Chef::Provider::Package::Rubygems do
it "determines the candidate version by querying the remote gem servers" do
@new_resource.source('http://mygems.example.com')
+ @provider.load_current_resource
+ @provider.current_resource.version('0.0.1')
version = Gem::Version.new(@spec_version)
expect(@provider.gem_env).to receive(:candidate_version_from_remote).
with(Gem::Dependency.new('rspec-core', @spec_version), "http://mygems.example.com").
@@ -477,8 +482,9 @@ describe Chef::Provider::Package::Rubygems do
it "parses the gem's specification if the requested source is a file" do
@new_resource.package_name('chef-integration-test')
- @new_resource.version('>= 0')
@new_resource.source(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
+ @new_resource.version('>= 0')
+ @provider.load_current_resource
expect(@provider.candidate_version).to eq('0.1.0')
end
@@ -495,20 +501,23 @@ describe Chef::Provider::Package::Rubygems do
describe "in the current gem environment" do
it "installs the gem via the gems api when no explicit options are used" do
expect(@provider.gem_env).to receive(:install).with(@gem_dep, :sources => nil)
- expect(@provider.action_install).to be_true
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
it "installs the gem via the gems api when a remote source is provided" do
@new_resource.source('http://gems.example.org')
sources = ['http://gems.example.org']
expect(@provider.gem_env).to receive(:install).with(@gem_dep, :sources => sources)
- expect(@provider.action_install).to be_true
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
it "installs the gem from file via the gems api when no explicit options are used" do
@new_resource.source(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
expect(@provider.gem_env).to receive(:install).with(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
- expect(@provider.action_install).to be_true
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
it "installs the gem from file via the gems api when the package is a path and the source is nil" do
@@ -517,7 +526,8 @@ describe Chef::Provider::Package::Rubygems do
@provider.current_resource = @current_resource
expect(@new_resource.source).to eq(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
expect(@provider.gem_env).to receive(:install).with(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
- expect(@provider.action_install).to be_true
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
# this catches 'gem_package "foo"' when "./foo" is a file in the cwd, and instead of installing './foo' it fetches the remote gem
@@ -525,20 +535,35 @@ describe Chef::Provider::Package::Rubygems do
allow(::File).to receive(:exists?).and_return(true)
@new_resource.package_name('rspec-core')
expect(@provider.gem_env).to receive(:install).with(@gem_dep, :sources => nil)
- expect(@provider.action_install).to be_true
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
it "installs the gem by shelling out when options are provided as a String" do
@new_resource.options('-i /alt/install/location')
expected ="gem install rspec-core -q --no-rdoc --no-ri -v \"#{@spec_version}\" -i /alt/install/location"
expect(@provider).to receive(:shell_out!).with(expected, :env => nil)
- expect(@provider.action_install).to be_true
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ context "when no version is given" do
+ let(:target_version) { nil }
+
+ it "installs the gem by shelling out when options are provided but no version is given" do
+ @new_resource.options('-i /alt/install/location')
+ expected ="gem install rspec-core -q --no-rdoc --no-ri -v \"#{@provider.candidate_version}\" -i /alt/install/location"
+ expect(@provider).to receive(:shell_out!).with(expected, :env => nil)
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
+ end
end
it "installs the gem via the gems api when options are given as a Hash" do
@new_resource.options(:install_dir => '/alt/install/location')
expect(@provider.gem_env).to receive(:install).with(@gem_dep, :sources => nil, :install_dir => '/alt/install/location')
- expect(@provider.action_install).to be_true
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
describe "at a specific version" do
@@ -548,24 +573,25 @@ describe Chef::Provider::Package::Rubygems do
it "installs the gem via the gems api" do
expect(@provider.gem_env).to receive(:install).with(@gem_dep, :sources => nil)
- expect(@provider.action_install).to be_true
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
end
describe "at version specified with comparison operator" do
it "skips install if current version satisifies requested version" do
- allow(@current_resource).to receive(:version).and_return("2.3.3")
- allow(@new_resource).to receive(:version).and_return(">=2.3.0")
+ @current_resource.version("2.3.3")
+ @new_resource.version(">=2.3.0")
expect(@provider.gem_env).not_to receive(:install)
- @provider.action_install
+ @provider.run_action(:install)
end
it "allows user to specify gem version with fuzzy operator" do
- allow(@current_resource).to receive(:version).and_return("2.3.3")
- allow(@new_resource).to receive(:version).and_return("~>2.3.0")
+ @current_resource.version("2.3.3")
+ @new_resource.version("~>2.3.0")
expect(@provider.gem_env).not_to receive(:install)
- @provider.action_install
+ @provider.run_action(:install)
end
end
end
@@ -574,7 +600,8 @@ describe Chef::Provider::Package::Rubygems do
it "installs the gem by shelling out to gem install" do
@new_resource.gem_binary('/usr/weird/bin/gem')
expect(@provider).to receive(:shell_out!).with("/usr/weird/bin/gem install rspec-core -q --no-rdoc --no-ri -v \"#{@spec_version}\"", :env=>nil)
- expect(@provider.action_install).to be_true
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
it "installs the gem from file by shelling out to gem install" do
@@ -582,7 +609,8 @@ describe Chef::Provider::Package::Rubygems do
@new_resource.source(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
@new_resource.version('>= 0')
expect(@provider).to receive(:shell_out!).with("/usr/weird/bin/gem install #{CHEF_SPEC_DATA}/gems/chef-integration-test-0.1.0.gem -q --no-rdoc --no-ri -v \">= 0\"", :env=>nil)
- expect(@provider.action_install).to be_true
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
it "installs the gem from file by shelling out to gem install when the package is a path and the source is nil" do
@@ -593,7 +621,8 @@ describe Chef::Provider::Package::Rubygems do
@new_resource.version('>= 0')
expect(@new_resource.source).to eq(CHEF_SPEC_DATA + '/gems/chef-integration-test-0.1.0.gem')
expect(@provider).to receive(:shell_out!).with("/usr/weird/bin/gem install #{CHEF_SPEC_DATA}/gems/chef-integration-test-0.1.0.gem -q --no-rdoc --no-ri -v \">= 0\"", :env=>nil)
- expect(@provider.action_install).to be_true
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated_by_last_action
end
end
diff --git a/spec/unit/provider/package/solaris_spec.rb b/spec/unit/provider/package/solaris_spec.rb
index 8438202576..c348d665e8 100644
--- a/spec/unit/provider/package/solaris_spec.rb
+++ b/spec/unit/provider/package/solaris_spec.rb
@@ -46,34 +46,33 @@ INSTDATE: Nov 04 2009 01:02
HOTLINE: Please contact your local service provider
PKGINFO
- @status = double("Status", :exitstatus => 0)
+ @status = double("Status",:stdout => "", :exitstatus => 0)
end
it "should create a current resource with the name of new_resource" do
- allow(@provider).to receive(:popen4).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(@status)
@provider.load_current_resource
expect(@provider.current_resource.name).to eq("SUNWbash")
end
it "should set the current reource package name to the new resource package name" do
- allow(@provider).to receive(:popen4).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(@status)
@provider.load_current_resource
expect(@provider.current_resource.package_name).to eq("SUNWbash")
end
it "should raise an exception if a source is supplied but not found" do
- allow(@provider).to receive(:popen4).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(@status)
allow(::File).to receive(:exists?).and_return(false)
- @provider.define_resource_requirements
@provider.load_current_resource
+ @provider.define_resource_requirements
expect { @provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Package)
end
it "should get the source package version from pkginfo if provided" do
- @stdout = StringIO.new(@pkginfo)
- @stdin, @stderr = StringIO.new, StringIO.new
- expect(@provider).to receive(:popen4).with("pkginfo -l -d /tmp/bash.pkg SUNWbash").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
- expect(@provider).to receive(:popen4).with("pkginfo -l SUNWbash").and_return(@status)
+ status = double(:stdout => @pkginfo, :exitstatus => 0)
+ expect(@provider).to receive(:shell_out).with("pkginfo -l -d /tmp/bash.pkg SUNWbash").and_return(status)
+ expect(@provider).to receive(:shell_out).with("pkginfo -l SUNWbash").and_return(@status)
@provider.load_current_resource
expect(@provider.current_resource.package_name).to eq("SUNWbash")
@@ -81,10 +80,9 @@ PKGINFO
end
it "should return the current version installed if found by pkginfo" do
- @stdout = StringIO.new(@pkginfo)
- @stdin, @stderr = StringIO.new, StringIO.new
- expect(@provider).to receive(:popen4).with("pkginfo -l -d /tmp/bash.pkg SUNWbash").and_return(@status)
- expect(@provider).to receive(:popen4).with("pkginfo -l SUNWbash").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ status = double(:stdout => @pkginfo, :exitstatus => 0)
+ expect(@provider).to receive(:shell_out).with("pkginfo -l -d /tmp/bash.pkg SUNWbash").and_return(@status)
+ expect(@provider).to receive(:shell_out).with("pkginfo -l SUNWbash").and_return(status)
@provider.load_current_resource
expect(@provider.current_resource.version).to eq("11.10.0,REV=2005.01.08.05.16")
end
@@ -92,20 +90,19 @@ PKGINFO
it "should raise an exception if the source is not set but we are installing" do
@new_resource = Chef::Resource::Package.new("SUNWbash")
@provider = Chef::Provider::Package::Solaris.new(@new_resource, @run_context)
- allow(@provider).to receive(:popen4).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(@status)
expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package)
end
it "should raise an exception if pkginfo fails to run" do
- @status = double("Status", :exitstatus => -1)
- allow(@provider).to receive(:popen4).and_return(@status)
+ status = double(:stdout => "", :exitstatus => -1)
+ allow(@provider).to receive(:shell_out).and_return(status)
expect { @provider.load_current_resource }.to raise_error(Chef::Exceptions::Package)
end
it "should return a current resource with a nil version if the package is not found" do
- @stdout = StringIO.new
- expect(@provider).to receive(:popen4).with("pkginfo -l -d /tmp/bash.pkg SUNWbash").and_return(@status)
- expect(@provider).to receive(:popen4).with("pkginfo -l SUNWbash").and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ expect(@provider).to receive(:shell_out).with("pkginfo -l -d /tmp/bash.pkg SUNWbash").and_return(@status)
+ expect(@provider).to receive(:shell_out).with("pkginfo -l SUNWbash").and_return(@status)
@provider.load_current_resource
expect(@provider.current_resource.version).to be_nil
end
@@ -114,20 +111,20 @@ PKGINFO
describe "candidate_version" do
it "should return the candidate_version variable if already setup" do
@provider.candidate_version = "11.10.0,REV=2005.01.08.05.16"
- expect(@provider).not_to receive(:popen4)
+ expect(@provider).not_to receive(:shell_out)
@provider.candidate_version
end
it "should lookup the candidate_version if the variable is not already set" do
- @status = double("Status", :exitstatus => 0)
- allow(@provider).to receive(:popen4).and_return(@status)
- expect(@provider).to receive(:popen4)
+ status = double(:stdout => "", :exitstatus => 0)
+ allow(@provider).to receive(:shell_out).and_return(status)
+ expect(@provider).to receive(:shell_out)
@provider.candidate_version
end
it "should throw and exception if the exitstatus is not 0" do
- @status = double("Status", :exitstatus => 1)
- allow(@provider).to receive(:popen4).and_return(@status)
+ status = double(:stdout => "", :exitstatus => 1)
+ allow(@provider).to receive(:shell_out).and_return(status)
expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package)
end
diff --git a/spec/unit/provider/package/yum_spec.rb b/spec/unit/provider/package/yum_spec.rb
index 0d2a44f3ae..aecbd1c34e 100644
--- a/spec/unit/provider/package/yum_spec.rb
+++ b/spec/unit/provider/package/yum_spec.rb
@@ -231,26 +231,102 @@ describe Chef::Provider::Package::Yum do
@provider.load_current_resource
end
- it "should search provides if package name can't be found then set package_name to match" do
+ context "when the package name isn't found" do
+ let(:yum_cache) { double(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.0.1.el5",
+ :candidate_version => "2.0.1.el5",
+ :package_available? => false,
+ :version_available? => true,
+ :disable_extra_repo_control => true
+ )
+ }
+
+ before do
+ allow(Chef::Provider::Package::Yum::YumCache).to receive(:instance).and_return(yum_cache)
+ @pkg = Chef::Provider::Package::Yum::RPMPackage.new("test-package", "2.0.1.el5", "x86_64", [])
+ expect(yum_cache).to receive(:packages_from_require).and_return([@pkg])
+ end
+
+ it "should search provides then set package_name to match" do
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ expect(@new_resource.package_name).to eq('test-package')
+ expect(@new_resource.version).to eq(nil)
+ end
+
+ it "should search provides then set version to match if a requirement was passed in the package name" do
+ @new_resource = Chef::Resource::YumPackage.new('test-package = 2.0.1.el5')
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ expect(@new_resource.package_name).to eq('test-package')
+ expect(@new_resource.version).to eq('2.0.1.el5')
+ end
+
+
+ it "should search provides then set version to match if a requirement was passed in the version" do
+ @new_resource = Chef::Resource::YumPackage.new('test-package')
+ @new_resource.version('= 2.0.1.el5')
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ expect(@new_resource.package_name).to eq('test-package')
+ expect(@new_resource.version).to eq('2.0.1.el5')
+ end
+
+
+ it "should search provides and not set the version to match if a specific version was requested" do
+ @new_resource = Chef::Resource::YumPackage.new('test-package')
+ @new_resource.version('3.0.1.el5')
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ expect(@new_resource.package_name).to eq('test-package')
+ expect(@new_resource.version).to eq('3.0.1.el5')
+ end
+
+ it "should search provides then set versions to match if requirements were passed in the package name as an array" do
+ @new_resource = Chef::Resource::YumPackage.new(['test-package = 2.0.1.el5'])
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ expect(@new_resource.package_name).to eq(['test-package'])
+ expect(@new_resource.version).to eq(['2.0.1.el5'])
+ end
+
+ it "should search provides and not set the versions to match if specific versions were requested in an array" do
+ @new_resource = Chef::Resource::YumPackage.new(['test-package'])
+ @new_resource.version(['3.0.1.el5'])
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ expect(@new_resource.package_name).to eq(['test-package'])
+ expect(@new_resource.version).to eq(['3.0.1.el5'])
+ end
+
+ end
+
+ it "should not return an error if no version number is specified in the resource" do
+ @new_resource = Chef::Resource::YumPackage.new('test-package')
@yum_cache = double(
- 'Chef::Provider::Yum::YumCache',
- :reload_installed => true,
- :reset => true,
- :installed_version => "1.2.4-11.18.el5",
- :candidate_version => "1.2.4-11.18.el5",
- :package_available? => false,
- :version_available? => true,
- :disable_extra_repo_control => true
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.0.1.el5",
+ :candidate_version => "2.0.1.el5",
+ :package_available? => false,
+ :version_available? => true,
+ :disable_extra_repo_control => true
)
allow(Chef::Provider::Package::Yum::YumCache).to receive(:instance).and_return(@yum_cache)
- pkg = Chef::Provider::Package::Yum::RPMPackage.new("test-package", "1.2.4-11.18.el5", "x86_64", [])
+ pkg = Chef::Provider::Package::Yum::RPMPackage.new("test-package", "2.0.1.el5", "x86_64", [])
expect(@yum_cache).to receive(:packages_from_require).and_return([pkg])
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@provider.load_current_resource
expect(@new_resource.package_name).to eq("test-package")
+ expect(@new_resource.version).to eq(nil)
end
- it "should search provides if package name can't be found, warn about multiple matches, but use the first one" do
+ it "should give precedence to the version attribute when both a requirement in the resource name and a version attribute are specified" do
+ @new_resource = Chef::Resource::YumPackage.new('test-package')
@yum_cache = double(
'Chef::Provider::Yum::YumCache',
:reload_installed => true,
@@ -262,13 +338,38 @@ describe Chef::Provider::Package::Yum do
:disable_extra_repo_control => true
)
allow(Chef::Provider::Package::Yum::YumCache).to receive(:instance).and_return(@yum_cache)
- pkg_x = Chef::Provider::Package::Yum::RPMPackage.new("test-package-x", "1.2.4-11.18.el5", "x86_64", [])
- pkg_y = Chef::Provider::Package::Yum::RPMPackage.new("test-package-y", "1.2.6-11.3.el5", "i386", [])
- expect(@yum_cache).to receive(:packages_from_require).and_return([pkg_x, pkg_y])
- expect(Chef::Log).to receive(:warn).exactly(1).times.with(%r{matched multiple Provides})
+ pkg = Chef::Provider::Package::Yum::RPMPackage.new("test-package", "2.0.1.el5", "x86_64", [])
+ expect(@yum_cache).to receive(:packages_from_require).and_return([pkg])
+ @new_resource = Chef::Resource::YumPackage.new('test-package = 2.0.1.el5')
+ @new_resource.version('3.0.1.el5')
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@provider.load_current_resource
- expect(@new_resource.package_name).to eq("test-package-x")
+ expect(@new_resource.package_name).to eq('test-package')
+ expect(@new_resource.version).to eq('3.0.1.el5')
+ end
+
+ it "should correctly detect the installed states of an array of package names and version numbers" do
+ @yum_cache = double(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => "1.0.1.el5",
+ :candidate_version => "2.0.1.el5",
+ :package_available? => false,
+ :version_available? => true,
+ :disable_extra_repo_control => true
+ )
+ allow(Chef::Provider::Package::Yum::YumCache).to receive(:instance).and_return(@yum_cache)
+
+ expect(@yum_cache).to receive(:packages_from_require).exactly(4).times.and_return([])
+ expect(@yum_cache).to receive(:reload_provides).twice
+
+ @new_resource = Chef::Resource::YumPackage.new(['test-package','test-package2'])
+ @new_resource.version(['2.0.1.el5','3.0.1.el5'])
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @provider.load_current_resource
+ expect(@new_resource.package_name).to eq(['test-package','test-package2'])
+ expect(@new_resource.version).to eq(['2.0.1.el5','3.0.1.el5'])
end
it "should search provides if no package is available - if no match in installed provides then load the complete set" do
@@ -287,6 +388,7 @@ describe Chef::Provider::Package::Yum do
expect(@yum_cache).to receive(:reload_provides)
@provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
@provider.load_current_resource
+ expect(@new_resource.version).to eq(nil)
end
it "should search provides if no package is available and not load the complete set if action is :remove or :purge" do
@@ -337,9 +439,9 @@ describe Chef::Provider::Package::Yum do
@provider.load_current_resource
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
- "yum -d0 -e0 -y install emacs-1.0"
+ "yum -d0 -e0 -y install cups-1.2.4-11.19.el5"
)
- @provider.install_package("emacs", "1.0")
+ @provider.install_package("cups", "1.2.4-11.19.el5")
end
it "should run yum localinstall if given a path to an rpm" do
@@ -366,14 +468,14 @@ describe Chef::Provider::Package::Yum do
allow(@new_resource).to receive(:arch).and_return("i386")
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
- "yum -d0 -e0 -y install emacs-21.4-20.el5.i386"
+ "yum -d0 -e0 -y install cups-1.2.4-11.19.el5.i386"
)
- @provider.install_package("emacs", "21.4-20.el5")
+ @provider.install_package("cups", "1.2.4-11.19.el5")
end
it "installs the package with the options given in the resource" do
@provider.load_current_resource
- @provider.candidate_version = '11'
+ allow(@provider).to receive(:candidate_version).and_return('11')
allow(@new_resource).to receive(:options).and_return("--disablerepo epmd")
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
@@ -467,10 +569,10 @@ describe Chef::Provider::Package::Yum do
@provider.load_current_resource
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
- "yum -d0 -e0 -y install emacs-1.0"
+ "yum -d0 -e0 -y install cups-1.2.4-11.15.el5"
)
expect(@yum_cache).to receive(:reload).once
- @provider.install_package("emacs", "1.0")
+ @provider.install_package("cups", "1.2.4-11.15.el5")
end
it "should run yum install then not flush the cache if :after is false" do
@@ -478,17 +580,17 @@ describe Chef::Provider::Package::Yum do
@provider.load_current_resource
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
- "yum -d0 -e0 -y install emacs-1.0"
+ "yum -d0 -e0 -y install cups-1.2.4-11.15.el5"
)
expect(@yum_cache).not_to receive(:reload)
- @provider.install_package("emacs", "1.0")
+ @provider.install_package("cups", "1.2.4-11.15.el5")
end
end
describe "when upgrading a package" do
it "should run yum install if the package is installed and a version is given" do
@provider.load_current_resource
- @provider.candidate_version = '11'
+ allow(@provider).to receive(:candidate_version).and_return('11')
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
"yum -d0 -e0 -y install cups-11"
@@ -499,7 +601,7 @@ describe Chef::Provider::Package::Yum do
it "should run yum install if the package is not installed" do
@provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
- @provider.candidate_version = '11'
+ allow(@provider).to receive(:candidate_version).and_return('11')
allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
expect(@provider).to receive(:yum_command).with(
"yum -d0 -e0 -y install cups-11"
@@ -528,42 +630,41 @@ describe Chef::Provider::Package::Yum do
# Test our little workaround, some crossover into Chef::Provider::Package territory
it "should call action_upgrade in the parent if the current resource version is nil" do
allow(@yum_cache).to receive(:installed_version).and_return(nil)
- @provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
- @provider.candidate_version = '11'
+ allow(@provider).to receive(:candidate_version).and_return('11')
expect(@provider).to receive(:upgrade_package).with(
"cups",
"11"
)
- @provider.action_upgrade
+ @provider.run_action(:upgrade)
end
it "should call action_upgrade in the parent if the candidate version is nil" do
@provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
- @provider.candidate_version = nil
+ allow(@provider).to receive(:candidate_version).and_return(nil)
expect(@provider).not_to receive(:upgrade_package)
- @provider.action_upgrade
+ @provider.run_action(:upgrade)
end
it "should call action_upgrade in the parent if the candidate is newer" do
@provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
- @provider.candidate_version = '11'
+ allow(@provider).to receive(:candidate_version).and_return('11')
expect(@provider).to receive(:upgrade_package).with(
"cups",
"11"
)
- @provider.action_upgrade
+ @provider.run_action(:upgrade)
end
it "should not call action_upgrade in the parent if the candidate is older" do
allow(@yum_cache).to receive(:installed_version).and_return("12")
@provider.load_current_resource
@current_resource = Chef::Resource::Package.new('cups')
- @provider.candidate_version = '11'
+ allow(@provider).to receive(:candidate_version).and_return('11')
expect(@provider).not_to receive(:upgrade_package)
- @provider.action_upgrade
+ @provider.run_action(:upgrade)
end
end
@@ -1861,3 +1962,103 @@ EOF
end
end
+
+describe "Chef::Provider::Package::Yum - Multi" do
+ before(:each) do
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+ @new_resource = Chef::Resource::Package.new(['cups', 'vim'])
+ @status = double("Status", :exitstatus => 0)
+ @yum_cache = double(
+ 'Chef::Provider::Yum::YumCache',
+ :reload_installed => true,
+ :reset => true,
+ :installed_version => 'XXXX',
+ :candidate_version => 'YYYY',
+ :package_available? => true,
+ :version_available? => true,
+ :allow_multi_install => [ 'kernel' ],
+ :package_repository => 'base',
+ :disable_extra_repo_control => true
+ )
+ allow(Chef::Provider::Package::Yum::YumCache).to receive(:instance).and_return(@yum_cache)
+ @provider = Chef::Provider::Package::Yum.new(@new_resource, @run_context)
+ @pid = double("PID")
+ end
+
+ describe "when loading the current system state" do
+ it "should create a current resource with the name of the new_resource" do
+ @provider.load_current_resource
+ expect(@provider.current_resource.name).to eq('cups, vim')
+ end
+
+ it "should set the current resources package name to the new resources package name" do
+ @provider.load_current_resource
+ expect(@provider.current_resource.package_name).to eq(['cups', 'vim'])
+ end
+
+ it "should set the installed version to nil on the current resource if no installed package" do
+ allow(@yum_cache).to receive(:installed_version).and_return(nil)
+ @provider.load_current_resource
+ expect(@provider.current_resource.version).to eq([nil, nil])
+ end
+
+ it "should set the installed version if yum has one" do
+ allow(@yum_cache).to receive(:installed_version).with('cups', nil).and_return('1.2.4-11.18.el5')
+ allow(@yum_cache).to receive(:installed_version).with('vim', nil).and_return('1.0')
+ allow(@yum_cache).to receive(:candidate_version).with('cups', nil).and_return('1.2.4-11.18.el5_2.3')
+ allow(@yum_cache).to receive(:candidate_version).with('vim', nil).and_return('1.5')
+ @provider.load_current_resource
+ expect(@provider.current_resource.version).to eq(['1.2.4-11.18.el5', '1.0'])
+ end
+
+ it "should set the candidate version if yum info has one" do
+ allow(@yum_cache).to receive(:installed_version).with('cups', nil).and_return('1.2.4-11.18.el5')
+ allow(@yum_cache).to receive(:installed_version).with('vim', nil).and_return('1.0')
+ allow(@yum_cache).to receive(:candidate_version).with('cups', nil).and_return('1.2.4-11.18.el5_2.3')
+ allow(@yum_cache).to receive(:candidate_version).with('vim', nil).and_return('1.5')
+ @provider.load_current_resource
+ expect(@provider.candidate_version).to eql(['1.2.4-11.18.el5_2.3', '1.5'])
+ end
+
+ it "should return the current resouce" do
+ expect(@provider.load_current_resource).to eql(@provider.current_resource)
+ end
+ end
+
+ describe "when installing a package" do
+ it "should run yum install with the package name and version" do
+ @provider.load_current_resource
+ allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
+ allow(@yum_cache).to receive(:installed_version).with('cups', nil).and_return('1.2.4-11.18.el5')
+ allow(@yum_cache).to receive(:installed_version).with('vim', nil).and_return('0.9')
+ expect(@provider).to receive(:yum_command).with(
+ "yum -d0 -e0 -y install cups-1.2.4-11.19.el5 vim-1.0"
+ )
+ @provider.install_package(["cups", "vim"], ["1.2.4-11.19.el5", '1.0'])
+ end
+
+ it "should run yum install with the package name, version and arch" do
+ @provider.load_current_resource
+ allow(@new_resource).to receive(:arch).and_return("i386")
+ allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
+ expect(@provider).to receive(:yum_command).with(
+ "yum -d0 -e0 -y install cups-1.2.4-11.19.el5.i386 vim-1.0.i386"
+ )
+ @provider.install_package(["cups", "vim"], ["1.2.4-11.19.el5", "1.0"])
+ end
+
+ it "installs the package with the options given in the resource" do
+ @provider.load_current_resource
+ allow(Chef::Provider::Package::Yum::RPMUtils).to receive(:rpmvercmp).and_return(-1)
+ allow(@yum_cache).to receive(:installed_version).with('cups', nil).and_return('1.2.4-11.18.el5')
+ allow(@yum_cache).to receive(:installed_version).with('vim', nil).and_return('0.9')
+ expect(@provider).to receive(:yum_command).with(
+ "yum -d0 -e0 -y --disablerepo epmd install cups-1.2.4-11.19.el5 vim-1.0"
+ )
+ allow(@new_resource).to receive(:options).and_return("--disablerepo epmd")
+ @provider.install_package(["cups", "vim"], ["1.2.4-11.19.el5", '1.0'])
+ end
+ end
+end \ No newline at end of file
diff --git a/spec/unit/provider/package/zypper_spec.rb b/spec/unit/provider/package/zypper_spec.rb
index 17d99640e6..706ad722dd 100644
--- a/spec/unit/provider/package/zypper_spec.rb
+++ b/spec/unit/provider/package/zypper_spec.rb
@@ -27,14 +27,10 @@ describe Chef::Provider::Package::Zypper do
@current_resource = Chef::Resource::Package.new("cups")
- @status = double("Status", :exitstatus => 0)
-
@provider = Chef::Provider::Package::Zypper.new(@new_resource, @run_context)
allow(Chef::Resource::Package).to receive(:new).and_return(@current_resource)
- allow(@provider).to receive(:popen4).and_return(@status)
- @stderr = StringIO.new
- @stdout = StringIO.new
- @pid = double("PID")
+ @status = double(:stdout => "\n", :exitstatus => 0)
+ allow(@provider).to receive(:shell_out).and_return(@status)
allow(@provider).to receive(:`).and_return("2.0")
end
@@ -50,27 +46,28 @@ describe Chef::Provider::Package::Zypper do
end
it "should run zypper info with the package name" do
- expect(@provider).to receive(:popen4).with("zypper --non-interactive info #{@new_resource.package_name}").and_return(@status)
+ expect(@provider).to receive(:shell_out).with("zypper --non-interactive info #{@new_resource.package_name}").and_return(@status)
@provider.load_current_resource
end
it "should set the installed version to nil on the current resource if zypper info installed version is (none)" do
- allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(@status)
expect(@current_resource).to receive(:version).with(nil).and_return(true)
@provider.load_current_resource
end
it "should set the installed version if zypper info has one" do
- @stdout = StringIO.new("Version: 1.0\nInstalled: Yes\n")
- allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ 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" do
- @stdout = StringIO.new("Version: 1.0\nInstalled: No\nStatus: out-of-date (version 0.9 installed)")
+ status = double(:stdout => "Version: 1.0\nInstalled: No\nStatus: out-of-date (version 0.9 installed)", :exitstatus => 0)
- allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
+ allow(@provider).to receive(:shell_out).and_return(status)
@provider.load_current_resource
expect(@provider.candidate_version).to eql("1.0")
end
diff --git a/spec/unit/provider/package_spec.rb b/spec/unit/provider/package_spec.rb
index 3a42bcacf6..1633d18f9d 100644
--- a/spec/unit/provider/package_spec.rb
+++ b/spec/unit/provider/package_spec.rb
@@ -152,7 +152,7 @@ describe Chef::Provider::Package do
it "should print the word 'uninstalled' if there was no original version" do
allow(@current_resource).to receive(:version).and_return(nil)
- expect(Chef::Log).to receive(:info).with("package[emacs] upgraded from uninstalled to 1.0")
+ expect(Chef::Log).to receive(:info).with("package[emacs] upgraded emacs to 1.0")
@provider.run_action(:upgrade)
expect(@new_resource).to be_updated_by_last_action
end
@@ -376,7 +376,7 @@ describe Chef::Provider::Package do
end
it "should never back up the cached response file" do
- expect(@provider.preseed_resource('java', '6').backup).to be_false
+ expect(@provider.preseed_resource('java', '6').backup).to be_falsey
end
it "sets the install path of the resource to $file_cache/$cookbook/$pkg_name-$pkg_version.seed" do
@@ -425,3 +425,277 @@ describe Chef::Provider::Package do
end
end
+
+describe "Chef::Provider::Package - Multi" do
+ before do
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+ @new_resource = Chef::Resource::Package.new(['emacs', 'vi'])
+ @current_resource = Chef::Resource::Package.new(['emacs', 'vi'])
+ @provider = Chef::Provider::Package.new(@new_resource, @run_context)
+ @provider.current_resource = @current_resource
+ @provider.candidate_version = ['1.0', '6.2']
+ end
+
+ describe "when installing multiple packages" do
+ before(:each) do
+ @provider.current_resource = @current_resource
+ allow(@provider).to receive(:install_package).and_return(true)
+ end
+
+ it "installs the candidate versions when none are installed" do
+ expect(@provider).to receive(:install_package).with(
+ ["emacs", "vi"],
+ ["1.0", "6.2"]
+ ).and_return(true)
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated
+ end
+
+ it "installs the candidate versions when some are installed" do
+ expect(@provider).to receive(:install_package).with(
+ [ 'vi' ],
+ [ '6.2' ]
+ ).and_return(true)
+ @current_resource.version(['1.0', nil])
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated
+ end
+
+ it "installs the specified version when some are out of date" do
+ @current_resource.version(['1.0', '6.2'])
+ @new_resource.version(['1.0', '6.1'])
+ @provider.run_action(:install)
+ expect(@new_resource).to be_updated
+ end
+
+ it "does not install any version if all are installed at the right version" do
+ @current_resource.version(['1.0', '6.2'])
+ @new_resource.version(['1.0', '6.2'])
+ @provider.run_action(:install)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+
+ it "does not install any version if all are installed, and no version was specified" do
+ @current_resource.version(['1.0', '6.2'])
+ @provider.run_action(:install)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+
+ it "raises an exception if both are not installed and no caondidates are available" do
+ @current_resource.version([nil, nil])
+ @provider.candidate_version = [nil, nil]
+ expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "raises an exception if one is not installed and no candidates are available" do
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = ['1.0', nil]
+ expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "does not raise an exception if the packages are installed or have a candidate" do
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = [nil, '6.2']
+ expect { @provider.run_action(:install) }.not_to raise_error
+ end
+
+ it "raises an exception if an explicit version is asked for, an old version is installed, but no candidate" do
+ @new_resource.version ['1.0', '6.2']
+ @current_resource.version(['1.0', '6.1'])
+ @provider.candidate_version = ['1.0', nil]
+ expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "does not raise an exception if an explicit version is asked for, and is installed, but no candidate" do
+ @new_resource.version ['1.0', '6.2']
+ @current_resource.version(['1.0', '6.2'])
+ @provider.candidate_version = ['1.0', nil]
+ expect { @provider.run_action(:install) }.not_to raise_error
+ end
+
+ it "raise an exception if an explicit version is asked for, and is not installed, and no candidate" do
+ @new_resource.version ['1.0', '6.2']
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = ['1.0', nil]
+ expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "does not raise an exception if an explicit version is asked for, and is not installed, and there is a candidate" do
+ @new_resource.version ['1.0', '6.2']
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = ['1.0', '6.2']
+ expect { @provider.run_action(:install) }.not_to raise_error
+ end
+ end
+
+ describe "when upgrading multiple packages" do
+ before(:each) do
+ @provider.current_resource = @current_resource
+ allow(@provider).to receive(:upgrade_package).and_return(true)
+ end
+
+ it "should upgrade the package if the current versions are not the candidate version" do
+ @current_resource.version ['0.9', '6.1']
+ expect(@provider).to receive(:upgrade_package).with(
+ @new_resource.package_name,
+ @provider.candidate_version
+ ).and_return(true)
+ @provider.run_action(:upgrade)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should upgrade the package if some of current versions are not the candidate versions" do
+ @current_resource.version ['1.0', '6.1']
+ expect(@provider).to receive(:upgrade_package).with(
+ ["vi"],
+ ["6.2"]
+ ).and_return(true)
+ @provider.run_action(:upgrade)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should not install the package if the current versions are the candidate version" do
+ @current_resource.version ['1.0', '6.2']
+ expect(@provider).not_to receive(:upgrade_package)
+ @provider.run_action(:upgrade)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+
+ it "should raise an exception if both are not installed and no caondidates are available" do
+ @current_resource.version([nil, nil])
+ @provider.candidate_version = [nil, nil]
+ expect { @provider.run_action(:upgrade) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "should raise an exception if one is not installed and no candidates are available" do
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = ['1.0', nil]
+ expect { @provider.run_action(:upgrade) }.to raise_error(Chef::Exceptions::Package)
+ end
+
+ it "should not raise an exception if the packages are installed or have a candidate" do
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = [nil, '6.2']
+ expect { @provider.run_action(:upgrade) }.not_to raise_error
+ end
+
+ it "should not raise an exception if the packages are installed or have a candidate" do
+ @current_resource.version(['1.0', nil])
+ @provider.candidate_version = [nil, '6.2']
+ expect { @provider.run_action(:upgrade) }.not_to raise_error
+ end
+ end
+
+ describe "When removing multiple packages " do
+ before(:each) do
+ allow(@provider).to receive(:remove_package).and_return(true)
+ @current_resource.version ['1.0', '6.2']
+ end
+
+ it "should remove the packages if all are installed" do
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:remove_package).with(['emacs', 'vi'], nil)
+ @provider.run_action(:remove)
+ expect(@new_resource).to be_updated
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should remove the packages if some are installed" do
+ @current_resource.version ['1.0', nil]
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:remove_package).with(['emacs', 'vi'], nil)
+ @provider.run_action(:remove)
+ expect(@new_resource).to be_updated
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should remove the packages at a specific version if they are installed at that version" do
+ @new_resource.version ['1.0', '6.2']
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:remove_package).with(['emacs', 'vi'], ['1.0', '6.2'])
+ @provider.run_action(:remove)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should remove the packages at a specific version any are is installed at that version" do
+ @new_resource.version ['0.5', '6.2']
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:remove_package).with(['emacs', 'vi'], ['0.5', '6.2'])
+ @provider.run_action(:remove)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should not remove the packages at a specific version if they are not installed at that version" do
+ @new_resource.version ['0.5', '6.0']
+ expect(@provider).not_to be_removing_package
+ expect(@provider).not_to receive(:remove_package)
+ @provider.run_action(:remove)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+
+ it "should not remove the packages if they are not installed" do
+ expect(@provider).not_to receive(:remove_package)
+ allow(@current_resource).to receive(:version).and_return(nil)
+ @provider.run_action(:remove)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+
+ end
+
+ describe "When purging multiple packages " do
+ before(:each) do
+ allow(@provider).to receive(:purge_package).and_return(true)
+ @current_resource.version ['1.0', '6.2']
+ end
+
+ it "should purge the packages if all are installed" do
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:purge_package).with(['emacs', 'vi'], nil)
+ @provider.run_action(:purge)
+ expect(@new_resource).to be_updated
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should purge the packages if some are installed" do
+ @current_resource.version ['1.0', nil]
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:purge_package).with(['emacs', 'vi'], nil)
+ @provider.run_action(:purge)
+ expect(@new_resource).to be_updated
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should purge the packages at a specific version if they are installed at that version" do
+ @new_resource.version ['1.0', '6.2']
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:purge_package).with(['emacs', 'vi'], ['1.0', '6.2'])
+ @provider.run_action(:purge)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should purge the packages at a specific version any are is installed at that version" do
+ @new_resource.version ['0.5', '6.2']
+ expect(@provider).to be_removing_package
+ expect(@provider).to receive(:purge_package).with(['emacs', 'vi'], ['0.5', '6.2'])
+ @provider.run_action(:purge)
+ expect(@new_resource).to be_updated_by_last_action
+ end
+
+ it "should not purge the packages at a specific version if they are not installed at that version" do
+ @new_resource.version ['0.5', '6.0']
+ expect(@provider).not_to be_removing_package
+ expect(@provider).not_to receive(:purge_package)
+ @provider.run_action(:purge)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+
+ it "should not purge the packages if they are not installed" do
+ expect(@provider).not_to receive(:purge_package)
+ allow(@current_resource).to receive(:version).and_return(nil)
+ @provider.run_action(:purge)
+ expect(@new_resource).not_to be_updated_by_last_action
+ end
+ end
+end
diff --git a/spec/unit/provider/package_spec.rbe b/spec/unit/provider/package_spec.rbe
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/spec/unit/provider/package_spec.rbe
diff --git a/spec/unit/provider/remote_directory_spec.rb b/spec/unit/provider/remote_directory_spec.rb
index a2f5092f57..4434714ebc 100644
--- a/spec/unit/provider/remote_directory_spec.rb
+++ b/spec/unit/provider/remote_directory_spec.rb
@@ -84,7 +84,7 @@ describe Chef::Provider::RemoteDirectory do
expect(directory_resource.mode).to eq("0750")
expect(directory_resource.group).to eq("wheel")
expect(directory_resource.owner).to eq("root")
- expect(directory_resource.recursive).to be_true
+ expect(directory_resource.recursive).to be_truthy
end
it "configures access control on files in the directory" do
@@ -116,17 +116,17 @@ describe Chef::Provider::RemoteDirectory do
it "creates the toplevel directory without error " do
@resource.recursive(false)
@provider.run_action(:create)
- expect(::File.exist?(@destination_dir)).to be_true
+ expect(::File.exist?(@destination_dir)).to be_truthy
end
it "transfers the directory with all contents" do
@provider.run_action(:create)
- expect(::File.exist?(@destination_dir + '/remote_dir_file1.txt')).to be_true
- expect(::File.exist?(@destination_dir + '/remote_dir_file2.txt')).to be_true
- expect(::File.exist?(@destination_dir + '/remotesubdir/remote_subdir_file1.txt')).to be_true
- expect(::File.exist?(@destination_dir + '/remotesubdir/remote_subdir_file2.txt')).to be_true
- expect(::File.exist?(@destination_dir + '/remotesubdir/.a_dotfile')).to be_true
- expect(::File.exist?(@destination_dir + '/.a_dotdir/.a_dotfile_in_a_dotdir')).to be_true
+ expect(::File.exist?(@destination_dir + '/remote_dir_file1.txt')).to be_truthy
+ expect(::File.exist?(@destination_dir + '/remote_dir_file2.txt')).to be_truthy
+ expect(::File.exist?(@destination_dir + '/remotesubdir/remote_subdir_file1.txt')).to be_truthy
+ expect(::File.exist?(@destination_dir + '/remotesubdir/remote_subdir_file2.txt')).to be_truthy
+ expect(::File.exist?(@destination_dir + '/remotesubdir/.a_dotfile')).to be_truthy
+ expect(::File.exist?(@destination_dir + '/.a_dotdir/.a_dotfile_in_a_dotdir')).to be_truthy
end
describe "only if it is missing" do
@@ -141,8 +141,8 @@ describe Chef::Provider::RemoteDirectory do
@provider.run_action(:create_if_missing)
- expect(file1md5.eql?(Digest::MD5.hexdigest(File.read(@destination_dir + '/remote_dir_file1.txt')))).to be_true
- expect(subdirfile1md5.eql?(Digest::MD5.hexdigest(File.read(@destination_dir + '/remotesubdir/remote_subdir_file1.txt')))).to be_true
+ expect(file1md5.eql?(Digest::MD5.hexdigest(File.read(@destination_dir + '/remote_dir_file1.txt')))).to be_truthy
+ expect(subdirfile1md5.eql?(Digest::MD5.hexdigest(File.read(@destination_dir + '/remotesubdir/remote_subdir_file1.txt')))).to be_truthy
end
end
@@ -155,13 +155,13 @@ describe Chef::Provider::RemoteDirectory do
FileUtils.touch(@destination_dir + '/remotesubdir/marked_for_death_again.txt')
@provider.run_action(:create)
- expect(::File.exist?(@destination_dir + '/remote_dir_file1.txt')).to be_true
- expect(::File.exist?(@destination_dir + '/remote_dir_file2.txt')).to be_true
- expect(::File.exist?(@destination_dir + '/remotesubdir/remote_subdir_file1.txt')).to be_true
- expect(::File.exist?(@destination_dir + '/remotesubdir/remote_subdir_file2.txt')).to be_true
+ expect(::File.exist?(@destination_dir + '/remote_dir_file1.txt')).to be_truthy
+ expect(::File.exist?(@destination_dir + '/remote_dir_file2.txt')).to be_truthy
+ expect(::File.exist?(@destination_dir + '/remotesubdir/remote_subdir_file1.txt')).to be_truthy
+ expect(::File.exist?(@destination_dir + '/remotesubdir/remote_subdir_file2.txt')).to be_truthy
- expect(::File.exist?(@destination_dir + '/marked_for_death.txt')).to be_false
- expect(::File.exist?(@destination_dir + '/remotesubdir/marked_for_death_again.txt')).to be_false
+ expect(::File.exist?(@destination_dir + '/marked_for_death.txt')).to be_falsey
+ expect(::File.exist?(@destination_dir + '/remotesubdir/marked_for_death_again.txt')).to be_falsey
end
it "removes files in subdirectories before files above" do
@@ -172,10 +172,10 @@ describe Chef::Provider::RemoteDirectory do
FileUtils.touch(@destination_dir + '/a/multiply/nested/baz.txt')
FileUtils.touch(@destination_dir + '/a/multiply/nested/directory/qux.txt')
@provider.run_action(:create)
- expect(::File.exist?(@destination_dir + '/a/foo.txt')).to be_false
- expect(::File.exist?(@destination_dir + '/a/multiply/bar.txt')).to be_false
- expect(::File.exist?(@destination_dir + '/a/multiply/nested/baz.txt')).to be_false
- expect(::File.exist?(@destination_dir + '/a/multiply/nested/directory/qux.txt')).to be_false
+ expect(::File.exist?(@destination_dir + '/a/foo.txt')).to be_falsey
+ expect(::File.exist?(@destination_dir + '/a/multiply/bar.txt')).to be_falsey
+ expect(::File.exist?(@destination_dir + '/a/multiply/nested/baz.txt')).to be_falsey
+ expect(::File.exist?(@destination_dir + '/a/multiply/nested/directory/qux.txt')).to be_falsey
end
it "removes directory symlinks properly", :not_supported_on_win2k3 do
@@ -188,12 +188,12 @@ describe Chef::Provider::RemoteDirectory do
Dir.mktmpdir do |tmp_dir|
begin
@fclass.file_class.symlink(tmp_dir.dup, symlinked_dir_path)
- expect(::File.exist?(symlinked_dir_path)).to be_true
+ expect(::File.exist?(symlinked_dir_path)).to be_truthy
@provider.run_action
- expect(::File.exist?(symlinked_dir_path)).to be_false
- expect(::File.exist?(tmp_dir)).to be_true
+ expect(::File.exist?(symlinked_dir_path)).to be_falsey
+ expect(::File.exist?(tmp_dir)).to be_truthy
rescue Chef::Exceptions::Win32APIError => e
pending "This must be run as an Administrator to create symlinks"
end
@@ -212,8 +212,8 @@ describe Chef::Provider::RemoteDirectory do
file1md5 = Digest::MD5.hexdigest(::File.read(@destination_dir + '/remote_dir_file1.txt'))
subdirfile1md5 = Digest::MD5.hexdigest(::File.read(@destination_dir + '/remotesubdir/remote_subdir_file1.txt'))
@provider.run_action(:create)
- expect(file1md5.eql?(Digest::MD5.hexdigest(::File.read(@destination_dir + '/remote_dir_file1.txt')))).to be_true
- expect(subdirfile1md5.eql?(Digest::MD5.hexdigest(::File.read(@destination_dir + '/remotesubdir/remote_subdir_file1.txt')))).to be_true
+ expect(file1md5.eql?(Digest::MD5.hexdigest(::File.read(@destination_dir + '/remote_dir_file1.txt')))).to be_truthy
+ expect(subdirfile1md5.eql?(Digest::MD5.hexdigest(::File.read(@destination_dir + '/remotesubdir/remote_subdir_file1.txt')))).to be_truthy
end
end
diff --git a/spec/unit/provider/remote_file/ftp_spec.rb b/spec/unit/provider/remote_file/ftp_spec.rb
index b3a3fcf376..dbbddd8e84 100644
--- a/spec/unit/provider/remote_file/ftp_spec.rb
+++ b/spec/unit/provider/remote_file/ftp_spec.rb
@@ -60,7 +60,7 @@ describe Chef::Provider::RemoteFile::FTP do
let(:uri) { URI.parse("ftp://opscode.com/seattle.txt") }
before(:each) do
- allow(Net::FTP).to receive(:new).with().and_return(ftp)
+ allow(Net::FTP).to receive(:new).with(no_args).and_return(ftp)
allow(Tempfile).to receive(:new).and_return(tempfile)
end
@@ -89,13 +89,13 @@ describe Chef::Provider::RemoteFile::FTP do
it "does not use passive mode when new_resource sets ftp_active_mode to true" do
new_resource.ftp_active_mode(true)
fetcher = Chef::Provider::RemoteFile::FTP.new(uri, new_resource, current_resource)
- expect(fetcher.use_passive_mode?).to be_false
+ expect(fetcher.use_passive_mode?).to be_falsey
end
it "uses passive mode when new_resource sets ftp_active_mode to false" do
new_resource.ftp_active_mode(false)
fetcher = Chef::Provider::RemoteFile::FTP.new(uri, new_resource, current_resource)
- expect(fetcher.use_passive_mode?).to be_true
+ expect(fetcher.use_passive_mode?).to be_truthy
end
end
diff --git a/spec/unit/provider/route_spec.rb b/spec/unit/provider/route_spec.rb
index e63029ad07..ff68eea895 100644
--- a/spec/unit/provider/route_spec.rb
+++ b/spec/unit/provider/route_spec.rb
@@ -65,7 +65,7 @@ describe Chef::Provider::Route do
provider = Chef::Provider::Route.new(resource, @run_context)
provider.load_current_resource
- expect(provider.is_running).to be_false
+ expect(provider.is_running).to be_falsey
end
it "should detect existing routes and set is_running attribute correctly" do
@@ -75,7 +75,7 @@ describe Chef::Provider::Route do
provider = Chef::Provider::Route.new(resource, @run_context)
provider.load_current_resource
- expect(provider.is_running).to be_true
+ expect(provider.is_running).to be_truthy
end
it "should use gateway value when matching routes" do
@@ -85,7 +85,7 @@ describe Chef::Provider::Route do
provider = Chef::Provider::Route.new(resource, @run_context)
provider.load_current_resource
- expect(provider.is_running).to be_false
+ expect(provider.is_running).to be_falsey
end
end
end
diff --git a/spec/unit/provider/script_spec.rb b/spec/unit/provider/script_spec.rb
index 7dc8588397..d1759981aa 100644
--- a/spec/unit/provider/script_spec.rb
+++ b/spec/unit/provider/script_spec.rb
@@ -19,77 +19,95 @@
require 'spec_helper'
describe Chef::Provider::Script, "action_run" do
- before(:each) do
- @node = Chef::Node.new
- @events = Chef::EventDispatch::Dispatcher.new
- @run_context = Chef::RunContext.new(@node, {}, @events)
- @new_resource = Chef::Resource::Script.new('run some perl code')
- @new_resource.code "$| = 1; print 'i like beans'"
- @new_resource.interpreter 'perl'
+ let(:node) { Chef::Node.new }
+
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
+
+ let(:run_context) { Chef::RunContext.new(node, {}, events) }
+
+ let(:new_resource) {
+ new_resource = Chef::Resource::Script.new('run some perl code')
+ new_resource.code "$| = 1; print 'i like beans'"
+ new_resource.interpreter 'perl'
+ new_resource
+ }
- @provider = Chef::Provider::Script.new(@new_resource, @run_context)
+ let(:provider) { Chef::Provider::Script.new(new_resource, run_context) }
- @script_file = StringIO.new
- allow(@script_file).to receive(:path).and_return('/tmp/the_script_file')
+ let(:tempfile) { Tempfile.open("rspec-provider-script") }
- allow(@provider).to receive(:shell_out!).and_return(true)
+ before(:each) do
+ allow(provider).to receive(:shell_out!).and_return(true)
+ allow(provider).to receive(:script_file).and_return(tempfile)
end
- it "creates a temporary file to store the script" do
- expect(@provider.script_file).to be_an_instance_of(Tempfile)
+ context "#script_file" do
+ it "creates a temporary file to store the script" do
+ allow(provider).to receive(:script_file).and_call_original
+ expect(provider.script_file).to be_an_instance_of(Tempfile)
+ end
end
- it "unlinks the tempfile when finished" do
- tempfile_path = @provider.script_file.path
- @provider.unlink_script_file
- expect(File.exist?(tempfile_path)).to be_false
+ context "#unlink_script_file" do
+ it "unlinks the tempfile" do
+ tempfile_path = tempfile.path
+ provider.unlink_script_file
+ expect(File.exist?(tempfile_path)).to be false
+ end
end
- it "sets the owner and group for the script file" do
- @new_resource.user 'toor'
- @new_resource.group 'wheel'
- allow(@provider).to receive(:script_file).and_return(@script_file)
- expect(FileUtils).to receive(:chown).with('toor', 'wheel', "/tmp/the_script_file")
- @provider.set_owner_and_group
+ context "#set_owner_and_group" do
+ it "sets the owner and group for the script file" do
+ new_resource.user 'toor'
+ new_resource.group 'wheel'
+ expect(FileUtils).to receive(:chown).with('toor', 'wheel', tempfile.path)
+ provider.set_owner_and_group
+ end
end
context "with the script file set to the correct owner and group" do
before do
- allow(@provider).to receive(:set_owner_and_group)
- allow(@provider).to receive(:script_file).and_return(@script_file)
+ allow(provider).to receive(:set_owner_and_group)
end
+
describe "when writing the script to the file" do
it "should put the contents of the script in the temp file" do
- @provider.action_run
- @script_file.rewind
- expect(@script_file.string).to eq("$| = 1; print 'i like beans'\n")
+ allow(provider).to receive(:unlink_script_file) # stub to avoid remove
+ provider.action_run
+ expect(IO.read(tempfile.path)).to eq("$| = 1; print 'i like beans'\n")
+ provider.unlink_script_file
end
it "closes before executing the script and unlinks it when finished" do
- @provider.action_run
- expect(@script_file).to be_closed
+ tempfile_path = tempfile.path
+ provider.action_run
+ expect(tempfile).to be_closed
+ expect(File.exist?(tempfile_path)).to be false
end
-
end
describe "when running the script" do
- it 'should set the command to "interpreter" "tempfile"' do
- @provider.action_run
- expect(@new_resource.command).to eq('"perl" "/tmp/the_script_file"')
- end
+ let (:default_opts) {
+ {timeout: 3600, returns: 0, log_level: :info, log_tag: "script[run some perl code]", live_stream: STDOUT}
+ }
- describe "with flags set on the resource" do
- before do
- @new_resource.flags '-f'
- end
+ before do
+ allow(STDOUT).to receive(:tty?).and_return(true)
+ end
- it "should set the command to 'interpreter flags tempfile'" do
- @provider.action_run
- expect(@new_resource.command).to eq('"perl" -f "/tmp/the_script_file"')
- end
+ it 'should set the command to "interpreter" "tempfile"' do
+ expect(provider.command).to eq(%Q{"perl" "#{tempfile.path}"})
+ end
+ it 'should call shell_out! with the command' do
+ expect(provider).to receive(:shell_out!).with(provider.command, default_opts).and_return(true)
+ provider.action_run
end
+ it "should set the command to 'interpreter flags tempfile'" do
+ new_resource.flags '-f'
+ expect(provider.command).to eq(%Q{"perl" -f "#{tempfile.path}"})
+ end
end
end
diff --git a/spec/unit/provider/service/aix_service_spec.rb b/spec/unit/provider/service/aix_service_spec.rb
index a2557354c2..796661145b 100644
--- a/spec/unit/provider/service/aix_service_spec.rb
+++ b/spec/unit/provider/service/aix_service_spec.rb
@@ -55,7 +55,7 @@ describe Chef::Provider::Service::Aix do
expect(@provider).to receive(:is_resource_group?).with(["chef chef 12345 active"])
@provider.load_current_resource
- expect(@current_resource.running).to be_true
+ expect(@current_resource.running).to be_truthy
end
end
@@ -69,7 +69,7 @@ describe Chef::Provider::Service::Aix do
expect(@provider).to receive(:is_resource_group?).with(["chef chef inoperative"])
@provider.load_current_resource
- expect(@current_resource.running).to be_false
+ expect(@current_resource.running).to be_falsey
end
end
end
@@ -83,7 +83,7 @@ describe Chef::Provider::Service::Aix do
it "service is a group" do
expect(@provider).to receive(:shell_out!).with("lssrc -a | grep -w chef").and_return(@status)
@provider.load_current_resource
- expect(@provider.instance_eval("@is_resource_group")).to be_true
+ expect(@provider.instance_eval("@is_resource_group")).to be_truthy
end
end
@@ -95,7 +95,7 @@ describe Chef::Provider::Service::Aix do
it "service is a group" do
expect(@provider).to receive(:shell_out!).with("lssrc -a | grep -w chef").and_return(@status)
@provider.load_current_resource
- expect(@provider.instance_eval("@is_resource_group")).to be_true
+ expect(@provider.instance_eval("@is_resource_group")).to be_truthy
end
end
@@ -107,7 +107,7 @@ describe Chef::Provider::Service::Aix do
it "service is a subsystem" do
expect(@provider).to receive(:shell_out!).with("lssrc -a | grep -w chef").and_return(@status)
@provider.load_current_resource
- expect(@provider.instance_eval("@is_resource_group")).to be_false
+ expect(@provider.instance_eval("@is_resource_group")).to be_falsey
end
end
end
diff --git a/spec/unit/provider/service/arch_service_spec.rb b/spec/unit/provider/service/arch_service_spec.rb
index e71d9adfad..49be0e274c 100644
--- a/spec/unit/provider/service/arch_service_spec.rb
+++ b/spec/unit/provider/service/arch_service_spec.rb
@@ -62,19 +62,19 @@ describe Chef::Provider::Service::Arch, "load_current_resource" do
it "should set running to true if the status command returns 0" do
allow(@provider).to receive(:shell_out).with("/etc/rc.d/chef status").and_return(OpenStruct.new(:exitstatus => 0))
@provider.load_current_resource
- expect(@provider.current_resource.running).to be_true
+ expect(@provider.current_resource.running).to be_truthy
end
it "should set running to false if the status command returns anything except 0" do
allow(@provider).to receive(:shell_out).with("/etc/rc.d/chef status").and_return(OpenStruct.new(:exitstatus => 1))
@provider.load_current_resource
- expect(@provider.current_resource.running).to be_false
+ expect(@provider.current_resource.running).to be_falsey
end
it "should set running to false if the status command raises" do
allow(@provider).to receive(:shell_out).with("/etc/rc.d/chef status").and_raise(Mixlib::ShellOut::ShellCommandFailed)
@provider.load_current_resource
- expect(@provider.current_resource.running).to be_false
+ expect(@provider.current_resource.running).to be_falsey
end
end
@@ -135,13 +135,13 @@ aj 7842 5057 0 21:26 pts/2 00:00:06 poos
RUNNING_PS
allow(@status).to receive(:stdout).and_return(@stdout)
@provider.load_current_resource
- expect(@provider.current_resource.running).to be_true
+ expect(@provider.current_resource.running).to be_truthy
end
it "determines the service is not running when it does not appear in ps" do
allow(@provider).to receive(:shell_out!).and_return(@status)
@provider.load_current_resource
- expect(@provider.current_resource.running).to be_false
+ expect(@provider.current_resource.running).to be_falsey
end
it "should raise an exception if ps fails" do
diff --git a/spec/unit/provider/service/debian_service_spec.rb b/spec/unit/provider/service/debian_service_spec.rb
index b974a6bf9e..a4667e8ce8 100644
--- a/spec/unit/provider/service/debian_service_spec.rb
+++ b/spec/unit/provider/service/debian_service_spec.rb
@@ -67,13 +67,13 @@ describe Chef::Provider::Service::Debian do
end
it "says the service is enabled" do
- expect(@provider.service_currently_enabled?(@provider.get_priority)).to be_true
+ expect(@provider.service_currently_enabled?(@provider.get_priority)).to be_truthy
end
it "stores the 'enabled' state" do
allow(Chef::Resource::Service).to receive(:new).and_return(@current_resource)
expect(@provider.load_current_resource).to equal(@current_resource)
- expect(@current_resource.enabled).to be_true
+ expect(@current_resource.enabled).to be_truthy
end
end
@@ -90,13 +90,13 @@ describe Chef::Provider::Service::Debian do
end
it "says the service is disabled" do
- expect(@provider.service_currently_enabled?(@provider.get_priority)).to be_false
+ expect(@provider.service_currently_enabled?(@provider.get_priority)).to be_falsey
end
it "stores the 'disabled' state" do
allow(Chef::Resource::Service).to receive(:new).and_return(@current_resource)
expect(@provider.load_current_resource).to equal(@current_resource)
- expect(@current_resource.enabled).to be_false
+ expect(@current_resource.enabled).to be_falsey
end
end
@@ -206,13 +206,13 @@ insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop
end
it "says the service is enabled" do
- expect(@provider.service_currently_enabled?(@provider.get_priority)).to be_true
+ expect(@provider.service_currently_enabled?(@provider.get_priority)).to be_truthy
end
it "stores the 'enabled' state" do
allow(Chef::Resource::Service).to receive(:new).and_return(@current_resource)
expect(@provider.load_current_resource).to equal(@current_resource)
- expect(@current_resource.enabled).to be_true
+ expect(@current_resource.enabled).to be_truthy
end
it "stores the start/stop priorities of the service" do
@@ -232,13 +232,13 @@ insserv: dryrun, not creating .depend.boot, .depend.start, and .depend.stop
end
it "says the service is disabled" do
- expect(@provider.service_currently_enabled?(@provider.get_priority)).to be_false
+ expect(@provider.service_currently_enabled?(@provider.get_priority)).to be_falsey
end
it "stores the 'disabled' state" do
allow(Chef::Resource::Service).to receive(:new).and_return(@current_resource)
expect(@provider.load_current_resource).to equal(@current_resource)
- expect(@current_resource.enabled).to be_false
+ expect(@current_resource.enabled).to be_falsey
end
end
end
diff --git a/spec/unit/provider/service/freebsd_service_spec.rb b/spec/unit/provider/service/freebsd_service_spec.rb
index eb55fac820..5a55425d87 100644
--- a/spec/unit/provider/service/freebsd_service_spec.rb
+++ b/spec/unit/provider/service/freebsd_service_spec.rb
@@ -172,14 +172,14 @@ PS_SAMPLE
it "should set running to true" do
allow(provider).to receive(:shell_out!).and_return(status)
provider.determine_current_status!
- expect(current_resource.running).to be_true
+ expect(current_resource.running).to be_truthy
end
end
it "should set running to false if the regex doesn't match" do
allow(provider).to receive(:shell_out!).and_return(status)
provider.determine_current_status!
- expect(current_resource.running).to be_false
+ expect(current_resource.running).to be_falsey
end
it "should set running to nil if ps fails" do
@@ -580,6 +580,13 @@ EOF
expect(provider).not_to receive(:write_rc_conf)
provider.enable_service
end
+
+ it "should remove commented out versions of it being enabled" do
+ allow(current_resource).to receive(:enabled).and_return(false)
+ expect(provider).to receive(:read_rc_conf).and_return([ "foo", "bar", "\# #{new_resource.service_name}_enable=\"YES\"", "\# #{new_resource.service_name}_enable=\"NO\""])
+ expect(provider).to receive(:write_rc_conf).with(["foo", "bar", "#{new_resource.service_name}_enable=\"YES\""])
+ provider.enable_service()
+ end
end
describe Chef::Provider::Service::Freebsd, "disable_service" do
@@ -607,5 +614,12 @@ EOF
expect(provider).not_to receive(:write_rc_conf)
provider.disable_service()
end
+
+ it "should remove commented out versions of it being disabled or enabled" do
+ allow(current_resource).to receive(:enabled).and_return(true)
+ expect(provider).to receive(:read_rc_conf).and_return([ "foo", "bar", "\# #{new_resource.service_name}_enable=\"YES\"", "\# #{new_resource.service_name}_enable=\"NO\""])
+ expect(provider).to receive(:write_rc_conf).with(["foo", "bar", "#{new_resource.service_name}_enable=\"NO\""])
+ provider.disable_service()
+ end
end
end
diff --git a/spec/unit/provider/service/gentoo_service_spec.rb b/spec/unit/provider/service/gentoo_service_spec.rb
index 04734e9c5d..c08982acc3 100644
--- a/spec/unit/provider/service/gentoo_service_spec.rb
+++ b/spec/unit/provider/service/gentoo_service_spec.rb
@@ -48,13 +48,13 @@ describe Chef::Provider::Service::Gentoo do
it "should track when service file is not found in /etc/runlevels" do
@provider.load_current_resource
- expect(@provider.instance_variable_get("@found_script")).to be_false
+ expect(@provider.instance_variable_get("@found_script")).to be_falsey
end
it "should track when service file is found in /etc/runlevels/**/" do
allow(Dir).to receive(:glob).with("/etc/runlevels/**/chef").and_return(["/etc/runlevels/default/chef"])
@provider.load_current_resource
- expect(@provider.instance_variable_get("@found_script")).to be_true
+ expect(@provider.instance_variable_get("@found_script")).to be_truthy
end
describe "when detecting the service enable state" do
@@ -70,7 +70,7 @@ describe Chef::Provider::Service::Gentoo do
end
it "should set enabled to true" do
@provider.load_current_resource
- expect(@current_resource.enabled).to be_true
+ expect(@current_resource.enabled).to be_truthy
end
end
@@ -82,7 +82,7 @@ describe Chef::Provider::Service::Gentoo do
it "should set enabled to false" do
@provider.load_current_resource
- expect(@current_resource.enabled).to be_false
+ expect(@current_resource.enabled).to be_falsey
end
end
@@ -94,7 +94,7 @@ describe Chef::Provider::Service::Gentoo do
it "should set enabled to false" do
@provider.load_current_resource
- expect(@current_resource.enabled).to be_false
+ expect(@current_resource.enabled).to be_falsey
end
end
@@ -108,17 +108,17 @@ describe Chef::Provider::Service::Gentoo do
it "should support the status command automatically" do
@provider.load_current_resource
- expect(@new_resource.supports[:status]).to be_true
+ expect(@new_resource.supports[:status]).to be_truthy
end
it "should support the restart command automatically" do
@provider.load_current_resource
- expect(@new_resource.supports[:restart]).to be_true
+ expect(@new_resource.supports[:restart]).to be_truthy
end
it "should not support the reload command automatically" do
@provider.load_current_resource
- expect(@new_resource.supports[:reload]).not_to be_true
+ expect(@new_resource.supports[:reload]).not_to be_truthy
end
end
diff --git a/spec/unit/provider/service/init_service_spec.rb b/spec/unit/provider/service/init_service_spec.rb
index 5dc5256061..827a4261e1 100644
--- a/spec/unit/provider/service/init_service_spec.rb
+++ b/spec/unit/provider/service/init_service_spec.rb
@@ -64,20 +64,20 @@ PS
it "should set running to true if the status command returns 0" do
allow(@provider).to receive(:shell_out).with("/etc/init.d/#{@current_resource.service_name} status").and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_true
+ expect(@current_resource.running).to be_truthy
end
it "should set running to false if the status command returns anything except 0" do
allow(@status).to receive(:exitstatus).and_return(1)
allow(@provider).to receive(:shell_out).with("/etc/init.d/#{@current_resource.service_name} status").and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_false
+ expect(@current_resource.running).to be_falsey
end
it "should set running to false if the status command raises" do
allow(@provider).to receive(:shell_out).and_raise(Mixlib::ShellOut::ShellCommandFailed)
@provider.load_current_resource
- expect(@current_resource.running).to be_false
+ expect(@current_resource.running).to be_falsey
end
end
@@ -139,13 +139,13 @@ aj 7842 5057 0 21:26 pts/2 00:00:06 poos
RUNNING_PS
allow(@status).to receive(:stdout).and_return(@stdout)
@provider.load_current_resource
- expect(@current_resource.running).to be_true
+ expect(@current_resource.running).to be_truthy
end
it "should set running to false if the regex doesn't match" do
allow(@provider).to receive(:shell_out!).and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_false
+ expect(@current_resource.running).to be_falsey
end
it "should raise an exception if ps fails" do
diff --git a/spec/unit/provider/service/insserv_service_spec.rb b/spec/unit/provider/service/insserv_service_spec.rb
index 6cead238fe..3799daebb4 100644
--- a/spec/unit/provider/service/insserv_service_spec.rb
+++ b/spec/unit/provider/service/insserv_service_spec.rb
@@ -41,7 +41,7 @@ describe Chef::Provider::Service::Insserv do
it "sets the current enabled status to true" do
@provider.load_current_resource
- expect(@provider.current_resource.enabled).to be_true
+ expect(@provider.current_resource.enabled).to be_truthy
end
end
@@ -52,7 +52,7 @@ describe Chef::Provider::Service::Insserv do
it "sets the current enabled status to false" do
@provider.load_current_resource
- expect(@provider.current_resource.enabled).to be_false
+ expect(@provider.current_resource.enabled).to be_falsey
end
end
diff --git a/spec/unit/provider/service/invokercd_service_spec.rb b/spec/unit/provider/service/invokercd_service_spec.rb
index 0b3b799798..81588c80e5 100644
--- a/spec/unit/provider/service/invokercd_service_spec.rb
+++ b/spec/unit/provider/service/invokercd_service_spec.rb
@@ -64,20 +64,20 @@ PS
it "should set running to true if the status command returns 0" do
allow(@provider).to receive(:shell_out).with("/usr/sbin/invoke-rc.d #{@current_resource.service_name} status").and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_true
+ expect(@current_resource.running).to be_truthy
end
it "should set running to false if the status command returns anything except 0" do
allow(@status).to receive(:exitstatus).and_return(1)
allow(@provider).to receive(:shell_out).with("/usr/sbin/invoke-rc.d #{@current_resource.service_name} status").and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_false
+ expect(@current_resource.running).to be_falsey
end
it "should set running to false if the status command raises" do
allow(@provider).to receive(:shell_out).with("/usr/sbin/invoke-rc.d #{@current_resource.service_name} status").and_raise(Mixlib::ShellOut::ShellCommandFailed)
@provider.load_current_resource
- expect(@current_resource.running).to be_false
+ expect(@current_resource.running).to be_falsey
end
end
@@ -125,14 +125,14 @@ RUNNING_PS
@status = double("Status", :exitstatus => 0, :stdout => @stdout)
expect(@provider).to receive(:shell_out!).and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_true
+ expect(@current_resource.running).to be_truthy
end
it "should set running to false if the regex doesn't match" do
@status = double("Status", :exitstatus => 0, :stdout => @stdout)
expect(@provider).to receive(:shell_out!).and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_false
+ expect(@current_resource.running).to be_falsey
end
it "should raise an exception if ps fails" do
diff --git a/spec/unit/provider/service/macosx_spec.rb b/spec/unit/provider/service/macosx_spec.rb
index 0d31ae2ffb..fb751592df 100644
--- a/spec/unit/provider/service/macosx_spec.rb
+++ b/spec/unit/provider/service/macosx_spec.rb
@@ -130,11 +130,11 @@ XML
end
it "sets resource running state to true" do
- expect(provider.current_resource.running).to be_true
+ expect(provider.current_resource.running).to be_truthy
end
it "sets resouce enabled state to true" do
- expect(provider.current_resource.enabled).to be_true
+ expect(provider.current_resource.enabled).to be_truthy
end
end
@@ -164,11 +164,11 @@ SVC_LIST
end
it "sets resource running state to false" do
- expect(provider.current_resource.running).to be_false
+ expect(provider.current_resource.running).to be_falsey
end
it "sets resouce enabled state to true" do
- expect(provider.current_resource.enabled).to be_true
+ expect(provider.current_resource.enabled).to be_truthy
end
end
@@ -180,7 +180,7 @@ SVC_LIST
it "sets service running state to false" do
provider.load_current_resource
- expect(provider.current_resource.running).to be_false
+ expect(provider.current_resource.running).to be_falsey
end
context "and plist for service is not available" do
@@ -190,7 +190,7 @@ SVC_LIST
end
it "sets resouce enabled state to false" do
- expect(provider.current_resource.enabled).to be_false
+ expect(provider.current_resource.enabled).to be_falsey
end
end
@@ -201,7 +201,7 @@ SVC_LIST
end
it "sets resouce enabled state to true" do
- expect(provider.current_resource.enabled).to be_true
+ expect(provider.current_resource.enabled).to be_truthy
end
end
diff --git a/spec/unit/provider/service/openbsd_service_spec.rb b/spec/unit/provider/service/openbsd_service_spec.rb
new file mode 100644
index 0000000000..1b5206470e
--- /dev/null
+++ b/spec/unit/provider/service/openbsd_service_spec.rb
@@ -0,0 +1,543 @@
+#
+# Author:: Bryan McLellan (btm@loftninjas.org)
+# Author:: Scott Bonds (scott@ggr.com)
+# Copyright:: Copyright (c) 2009 Bryan McLellan
+# Copyright:: Copyright (c) 2014 Scott Bonds
+# 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 'spec_helper'
+
+class Chef::Provider::Service::Openbsd
+ public :builtin_service_enable_variable_name
+ public :determine_enabled_status!
+ public :determine_current_status!
+ public :is_enabled?
+ attr_accessor :rc_conf, :rc_conf_local
+end
+
+describe Chef::Provider::Service::Openbsd do
+ let(:node) do
+ node = Chef::Node.new
+ node.automatic_attrs[:command] = {:ps => "ps -ax"}
+ node
+ end
+
+ let(:new_resource) do
+ new_resource = Chef::Resource::Service.new("sndiod")
+ new_resource.pattern("sndiod")
+ new_resource.supports({:status => false})
+ new_resource
+ end
+
+ let(:current_resource) do
+ current_resource = Chef::Resource::Service.new("sndiod")
+ current_resource
+ end
+
+ let(:provider) do
+ events = Chef::EventDispatch::Dispatcher.new
+ run_context = Chef::RunContext.new(node, {}, events)
+ allow(::File).to receive(:read).with('/etc/rc.conf').and_return('')
+ allow(::File).to receive(:read).with('/etc/rc.conf.local').and_return('')
+ provider = Chef::Provider::Service::Openbsd.new(new_resource,run_context)
+ provider.action = :start
+ provider
+ end
+
+ before do
+ allow(Chef::Resource::Service).to receive(:new).and_return(current_resource)
+ end
+
+ def stub_etc_rcd_script
+ allow(::File).to receive(:exist?).and_return(false)
+ expect(::File).to receive(:exist?).with("/etc/rc.d/#{new_resource.service_name}").and_return(true)
+ end
+
+ def run_load_current_resource
+ stub_etc_rcd_script
+ provider.load_current_resource
+ end
+
+ describe Chef::Provider::Service::Openbsd, "initialize" do
+ it "should find /etc/rc.d init scripts" do
+ stub_etc_rcd_script
+ expect(provider.init_command).to eql "/etc/rc.d/sndiod"
+ end
+
+ it "should set init_command to nil if it can't find anything" do
+ expect(::File).to receive(:exist?).with('/etc/rc.d/sndiod').and_return(false)
+ expect(provider.init_command).to be nil
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "determine_current_status!" do
+ before do
+ stub_etc_rcd_script
+ provider.current_resource = current_resource
+ current_resource.service_name(new_resource.service_name)
+ end
+
+ context "when a status command has been specified" do
+ let(:status) { double(:stdout => "", :exitstatus => 0) }
+
+ before do
+ new_resource.status_command("/bin/chefhasmonkeypants status")
+ end
+
+ it "should run the services status command if one has been specified" do
+ expect(provider).to receive(:shell_out).with("/bin/chefhasmonkeypants status").and_return(status)
+ provider.determine_current_status!
+ end
+ end
+
+ context "when the service supports status" do
+ let(:status) { double(:stdout => "", :exitstatus => 0) }
+
+ before do
+ new_resource.supports({:status => true})
+ end
+
+ it "should run '/etc/rc.d/service_name status'" do
+ expect(provider).to receive(:shell_out).with("/etc/rc.d/#{new_resource.service_name} check").and_return(status)
+ provider.determine_current_status!
+ end
+
+ it "should set running to true if the status command returns 0" do
+ expect(provider).to receive(:shell_out).with("/etc/rc.d/#{new_resource.service_name} check").and_return(status)
+ provider.determine_current_status!
+ expect(current_resource.running).to be true
+ end
+
+ it "should set running to false if the status command returns anything except 0" do
+ expect(provider).to receive(:shell_out).with("/etc/rc.d/#{new_resource.service_name} check").and_raise(Mixlib::ShellOut::ShellCommandFailed)
+ provider.determine_current_status!
+ expect(current_resource.running).to be false
+ end
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "determine_enabled_status!" do
+ before do
+ stub_etc_rcd_script
+ provider.current_resource = current_resource
+ current_resource.service_name(new_resource.service_name)
+
+ allow(provider).to receive(:service_enable_variable_name).and_return("#{new_resource.service_name}_enable")
+ end
+
+ context "when the service is builtin" do
+ before do
+ expect(::File).to receive(:open).with("/etc/rc.d/#{new_resource.service_name}")
+ provider.rc_conf = "#{provider.builtin_service_enable_variable_name}=NO"
+ provider.rc_conf_local = lines.join("\n")
+ end
+
+ %w{YES Yes yes yEs YeS}.each do |setting|
+ context "when the enable variable is set to #{setting}" do
+ let(:lines) { [ %Q{#{provider.builtin_service_enable_variable_name}="#{setting}"} ] }
+ it "sets enabled to true" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be true
+ end
+ end
+ end
+
+ %w{No NO no nO None NONE none nOnE}.each do |setting|
+ context "when the enable variable is set to #{setting}" do
+ let(:lines) { [ %Q{#{provider.builtin_service_enable_variable_name}="#{setting}"} ] }
+ it "sets enabled to false" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+ end
+
+ context "when the enable variable is garbage" do
+ let(:lines) { [ %Q{#{provider.builtin_service_enable_variable_name}_enable="alskdjflasdkjflakdfj"} ] }
+ it "sets enabled to false" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+
+ context "when the enable variable partial matches (left) some other service and we are disabled" do
+ let(:lines) { [
+ %Q{thing_#{provider.builtin_service_enable_variable_name}="YES"},
+ %Q{#{provider.builtin_service_enable_variable_name}="NO"},
+ ] }
+ it "sets enabled based on the exact match (false)" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+
+ context "when the enable variable partial matches (right) some other service and we are disabled" do
+ let(:lines) { [
+ %Q{#{provider.builtin_service_enable_variable_name}_thing="YES"},
+ %Q{#{provider.builtin_service_enable_variable_name}},
+ ] }
+ it "sets enabled based on the exact match (false)" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+
+ context "when the enable variable partial matches (left) some other disabled service and we are enabled" do
+ let(:lines) { [
+ %Q{thing_#{provider.builtin_service_enable_variable_name}="NO"},
+ %Q{#{provider.builtin_service_enable_variable_name}="YES"},
+ ] }
+ it "sets enabled based on the exact match (true)" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be true
+ end
+ end
+
+ context "when the enable variable partial matches (right) some other disabled service and we are enabled" do
+ let(:lines) { [
+ %Q{#{provider.builtin_service_enable_variable_name}_thing="NO"},
+ %Q{#{provider.builtin_service_enable_variable_name}="YES"},
+ ] }
+ it "sets enabled based on the exact match (true)" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be true
+ end
+ end
+
+ context "when the enable variable only partial matches (left) some other enabled service" do
+ let(:lines) { [ %Q{thing_#{provider.builtin_service_enable_variable_name}_enable="YES"} ] }
+ it "sets enabled to false" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+
+ context "when the enable variable only partial matches (right) some other enabled service" do
+ let(:lines) { [ %Q{#{provider.builtin_service_enable_variable_name}_thing_enable="YES"} ] }
+ it "sets enabled to false" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+
+ context "when nothing matches" do
+ let(:lines) { [] }
+ it "sets enabled to true" do
+ provider.determine_enabled_status!
+ expect(current_resource.enabled).to be false
+ end
+ end
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "load_current_resource" do
+ before(:each) do
+ stub_etc_rcd_script
+ expect(provider).to receive(:determine_current_status!)
+ current_resource.running(false)
+ allow(provider).to receive(:service_enable_variable_name).and_return "#{new_resource.service_name}_enable"
+ expect(::File).to receive(:open).with("/etc/rc.d/#{new_resource.service_name}")
+ end
+
+ it "should create a current resource with the name of the new resource" do
+ expect(Chef::Resource::Service).to receive(:new).and_return(current_resource)
+ provider.load_current_resource
+ end
+
+ it "should set the current resources service name to the new resources service name" do
+ provider.load_current_resource
+ expect(current_resource.service_name).to eq(new_resource.service_name)
+ end
+
+ it "should return the current resource" do
+ expect(provider.load_current_resource).to eql(current_resource)
+ end
+
+ end
+
+ context "when testing actions" do
+ before(:each) do
+ stub_etc_rcd_script
+ expect(provider).to receive(:determine_current_status!)
+ current_resource.running(false)
+ expect(provider).to receive(:determine_enabled_status!)
+ current_resource.enabled(false)
+ provider.load_current_resource
+ end
+
+ describe Chef::Provider::Service::Openbsd, "start_service" do
+ it "should call the start command if one is specified" do
+ new_resource.start_command("/etc/rc.d/chef startyousillysally")
+ expect(provider).to receive(:shell_out_with_systems_locale!).with("/etc/rc.d/chef startyousillysally")
+ provider.start_service()
+ end
+
+ it "should call '/usr/local/etc/rc.d/service_name start' if no start command is specified" do
+ expect(provider).to receive(:shell_out_with_systems_locale!).with("/etc/rc.d/#{new_resource.service_name} start")
+ provider.start_service()
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "stop_service" do
+ it "should call the stop command if one is specified" do
+ new_resource.stop_command("/etc/init.d/chef itoldyoutostop")
+ expect(provider).to receive(:shell_out_with_systems_locale!).with("/etc/init.d/chef itoldyoutostop")
+ provider.stop_service()
+ end
+
+ it "should call '/usr/local/etc/rc.d/service_name stop' if no stop command is specified" do
+ expect(provider).to receive(:shell_out_with_systems_locale!).with("/etc/rc.d/#{new_resource.service_name} stop")
+ provider.stop_service()
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "restart_service" do
+ it "should call 'restart' on the service_name if the resource supports it" do
+ new_resource.supports({:restart => true})
+ expect(provider).to receive(:shell_out_with_systems_locale!).with("/etc/rc.d/#{new_resource.service_name} restart")
+ provider.restart_service()
+ end
+
+ it "should call the restart_command if one has been specified" do
+ new_resource.restart_command("/etc/init.d/chef restartinafire")
+ expect(provider).to receive(:shell_out_with_systems_locale!).with("/etc/init.d/chef restartinafire")
+ provider.restart_service()
+ end
+
+ it "otherwise it should call stop and start" do
+ expect(provider).to receive(:stop_service)
+ expect(provider).to receive(:start_service)
+ provider.restart_service()
+ end
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "define_resource_requirements" do
+ before do
+ provider.current_resource = current_resource
+ end
+
+ context "when the init script is not found" do
+ before do
+ provider.init_command = nil
+ allow(provider).to receive(:builtin_service_enable_variable_name).and_return("#{new_resource.service_name}_enable")
+ end
+
+ [ "start", "reload", "restart", "enable" ].each do |action|
+ it "should raise an exception when the action is #{action}" do
+ provider.define_resource_requirements
+ provider.action = action
+ expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Service)
+ end
+ end
+
+ [ "stop", "disable" ].each do |action|
+ it "should not raise an error when the action is #{action}" do
+ provider.define_resource_requirements
+ provider.action = action
+ expect { provider.process_resource_requirements }.not_to raise_error
+ end
+ end
+ end
+
+ context "when the init script is found, but the service_enable_variable_name is nil" do
+ before do
+ allow(provider).to receive(:builtin_service_enable_variable_name).and_return(nil)
+ end
+
+ [ "start", "reload", "restart", "enable" ].each do |action|
+ it "should raise an exception when the action is #{action}" do
+ provider.action = action
+ provider.define_resource_requirements
+ expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Service)
+ end
+ end
+
+ [ "stop", "disable" ].each do |action|
+ it "should not raise an error when the action is #{action}" do
+ provider.action = action
+ provider.define_resource_requirements
+ expect { provider.process_resource_requirements }.not_to raise_error
+ end
+ end
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "enable_service" do
+ before do
+ provider.current_resource = current_resource
+ allow(FileUtils).to receive(:touch).with('/etc/rc.conf.local')
+ end
+ context "is builtin and disabled by default" do
+ before do
+ provider.rc_conf = "#{provider.builtin_service_enable_variable_name}=NO"
+ end
+ context "is enabled" do
+ before do
+ provider.rc_conf_local = "#{provider.builtin_service_enable_variable_name}=\"\""
+ end
+ it "should not change rc.conf.local since it is already enabled" do
+ expect(::File).not_to receive(:write)
+ provider.enable_service
+ end
+ end
+ context "is disabled" do
+ before do
+ provider.rc_conf_local = ''
+ end
+ it "should enable the service by adding a line to rc.conf.local" do
+ expect(::File).to receive(:write).with('/etc/rc.conf.local', include("#{provider.builtin_service_enable_variable_name}=\"\""))
+ expect(provider.is_enabled?).to be false
+ provider.enable_service
+ expect(provider.is_enabled?).to be true
+ end
+ end
+ end
+ context "is builtin and enabled by default" do
+ before do
+ provider.rc_conf = "#{provider.builtin_service_enable_variable_name}=\"\""
+ end
+ context "is enabled" do
+ before do
+ provider.rc_conf_local = ''
+ end
+ it "should not change rc.conf.local since it is already enabled" do
+ expect(::File).not_to receive(:write)
+ provider.enable_service
+ end
+ end
+ context "is disabled" do
+ before do
+ provider.rc_conf_local = "#{provider.builtin_service_enable_variable_name}=NO"
+ end
+ it "should enable the service by removing a line from rc.conf.local" do
+ expect(::File).to receive(:write).with('/etc/rc.conf.local', /^(?!#{provider.builtin_service_enable_variable_name})$/)
+ expect(provider.is_enabled?).to be false
+ provider.enable_service
+ expect(provider.is_enabled?).to be true
+ end
+ end
+ end
+ context "is not builtin" do
+ before do
+ provider.rc_conf = ''
+ end
+ context "is enabled" do
+ before do
+ provider.rc_conf_local = "pkg_scripts=\"#{new_resource.service_name}\"\n"
+ end
+ it "should not change rc.conf.local since it is already enabled" do
+ expect(::File).not_to receive(:write)
+ provider.enable_service
+ end
+ end
+ context "is disabled" do
+ before do
+ provider.rc_conf_local = ''
+ end
+ it "should enable the service by adding it to the pkg_scripts list" do
+ expect(::File).to receive(:write).with('/etc/rc.conf.local', "\npkg_scripts=\"#{new_resource.service_name}\"\n")
+ expect(provider.is_enabled?).to be false
+ provider.enable_service
+ expect(provider.is_enabled?).to be true
+ end
+ end
+ end
+ end
+
+ describe Chef::Provider::Service::Openbsd, "disable_service" do
+ before do
+ provider.current_resource = current_resource
+ allow(FileUtils).to receive(:touch).with('/etc/rc.conf.local')
+ end
+ context "is builtin and disabled by default" do
+ before do
+ provider.rc_conf = "#{provider.builtin_service_enable_variable_name}=NO"
+ end
+ context "is enabled" do
+ before do
+ provider.rc_conf_local = "#{provider.builtin_service_enable_variable_name}=\"\""
+ end
+ it "should disable the service by removing its line from rc.conf.local" do
+ expect(::File).to receive(:write).with('/etc/rc.conf.local', /^(?!#{provider.builtin_service_enable_variable_name})$/)
+ expect(provider.is_enabled?).to be true
+ provider.disable_service
+ expect(provider.is_enabled?).to be false
+ end
+ end
+ context "is disabled" do
+ before do
+ provider.rc_conf_local = ''
+ end
+ it "should not change rc.conf.local since it is already disabled" do
+ expect(::File).not_to receive(:write)
+ provider.disable_service
+ end
+ end
+ end
+ context "is builtin and enabled by default" do
+ before do
+ provider.rc_conf = "#{provider.builtin_service_enable_variable_name}=\"\""
+ end
+ context "is enabled" do
+ before do
+ provider.rc_conf_local = ''
+ end
+ it "should disable the service by adding a line to rc.conf.local" do
+ expect(::File).to receive(:write).with('/etc/rc.conf.local', include("#{provider.builtin_service_enable_variable_name}=\"NO\""))
+ expect(provider.is_enabled?).to be true
+ provider.disable_service
+ expect(provider.is_enabled?).to be false
+ end
+ end
+ context "is disabled" do
+ before do
+ provider.rc_conf_local = "#{provider.builtin_service_enable_variable_name}=NO"
+ end
+ it "should not change rc.conf.local since it is already disabled" do
+ expect(::File).not_to receive(:write)
+ provider.disable_service
+ end
+ end
+ end
+ context "is not builtin" do
+ before do
+ provider.rc_conf = ''
+ end
+ context "is enabled" do
+ before do
+ provider.rc_conf_local = "pkg_scripts=\"#{new_resource.service_name}\"\n"
+ end
+ it "should disable the service by removing it from the pkg_scripts list" do
+ expect(::File).to receive(:write).with('/etc/rc.conf.local', /^(?!#{new_resource.service_name})$/)
+ expect(provider.is_enabled?).to be true
+ provider.disable_service
+ expect(provider.is_enabled?).to be false
+ end
+ end
+ context "is disabled" do
+ before do
+ provider.rc_conf_local = ''
+ end
+ it "should not change rc.conf.local since it is already disabled" do
+ expect(::File).not_to receive(:write)
+ provider.disable_service
+ end
+ end
+ end
+ end
+
+end
diff --git a/spec/unit/provider/service/redhat_spec.rb b/spec/unit/provider/service/redhat_spec.rb
index ed3dd5bfa7..73cfec8a6f 100644
--- a/spec/unit/provider/service/redhat_spec.rb
+++ b/spec/unit/provider/service/redhat_spec.rb
@@ -69,9 +69,9 @@ describe "Chef::Provider::Service::Redhat" do
expect(@provider).to receive(:shell_out).with("/sbin/service chef status").and_return(status)
chkconfig = double("Chkconfig", :exitstatus => 0, :stdout => "chef 0:off 1:off 2:off 3:off 4:off 5:on 6:off", :stderr => "")
expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_return(chkconfig)
- expect(@provider.instance_variable_get("@service_missing")).to be_false
+ expect(@provider.instance_variable_get("@service_missing")).to be_falsey
@provider.load_current_resource
- expect(@current_resource.enabled).to be_true
+ expect(@current_resource.enabled).to be_truthy
end
it "sets the current enabled status to false if the regex does not match" do
@@ -79,9 +79,9 @@ describe "Chef::Provider::Service::Redhat" do
expect(@provider).to receive(:shell_out).with("/sbin/service chef status").and_return(status)
chkconfig = double("Chkconfig", :exitstatus => 0, :stdout => "chef 0:off 1:off 2:off 3:off 4:off 5:off 6:off", :stderr => "")
expect(@provider).to receive(:shell_out!).with("/sbin/chkconfig --list chef", :returns => [0,1]).and_return(chkconfig)
- expect(@provider.instance_variable_get("@service_missing")).to be_false
+ expect(@provider.instance_variable_get("@service_missing")).to be_falsey
expect(@provider.load_current_resource).to eql(@current_resource)
- expect(@current_resource.enabled).to be_false
+ expect(@current_resource.enabled).to be_falsey
end
end
diff --git a/spec/unit/provider/service/simple_service_spec.rb b/spec/unit/provider/service/simple_service_spec.rb
index 83ebcb688f..895c559dff 100644
--- a/spec/unit/provider/service/simple_service_spec.rb
+++ b/spec/unit/provider/service/simple_service_spec.rb
@@ -82,13 +82,13 @@ NOMOCKINGSTRINGSPLZ
@status = double("Status", :exitstatus => 0, :stdout => @stdout)
allow(@provider).to receive(:shell_out!).and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_true
+ expect(@current_resource.running).to be_truthy
end
it "should set running to false if the regex doesn't match" do
allow(@provider).to receive(:shell_out!).and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_false
+ expect(@current_resource.running).to be_falsey
end
it "should raise an exception if ps fails" do
diff --git a/spec/unit/provider/service/solaris_smf_service_spec.rb b/spec/unit/provider/service/solaris_smf_service_spec.rb
index 2f790a0ebb..2039408914 100644
--- a/spec/unit/provider/service/solaris_smf_service_spec.rb
+++ b/spec/unit/provider/service/solaris_smf_service_spec.rb
@@ -85,14 +85,14 @@ describe Chef::Provider::Service::Solaris do
it "should not mark service as maintenance" do
allow(@provider).to receive(:shell_out!).and_return(@status)
@provider.load_current_resource
- expect(@provider.maintenance).to be_false
+ expect(@provider.maintenance).to be_falsey
end
it "should mark service as maintenance" do
@status = double("Status", :exitstatus => 0, :stdout => 'state maintenance')
allow(@provider).to receive(:shell_out!).and_return(@status)
@provider.load_current_resource
- expect(@provider.maintenance).to be_true
+ expect(@provider.maintenance).to be_truthy
end
end
@@ -105,15 +105,15 @@ describe Chef::Provider::Service::Solaris do
it "should call svcadm enable -s chef" do
expect(@provider).not_to receive(:shell_out!).with("/usr/sbin/svcadm clear #{@current_resource.service_name}")
expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm enable -s #{@current_resource.service_name}").and_return(@status)
- expect(@provider.enable_service).to be_true
- expect(@current_resource.enabled).to be_true
+ expect(@provider.enable_service).to be_truthy
+ expect(@current_resource.enabled).to be_truthy
end
it "should call svcadm enable -s chef for start_service" do
expect(@provider).not_to receive(:shell_out!).with("/usr/sbin/svcadm clear #{@current_resource.service_name}")
expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm enable -s #{@current_resource.service_name}").and_return(@status)
- expect(@provider.start_service).to be_true
- expect(@current_resource.enabled).to be_true
+ expect(@provider.start_service).to be_truthy
+ expect(@current_resource.enabled).to be_truthy
end
it "should call svcadm clear chef for start_service when state maintenance" do
@@ -122,8 +122,8 @@ describe Chef::Provider::Service::Solaris do
@provider.load_current_resource
expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm clear #{@current_resource.service_name}").and_return(@status)
expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm enable -s #{@current_resource.service_name}").and_return(@status)
- expect(@provider.enable_service).to be_true
- expect(@current_resource.enabled).to be_true
+ expect(@provider.enable_service).to be_truthy
+ expect(@current_resource.enabled).to be_truthy
end
end
@@ -135,14 +135,14 @@ describe Chef::Provider::Service::Solaris do
it "should call svcadm disable -s chef" do
expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm disable -s chef").and_return(@status)
- expect(@provider.disable_service).to be_true
- expect(@current_resource.enabled).to be_false
+ expect(@provider.disable_service).to be_truthy
+ expect(@current_resource.enabled).to be_falsey
end
it "should call svcadm disable -s chef for stop_service" do
expect(@provider).to receive(:shell_out!).with("/usr/sbin/svcadm disable -s chef").and_return(@status)
- expect(@provider.stop_service).to be_true
- expect(@current_resource.enabled).to be_false
+ expect(@provider.stop_service).to be_truthy
+ expect(@current_resource.enabled).to be_falsey
end
end
@@ -170,13 +170,13 @@ describe Chef::Provider::Service::Solaris do
it "should be marked not running" do
expect(@provider).to receive(:shell_out!).with("/bin/svcs -l chef", {:returns=>[0, 1]}).and_return(@status)
@provider.service_status
- expect(@current_resource.running).to be_false
+ expect(@current_resource.running).to be_falsey
end
it "should be marked not enabled" do
expect(@provider).to receive(:shell_out!).with("/bin/svcs -l chef", {:returns=>[0, 1]}).and_return(@status)
@provider.service_status
- expect(@current_resource.enabled).to be_false
+ expect(@current_resource.enabled).to be_falsey
end
end
diff --git a/spec/unit/provider/service/systemd_service_spec.rb b/spec/unit/provider/service/systemd_service_spec.rb
index 5ba3bed184..90b669a459 100644
--- a/spec/unit/provider/service/systemd_service_spec.rb
+++ b/spec/unit/provider/service/systemd_service_spec.rb
@@ -257,14 +257,22 @@ describe Chef::Provider::Service::Systemd do
end
end
- it "should return true if '#{systemctl_path} is-enabled service_name' returns 0" do
- expect(provider).to receive(:shell_out).with("#{systemctl_path} is-enabled #{service_name} --quiet").and_return(shell_out_success)
- expect(provider.is_enabled?).to be true
- end
+ describe "is_enabled?" do
+ before(:each) do
+ provider.current_resource = current_resource
+ current_resource.service_name(service_name)
+ allow(provider).to receive(:which).with("systemctl").and_return("#{systemctl_path}")
+ end
+
+ it "should return true if '#{systemctl_path} is-enabled service_name' returns 0" do
+ expect(provider).to receive(:shell_out).with("#{systemctl_path} is-enabled #{service_name} --quiet").and_return(shell_out_success)
+ expect(provider.is_enabled?).to be true
+ end
- it "should return false if '#{systemctl_path} is-enabled service_name' returns anything except 0" do
- expect(provider).to receive(:shell_out).with("#{systemctl_path} is-enabled #{service_name} --quiet").and_return(shell_out_failure)
- expect(provider.is_enabled?).to be false
+ it "should return false if '#{systemctl_path} is-enabled service_name' returns anything except 0" do
+ expect(provider).to receive(:shell_out).with("#{systemctl_path} is-enabled #{service_name} --quiet").and_return(shell_out_failure)
+ expect(provider.is_enabled?).to be false
+ end
end
end
end
diff --git a/spec/unit/provider/service/upstart_service_spec.rb b/spec/unit/provider/service/upstart_service_spec.rb
index 69948fbc6a..ca7ce8f930 100644
--- a/spec/unit/provider/service/upstart_service_spec.rb
+++ b/spec/unit/provider/service/upstart_service_spec.rb
@@ -108,14 +108,14 @@ describe Chef::Provider::Service::Upstart do
@stdout = StringIO.new("rsyslog start/running")
allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_true
+ expect(@current_resource.running).to be_truthy
end
it "should set running to false if the status command returns anything except 0" do
@stdout = StringIO.new("rsyslog stop/waiting")
allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_false
+ expect(@current_resource.running).to be_falsey
end
end
@@ -124,14 +124,14 @@ describe Chef::Provider::Service::Upstart do
@stdout = StringIO.new("rsyslog (start) running, process 32225")
allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_true
+ expect(@current_resource.running).to be_truthy
end
it "should set running to false if the status command returns anything except 0" do
@stdout = StringIO.new("rsyslog (stop) waiting")
allow(@provider).to receive(:popen4).and_yield(@pid, @stdin, @stdout, @stderr).and_return(@status)
@provider.load_current_resource
- expect(@current_resource.running).to be_false
+ expect(@current_resource.running).to be_falsey
end
end
diff --git a/spec/unit/provider/service/windows_spec.rb b/spec/unit/provider/service/windows_spec.rb
index f35f169bc4..784a2232b2 100644
--- a/spec/unit/provider/service/windows_spec.rb
+++ b/spec/unit/provider/service/windows_spec.rb
@@ -18,6 +18,7 @@
#
require 'spec_helper'
+require 'mixlib/shellout'
describe Chef::Provider::Service::Windows, "load_current_resource" do
before(:each) do
@@ -38,6 +39,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
allow(Win32::Service).to receive(:config_info).with(@new_resource.service_name).and_return(
double("ConfigStruct", :start_type => "auto start"))
allow(Win32::Service).to receive(:exists?).and_return(true)
+ allow(Win32::Service).to receive(:configure).and_return(Win32::Service)
end
it "should set the current resources service name to the new resources service name" do
@@ -51,12 +53,12 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
it "should set the current resources status" do
@provider.load_current_resource
- expect(@provider.current_resource.running).to be_true
+ expect(@provider.current_resource.running).to be_truthy
end
it "should set the current resources start type" do
@provider.load_current_resource
- expect(@provider.current_resource.enabled).to be_true
+ expect(@provider.current_resource.enabled).to be_truthy
end
it "does not set the current resources start type if it is neither AUTO START or DISABLED" do
@@ -77,20 +79,20 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@new_resource.start_command "sc start chef"
expect(@provider).to receive(:shell_out!).with("#{@new_resource.start_command}").and_return("Starting custom service")
@provider.start_service
- expect(@new_resource.updated_by_last_action?).to be_true
+ expect(@new_resource.updated_by_last_action?).to be_truthy
end
it "should use the built-in command if no start command is specified" do
expect(Win32::Service).to receive(:start).with(@new_resource.service_name)
@provider.start_service
- expect(@new_resource.updated_by_last_action?).to be_true
+ expect(@new_resource.updated_by_last_action?).to be_truthy
end
it "should do nothing if the service does not exist" do
allow(Win32::Service).to receive(:exists?).with(@new_resource.service_name).and_return(false)
expect(Win32::Service).not_to receive(:start).with(@new_resource.service_name)
@provider.start_service
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
it "should do nothing if the service is running" do
@@ -99,7 +101,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@provider.load_current_resource
expect(Win32::Service).not_to receive(:start).with(@new_resource.service_name)
@provider.start_service
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
it "should raise an error if the service is paused" do
@@ -108,7 +110,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@provider.load_current_resource
expect(Win32::Service).not_to receive(:start).with(@new_resource.service_name)
expect { @provider.start_service }.to raise_error( Chef::Exceptions::Service )
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
it "should wait and continue if the service is in start_pending" do
@@ -119,7 +121,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@provider.load_current_resource
expect(Win32::Service).not_to receive(:start).with(@new_resource.service_name)
@provider.start_service
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
it "should fail if the service is in stop_pending" do
@@ -128,9 +130,29 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@provider.load_current_resource
expect(Win32::Service).not_to receive(:start).with(@new_resource.service_name)
expect { @provider.start_service }.to raise_error( Chef::Exceptions::Service )
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
+ describe "running as a different account" do
+ let(:old_run_as_user) { @new_resource.run_as_user }
+ let(:old_run_as_password) { @new_resource.run_as_password }
+
+ before {
+ @new_resource.run_as_user(".\\wallace")
+ @new_resource.run_as_password("Wensleydale")
+ }
+
+ after {
+ @new_resource.run_as_user(old_run_as_user)
+ @new_resource.run_as_password(old_run_as_password)
+ }
+
+ it "should call #grant_service_logon if the :run_as_user and :run_as_password attributes are present" do
+ expect(Win32::Service).to receive(:start)
+ expect(@provider).to receive(:grant_service_logon).and_return(true)
+ @provider.start_service
+ end
+ end
end
@@ -146,20 +168,20 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@new_resource.stop_command "sc stop chef"
expect(@provider).to receive(:shell_out!).with("#{@new_resource.stop_command}").and_return("Stopping custom service")
@provider.stop_service
- expect(@new_resource.updated_by_last_action?).to be_true
+ expect(@new_resource.updated_by_last_action?).to be_truthy
end
it "should use the built-in command if no stop command is specified" do
expect(Win32::Service).to receive(:stop).with(@new_resource.service_name)
@provider.stop_service
- expect(@new_resource.updated_by_last_action?).to be_true
+ expect(@new_resource.updated_by_last_action?).to be_truthy
end
it "should do nothing if the service does not exist" do
allow(Win32::Service).to receive(:exists?).with(@new_resource.service_name).and_return(false)
expect(Win32::Service).not_to receive(:stop).with(@new_resource.service_name)
@provider.stop_service
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
it "should do nothing if the service is stopped" do
@@ -168,7 +190,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@provider.load_current_resource
expect(Win32::Service).not_to receive(:stop).with(@new_resource.service_name)
@provider.stop_service
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
it "should raise an error if the service is paused" do
@@ -177,7 +199,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@provider.load_current_resource
expect(Win32::Service).not_to receive(:start).with(@new_resource.service_name)
expect { @provider.stop_service }.to raise_error( Chef::Exceptions::Service )
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
it "should wait and continue if the service is in stop_pending" do
@@ -188,7 +210,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@provider.load_current_resource
expect(Win32::Service).not_to receive(:stop).with(@new_resource.service_name)
@provider.stop_service
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
it "should fail if the service is in start_pending" do
@@ -197,7 +219,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@provider.load_current_resource
expect(Win32::Service).not_to receive(:stop).with(@new_resource.service_name)
expect { @provider.stop_service }.to raise_error( Chef::Exceptions::Service )
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
it "should pass custom timeout to the stop command if provided" do
@@ -208,7 +230,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
Timeout.timeout(2) do
expect { @provider.stop_service }.to raise_error(Timeout::Error)
end
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
end
@@ -219,7 +241,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
@new_resource.restart_command "sc restart"
expect(@provider).to receive(:shell_out!).with("#{@new_resource.restart_command}")
@provider.restart_service
- expect(@new_resource.updated_by_last_action?).to be_true
+ expect(@new_resource.updated_by_last_action?).to be_truthy
end
it "should stop then start the service if it is running" do
@@ -231,7 +253,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
expect(Win32::Service).to receive(:stop).with(@new_resource.service_name)
expect(Win32::Service).to receive(:start).with(@new_resource.service_name)
@provider.restart_service
- expect(@new_resource.updated_by_last_action?).to be_true
+ expect(@new_resource.updated_by_last_action?).to be_truthy
end
it "should just start the service if it is stopped" do
@@ -241,7 +263,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
double("StatusStruct", :current_state => "running"))
expect(Win32::Service).to receive(:start).with(@new_resource.service_name)
@provider.restart_service
- expect(@new_resource.updated_by_last_action?).to be_true
+ expect(@new_resource.updated_by_last_action?).to be_truthy
end
it "should do nothing if the service does not exist" do
@@ -249,7 +271,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
expect(Win32::Service).not_to receive(:stop).with(@new_resource.service_name)
expect(Win32::Service).not_to receive(:start).with(@new_resource.service_name)
@provider.restart_service
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
end
@@ -263,14 +285,14 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
it "should enable service" do
expect(Win32::Service).to receive(:configure).with(:service_name => @new_resource.service_name, :start_type => Win32::Service::AUTO_START)
@provider.enable_service
- expect(@new_resource.updated_by_last_action?).to be_true
+ expect(@new_resource.updated_by_last_action?).to be_truthy
end
it "should do nothing if the service does not exist" do
allow(Win32::Service).to receive(:exists?).with(@new_resource.service_name).and_return(false)
expect(Win32::Service).not_to receive(:configure)
@provider.enable_service
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
end
@@ -315,14 +337,14 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
it "should disable service" do
expect(Win32::Service).to receive(:configure)
@provider.disable_service
- expect(@new_resource.updated_by_last_action?).to be_true
+ expect(@new_resource.updated_by_last_action?).to be_truthy
end
it "should do nothing if the service does not exist" do
allow(Win32::Service).to receive(:exists?).with(@new_resource.service_name).and_return(false)
expect(Win32::Service).not_to receive(:configure)
@provider.disable_service
- expect(@new_resource.updated_by_last_action?).to be_false
+ expect(@new_resource.updated_by_last_action?).to be_falsey
end
end
@@ -364,4 +386,76 @@ describe Chef::Provider::Service::Windows, "load_current_resource" do
expect { @provider.send(:set_startup_type, :fire_truck) }.to raise_error(Chef::Exceptions::ConfigurationError)
end
end
+
+ shared_context "testing private methods" do
+
+ let(:private_methods) {
+ described_class.private_instance_methods
+ }
+
+ before {
+ described_class.send(:public, *private_methods)
+ }
+
+ after {
+ described_class.send(:private, *private_methods)
+ }
+ end
+
+ describe "grant_service_logon" do
+ include_context "testing private methods"
+
+ let(:username) { "unit_test_user" }
+ let(:success_string) { "The task has completed successfully.\r\nSee logfile etc." }
+ let(:failure_string) { "Look on my works, ye Mighty, and despair!" }
+ let(:command) {
+ dbfile = @provider.grant_dbfile_name(username)
+ policyfile = @provider.grant_policyfile_name(username)
+ logfile = @provider.grant_logfile_name(username)
+
+ %Q{secedit.exe /configure /db "#{dbfile}" /cfg "#{policyfile}" /areas USER_RIGHTS SECURITYPOLICY SERVICES /log "#{logfile}"}
+ }
+ let(:shellout_env) { {:environment=>{"LC_ALL"=>"en_US.UTF-8"}} }
+
+ before {
+ expect_any_instance_of(described_class).to receive(:shell_out).with(command).and_call_original
+ expect_any_instance_of(Mixlib::ShellOut).to receive(:run_command).and_return(nil)
+ }
+
+ after {
+ # only needed for the second test.
+ ::File.delete(@provider.grant_policyfile_name(username)) rescue nil
+ ::File.delete(@provider.grant_logfile_name(username)) rescue nil
+ ::File.delete(@provider.grant_dbfile_name(username)) rescue nil
+ }
+
+ it "calls Mixlib::Shellout with the correct command string" do
+ expect_any_instance_of(Mixlib::ShellOut).to receive(:exitstatus).and_return(0)
+ expect(@provider.grant_service_logon(username)).to equal true
+ end
+
+ it "raises an exception when the grant command fails" do
+ expect_any_instance_of(Mixlib::ShellOut).to receive(:exitstatus).and_return(1)
+ expect_any_instance_of(Mixlib::ShellOut).to receive(:stdout).and_return(failure_string)
+ expect { @provider.grant_service_logon(username) }.to raise_error(Chef::Exceptions::Service)
+ end
+ end
+
+ describe "cleaning usernames" do
+ include_context "testing private methods"
+
+ it "correctly reformats usernames to create valid filenames" do
+ expect(@provider.clean_username_for_path("\\\\problem username/oink.txt")).to eq("_problem_username_oink_txt")
+ expect(@provider.clean_username_for_path("boring_username")).to eq("boring_username")
+ end
+
+ it "correctly reformats usernames for the policy file" do
+ expect(@provider.canonicalize_username(".\\maryann")).to eq("maryann")
+ expect(@provider.canonicalize_username("maryann")).to eq("maryann")
+
+ expect(@provider.canonicalize_username("\\\\maryann")).to eq("maryann")
+ expect(@provider.canonicalize_username("mydomain\\\\maryann")).to eq("mydomain\\\\maryann")
+ expect(@provider.canonicalize_username("\\\\mydomain\\\\maryann")).to eq("mydomain\\\\maryann")
+ end
+ end
end
diff --git a/spec/unit/provider/service_spec.rb b/spec/unit/provider/service_spec.rb
index e60b08e7f0..17bade55b6 100644
--- a/spec/unit/provider/service_spec.rb
+++ b/spec/unit/provider/service_spec.rb
@@ -69,7 +69,7 @@ describe Chef::Provider::Service do
describe "action_start" do
it "should start the service if it isn't running and set the resource as updated" do
@current_resource.running(false)
- expect(@provider).to receive(:start_service).with.and_return(true)
+ expect(@provider).to receive(:start_service).with(no_args).and_return(true)
@provider.run_action(:start)
expect(@provider.new_resource).to be_updated
end
diff --git a/spec/unit/provider/user/dscl_spec.rb b/spec/unit/provider/user/dscl_spec.rb
index c8dbef770e..5ea037d944 100644
--- a/spec/unit/provider/user/dscl_spec.rb
+++ b/spec/unit/provider/user/dscl_spec.rb
@@ -171,7 +171,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
describe "uid_used?" do
it "should return false if not given any valid uid number" do
- expect(provider.uid_used?(nil)).to be_false
+ expect(provider.uid_used?(nil)).to be_falsey
end
describe "when called with a user id" do
@@ -180,11 +180,11 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
end
it "should return true for a used uid number" do
- expect(provider.uid_used?(500)).to be_true
+ expect(provider.uid_used?(500)).to be_truthy
end
it "should return false for an unused uid number" do
- expect(provider.uid_used?(501)).to be_false
+ expect(provider.uid_used?(501)).to be_falsey
end
end
end
@@ -400,7 +400,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
it "should set @user_exists" do
provider.load_current_resource
- expect(provider.instance_variable_get(:@user_exists)).to be_false
+ expect(provider.instance_variable_get(:@user_exists)).to be_falsey
end
it "should set username" do
@@ -422,7 +422,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
it "collects the user data correctly" do
provider.load_current_resource
expect(provider.current_resource.comment).to eq("vagrant")
- expect(provider.current_resource.uid).to eq("11112222-3333-4444-AAAA-BBBBCCCCDDDD")
+ expect(provider.current_resource.uid).to eq("501")
expect(provider.current_resource.gid).to eq("80")
expect(provider.current_resource.home).to eq("/Users/vagrant")
expect(provider.current_resource.shell).to eq("/bin/bash")
@@ -434,7 +434,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
it "diverged_password? should report false" do
provider.load_current_resource
- expect(provider.diverged_password?).to be_false
+ expect(provider.diverged_password?).to be_falsey
end
end
@@ -443,7 +443,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
it "diverged_password? should report true" do
provider.load_current_resource
- expect(provider.diverged_password?).to be_true
+ expect(provider.diverged_password?).to be_truthy
end
end
@@ -453,7 +453,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
it "diverged_password? should report false" do
provider.load_current_resource
- expect(provider.diverged_password?).to be_false
+ expect(provider.diverged_password?).to be_falsey
end
end
@@ -462,7 +462,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
it "diverged_password? should report true" do
provider.load_current_resource
- expect(provider.diverged_password?).to be_true
+ expect(provider.diverged_password?).to be_truthy
end
end
@@ -472,7 +472,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
it "diverged_password? should report false" do
provider.load_current_resource
- expect(provider.diverged_password?).to be_false
+ expect(provider.diverged_password?).to be_falsey
end
end
end
@@ -487,7 +487,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
it "collects the user data correctly" do
provider.load_current_resource
expect(provider.current_resource.comment).to eq("vagrant")
- expect(provider.current_resource.uid).to eq("11112222-3333-4444-AAAA-BBBBCCCCDDDD")
+ expect(provider.current_resource.uid).to eq("501")
expect(provider.current_resource.gid).to eq("80")
expect(provider.current_resource.home).to eq("/Users/vagrant")
expect(provider.current_resource.shell).to eq("/bin/bash")
@@ -513,7 +513,7 @@ e68d1f9821b26689312366")
it "collects the user data correctly" do
provider.load_current_resource
expect(provider.current_resource.comment).to eq("vagrant")
- expect(provider.current_resource.uid).to eq("11112222-3333-4444-AAAA-BBBBCCCCDDDD")
+ expect(provider.current_resource.uid).to eq("501")
expect(provider.current_resource.gid).to eq("80")
expect(provider.current_resource.home).to eq("/Users/vagrant")
expect(provider.current_resource.shell).to eq("/bin/bash")
@@ -525,7 +525,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
describe "when a plain text password is set" do
it "reports password needs to be updated" do
provider.load_current_resource
- expect(provider.diverged_password?).to be_true
+ expect(provider.diverged_password?).to be_truthy
end
end
@@ -536,7 +536,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
it "reports password needs to be updated" do
provider.load_current_resource
- expect(provider.diverged_password?).to be_true
+ expect(provider.diverged_password?).to be_truthy
end
end
end
@@ -551,7 +551,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
it "collects the user data correctly" do
provider.load_current_resource
expect(provider.current_resource.comment).to eq("vagrant")
- expect(provider.current_resource.uid).to eq("11112222-3333-4444-AAAA-BBBBCCCCDDDD")
+ expect(provider.current_resource.uid).to eq("501")
expect(provider.current_resource.gid).to eq("80")
expect(provider.current_resource.home).to eq("/Users/vagrant")
expect(provider.current_resource.shell).to eq("/bin/bash")
@@ -565,7 +565,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
it "diverged_password? should report false" do
provider.load_current_resource
- expect(provider.diverged_password?).to be_false
+ expect(provider.diverged_password?).to be_falsey
end
end
@@ -574,7 +574,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
it "diverged_password? should report true" do
provider.load_current_resource
- expect(provider.diverged_password?).to be_true
+ expect(provider.diverged_password?).to be_truthy
end
end
@@ -585,7 +585,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
it "diverged_password? should report true" do
provider.load_current_resource
- expect(provider.diverged_password?).to be_true
+ expect(provider.diverged_password?).to be_truthy
end
end
@@ -596,7 +596,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
it "diverged_password? should report true" do
provider.load_current_resource
- expect(provider.diverged_password?).to be_true
+ expect(provider.diverged_password?).to be_truthy
end
end
@@ -607,7 +607,15 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
it "diverged_password? should report true" do
provider.load_current_resource
- expect(provider.diverged_password?).to be_true
+ expect(provider.diverged_password?).to be_truthy
+ end
+ end
+
+ describe "when salt isn't found" do
+ it "diverged_password? should report true" do
+ provider.load_current_resource
+ provider.current_resource.salt(nil)
+ expect(provider.diverged_password?).to be_truthy
end
end
end
@@ -616,23 +624,23 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
describe "salted_sha512_pbkdf2?" do
it "should return true when the string is a salted_sha512_pbkdf2 hash" do
- expect(provider.salted_sha512_pbkdf2?(salted_sha512_pbkdf2_password)).to be_true
+ expect(provider.salted_sha512_pbkdf2?(salted_sha512_pbkdf2_password)).to be_truthy
end
it "should return false otherwise" do
- expect(provider.salted_sha512_pbkdf2?(salted_sha512_password)).to be_false
- expect(provider.salted_sha512_pbkdf2?("any other string")).to be_false
+ expect(provider.salted_sha512_pbkdf2?(salted_sha512_password)).to be_falsey
+ expect(provider.salted_sha512_pbkdf2?("any other string")).to be_falsey
end
end
describe "salted_sha512?" do
it "should return true when the string is a salted_sha512_pbkdf2 hash" do
- expect(provider.salted_sha512_pbkdf2?(salted_sha512_pbkdf2_password)).to be_true
+ expect(provider.salted_sha512_pbkdf2?(salted_sha512_pbkdf2_password)).to be_truthy
end
it "should return false otherwise" do
- expect(provider.salted_sha512?(salted_sha512_pbkdf2_password)).to be_false
- expect(provider.salted_sha512?("any other string")).to be_false
+ expect(provider.salted_sha512?(salted_sha512_pbkdf2_password)).to be_falsey
+ expect(provider.salted_sha512?("any other string")).to be_falsey
end
end
@@ -649,7 +657,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
shadow_info = provider.prepare_password_shadow_info
expect(shadow_info).to have_key("SALTED-SHA512")
info = shadow_info["SALTED-SHA512"].string.unpack('H*').first
- expect(provider.salted_sha512?(info)).to be_true
+ expect(provider.salted_sha512?(info)).to be_truthy
end
end
@@ -660,7 +668,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
shadow_info = provider.prepare_password_shadow_info
expect(shadow_info).to have_key("SALTED-SHA512")
info = shadow_info["SALTED-SHA512"].string.unpack('H*').first
- expect(provider.salted_sha512?(info)).to be_true
+ expect(provider.salted_sha512?(info)).to be_truthy
expect(info).to eq(vagrant_sha_512)
end
end
@@ -682,7 +690,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
expect(shadow_info["SALTED-SHA512-PBKDF2"]).to have_key("salt")
expect(shadow_info["SALTED-SHA512-PBKDF2"]).to have_key("iterations")
info = shadow_info["SALTED-SHA512-PBKDF2"]["entropy"].string.unpack('H*').first
- expect(provider.salted_sha512_pbkdf2?(info)).to be_true
+ expect(provider.salted_sha512_pbkdf2?(info)).to be_truthy
end
end
@@ -698,7 +706,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
expect(shadow_info["SALTED-SHA512-PBKDF2"]).to have_key("salt")
expect(shadow_info["SALTED-SHA512-PBKDF2"]).to have_key("iterations")
info = shadow_info["SALTED-SHA512-PBKDF2"]["entropy"].string.unpack('H*').first
- expect(provider.salted_sha512_pbkdf2?(info)).to be_true
+ expect(provider.salted_sha512_pbkdf2?(info)).to be_truthy
expect(info).to eq(vagrant_sha_512_pbkdf2)
end
end
diff --git a/spec/unit/provider/user_spec.rb b/spec/unit/provider/user_spec.rb
index 44434794e7..381168647b 100644
--- a/spec/unit/provider/user_spec.rb
+++ b/spec/unit/provider/user_spec.rb
@@ -91,7 +91,7 @@ describe Chef::Provider::User do
expect(@current_resource.username).to eq(@new_resource.username)
end
- it "should change the encoding of gecos to the encoding of the new resource", :ruby_gte_19_only do
+ it "should change the encoding of gecos to the encoding of the new resource" do
@pw_user.gecos.force_encoding('ASCII-8BIT')
@provider.load_current_resource
expect(@provider.current_resource.comment.encoding).to eq(@new_resource.comment.encoding)
diff --git a/spec/unit/provider_resolver_spec.rb b/spec/unit/provider_resolver_spec.rb
index ab19ff4bee..a9fa08ebfd 100644
--- a/spec/unit/provider_resolver_spec.rb
+++ b/spec/unit/provider_resolver_spec.rb
@@ -511,10 +511,11 @@ describe Chef::ProviderResolver do
supported_providers = [
:apt_package, :bash, :breakpoint, :chef_gem, :cookbook_file, :csh, :deploy,
- :deploy_revision, :directory, :dpkg_package, :easy_install_package,
- :erl_call, :execute, :file, :gem_package, :git, :http_request, :link, :log, :pacman_package, :paludis_package,
- :perl, :python, :remote_directory, :route, :rpm_package, :ruby, :ruby_block, :script,
- :subversion, :template, :timestamped_deploy, :whyrun_safe_ruby_block, :yum_package, :homebrew_package,
+ :deploy_revision, :directory, :dpkg_package, :easy_install_package, :erl_call,
+ :execute, :file, :gem_package, :git, :homebrew_package, :http_request, :link,
+ :log, :macports_package, :pacman_package, :paludis_package, :perl, :python,
+ :remote_directory, :route, :rpm_package, :ruby, :ruby_block, :script, :subversion,
+ :template, :timestamped_deploy, :whyrun_safe_ruby_block, :yum_package,
]
supported_providers.each do |static_resource|
@@ -530,9 +531,8 @@ describe Chef::ProviderResolver do
end
unsupported_providers = [
- :bff_package, :dsc_script, :ips_package, :macports_package,
- :smartos_package, :solaris_package, :windows_package,
- :windows_service,
+ :bff_package, :dsc_script, :ips_package, :smartos_package,
+ :solaris_package, :windows_package, :windows_service,
]
unsupported_providers.each do |static_resource|
diff --git a/spec/unit/provider_spec.rb b/spec/unit/provider_spec.rb
index 9b89fc1888..5a21b094d0 100644
--- a/spec/unit/provider_spec.rb
+++ b/spec/unit/provider_spec.rb
@@ -74,23 +74,23 @@ describe Chef::Provider do
end
it "should store the resource passed to new as new_resource" do
- @provider.new_resource.should eql(@resource)
+ expect(@provider.new_resource).to eql(@resource)
end
it "should store the node passed to new as node" do
- @provider.node.should eql(@node)
+ expect(@provider.node).to eql(@node)
end
it "should have nil for current_resource by default" do
- @provider.current_resource.should eql(nil)
+ expect(@provider.current_resource).to eql(nil)
end
it "should not support whyrun by default" do
- @provider.send(:whyrun_supported?).should eql(false)
+ expect(@provider.send(:whyrun_supported?)).to eql(false)
end
it "should return true for action_nothing" do
- @provider.action_nothing.should eql(true)
+ expect(@provider.action_nothing).to eql(true)
end
it "evals embedded recipes with a pristine resource collection" do
@@ -98,27 +98,27 @@ describe Chef::Provider do
temporary_collection = nil
snitch = Proc.new {temporary_collection = @run_context.resource_collection}
@provider.send(:recipe_eval, &snitch)
- temporary_collection.should be_an_instance_of(Chef::ResourceCollection)
- @provider.run_context.instance_variable_get(:@resource_collection).should == "doesn't matter what this is"
+ expect(temporary_collection).to be_an_instance_of(Chef::ResourceCollection)
+ expect(@provider.run_context.instance_variable_get(:@resource_collection)).to eq("doesn't matter what this is")
end
it "does not re-load recipes when creating the temporary run context" do
# we actually want to test that RunContext#load is never called, but we
# can't stub all instances of an object with rspec's mocks. :/
- Chef::RunContext.stub(:new).and_raise("not supposed to happen")
+ allow(Chef::RunContext).to receive(:new).and_raise("not supposed to happen")
snitch = Proc.new {temporary_collection = @run_context.resource_collection}
@provider.send(:recipe_eval, &snitch)
end
context "when no converge actions are queued" do
before do
- @provider.stub(:whyrun_supported?).and_return(true)
- @provider.stub(:load_current_resource)
+ allow(@provider).to receive(:whyrun_supported?).and_return(true)
+ allow(@provider).to receive(:load_current_resource)
end
it "does not mark the new resource as updated" do
- @resource.should_not be_updated
- @resource.should_not be_updated_by_last_action
+ expect(@resource).not_to be_updated
+ expect(@resource).not_to be_updated_by_last_action
end
end
@@ -129,23 +129,23 @@ describe Chef::Provider do
end
it "should tell us that it does support whyrun" do
- @provider.should be_whyrun_supported
+ expect(@provider).to be_whyrun_supported
end
it "queues up converge actions" do
@provider.action_foo
- @provider.send(:converge_actions).should have(1).actions
+ expect(@provider.send(:converge_actions).actions.size).to eq(1)
end
it "executes pending converge actions to converge the system" do
@provider.run_action(:foo)
- @provider.instance_variable_get(:@system_state_altered).should be_true
+ expect(@provider.instance_variable_get(:@system_state_altered)).to be_truthy
end
it "marks the resource as updated" do
@provider.run_action(:foo)
- @resource.should be_updated
- @resource.should be_updated_by_last_action
+ expect(@resource).to be_updated
+ expect(@resource).to be_updated_by_last_action
end
end
@@ -160,20 +160,20 @@ describe Chef::Provider do
end
it "should tell us that it doesn't support whyrun" do
- @provider.should_not be_whyrun_supported
+ expect(@provider).not_to be_whyrun_supported
end
it "should automatically generate a converge_by block on the provider's behalf" do
@provider.run_action(:foo)
- @provider.send(:converge_actions).should have(0).actions
- @provider.system_state_altered.should be_false
+ expect(@provider.send(:converge_actions).actions.size).to eq(0)
+ expect(@provider.system_state_altered).to be_falsey
end
it "should automatically execute the generated converge_by block" do
@provider.run_action(:foo)
- @provider.system_state_altered.should be_false
- @resource.should_not be_updated
- @resource.should_not be_updated_by_last_action
+ expect(@provider.system_state_altered).to be_falsey
+ expect(@resource).not_to be_updated
+ expect(@resource).not_to be_updated_by_last_action
end
end
end
diff --git a/spec/unit/recipe_spec.rb b/spec/unit/recipe_spec.rb
index a9f37098a2..8d0b1bcfd2 100644
--- a/spec/unit/recipe_spec.rb
+++ b/spec/unit/recipe_spec.rb
@@ -52,50 +52,50 @@ describe Chef::Recipe do
describe "method_missing" do
describe "resources" do
it "should load a two word (zen_master) resource" do
- lambda do
+ expect do
recipe.zen_master "monkey" do
peace true
end
- end.should_not raise_error
+ end.not_to raise_error
end
it "should load a one word (cat) resource" do
- lambda do
+ expect do
recipe.cat "loulou" do
pretty_kitty true
end
- end.should_not raise_error
+ end.not_to raise_error
end
it "should load a four word (one_two_three_four) resource" do
- lambda do
+ expect do
recipe.one_two_three_four "numbers" do
i_can_count true
end
- end.should_not raise_error
+ end.not_to raise_error
end
it "should throw an error if you access a resource that we can't find" do
- lambda { recipe.not_home("not_home_resource") }.should raise_error(NameError)
+ expect { recipe.not_home("not_home_resource") }.to raise_error(NameError)
end
it "should require a name argument" do
- lambda {
+ expect {
recipe.cat
- }.should raise_error(ArgumentError, "You must supply a name when declaring a cat resource")
+ }.to raise_error(ArgumentError, "You must supply a name when declaring a cat resource")
end
it "should allow regular errors (not NameErrors) to pass unchanged" do
- lambda {
+ expect {
recipe.cat("felix") { raise ArgumentError, "You Suck" }
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should add our zen_master to the collection" do
recipe.zen_master "monkey" do
peace true
end
- run_context.resource_collection.lookup("zen_master[monkey]").name.should eql("monkey")
+ expect(run_context.resource_collection.lookup("zen_master[monkey]").name).to eql("monkey")
end
it "should add our zen masters to the collection in the order they appear" do
@@ -105,15 +105,15 @@ describe Chef::Recipe do
end
end
- run_context.resource_collection.map{|r| r.name}.should eql(["monkey", "dog", "cat"])
+ expect(run_context.resource_collection.map{|r| r.name}).to eql(["monkey", "dog", "cat"])
end
it "should return the new resource after creating it" do
res = recipe.zen_master "makoto" do
peace true
end
- res.resource_name.should eql(:zen_master)
- res.name.should eql("makoto")
+ expect(res.resource_name).to eql(:zen_master)
+ expect(res.name).to eql("makoto")
end
describe "should locate platform mapped resources" do
@@ -124,7 +124,7 @@ describe Chef::Recipe do
node.automatic[:platform] = "television"
node.automatic[:platform_version] = "123"
res = recipe.laughter "timmy"
- res.name.should eql("timmy")
+ expect(res.name).to eql("timmy")
res.kind_of?(ShaunTheSheep)
end
@@ -132,7 +132,7 @@ describe Chef::Recipe do
YourMom = Class.new(Chef::Resource)
YourMom.provides :love_and_caring
res = recipe.love_and_caring "mommy"
- res.name.should eql("mommy")
+ expect(res.name).to eql("mommy")
res.kind_of?(YourMom)
end
@@ -147,21 +147,96 @@ describe Chef::Recipe do
end
it "applies attributes from the block to the resource" do
- zm_resource.something.should == "bvb"
+ expect(zm_resource.something).to eq("bvb")
end
it "sets contextual attributes on the resource" do
- zm_resource.recipe_name.should == "test"
- zm_resource.cookbook_name.should == "hjk"
- zm_resource.source_line.should include(__FILE__)
- zm_resource.declared_type.should == :zen_master
+ expect(zm_resource.recipe_name).to eq("test")
+ expect(zm_resource.cookbook_name).to eq("hjk")
+ expect(zm_resource.source_line).to include(__FILE__)
+ expect(zm_resource.declared_type).to eq(:zen_master)
end
it "does not add the resource to the resource collection" do
zm_resource # force let binding evaluation
expect { run_context.resource_collection.resources(:zen_master => "klopp") }.to raise_error(Chef::Exceptions::ResourceNotFound)
end
+ end
+
+ describe "when cloning resources" do
+ def expect_warning
+ expect(Chef::Log).to receive(:warn).with(/3694/)
+ expect(Chef::Log).to receive(:warn).with(/Previous/)
+ expect(Chef::Log).to receive(:warn).with(/Current/)
+ end
+
+ it "should emit a 3694 warning when attributes change" do
+ recipe.zen_master "klopp" do
+ something "bvb"
+ end
+ expect_warning
+ recipe.zen_master "klopp" do
+ something "vbv"
+ end
+ end
+
+ it "should emit a 3694 warning when attributes change" do
+ recipe.zen_master "klopp" do
+ something "bvb"
+ end
+ expect_warning
+ recipe.zen_master "klopp" do
+ something "bvb"
+ peace true
+ end
+ end
+
+ it "should emit a 3694 warning when attributes change" do
+ recipe.zen_master "klopp" do
+ something "bvb"
+ peace true
+ end
+ expect_warning
+ recipe.zen_master "klopp" do
+ something "bvb"
+ end
+ end
+
+ it "should emit a 3694 warning for non-trivial attributes (unfortunately)" do
+ recipe.zen_master "klopp" do
+ something "bvb"
+ end
+ expect_warning
+ recipe.zen_master "klopp" do
+ something "bvb"
+ end
+ end
+ it "should not emit a 3694 warning for completely trivial resource cloning" do
+ recipe.zen_master "klopp"
+ expect(Chef::Log).to_not receive(:warn)
+ recipe.zen_master "klopp"
+ end
+
+ it "should not emit a 3694 warning when attributes do not change and the first action is :nothing" do
+ recipe.zen_master "klopp" do
+ action :nothing
+ end
+ expect(Chef::Log).to_not receive(:warn)
+ recipe.zen_master "klopp" do
+ action :score
+ end
+ end
+
+ it "should not emit a 3694 warning when attributes do not change and the second action is :nothing" do
+ recipe.zen_master "klopp" do
+ action :score
+ end
+ expect(Chef::Log).to_not receive(:warn)
+ recipe.zen_master "klopp" do
+ action :nothing
+ end
+ end
end
describe "creating resources via declare_resource" do
@@ -172,18 +247,18 @@ describe Chef::Recipe do
end
it "applies attributes from the block to the resource" do
- zm_resource.something.should == "bvb"
+ expect(zm_resource.something).to eq("bvb")
end
it "sets contextual attributes on the resource" do
- zm_resource.recipe_name.should == "test"
- zm_resource.cookbook_name.should == "hjk"
- zm_resource.source_line.should include(__FILE__)
+ expect(zm_resource.recipe_name).to eq("test")
+ expect(zm_resource.cookbook_name).to eq("hjk")
+ expect(zm_resource.source_line).to include(__FILE__)
end
it "adds the resource to the resource collection" do
zm_resource # force let binding evaluation
- run_context.resource_collection.resources(:zen_master => "klopp").should == zm_resource
+ expect(run_context.resource_collection.resources(:zen_master => "klopp")).to eq(zm_resource)
end
end
@@ -202,7 +277,7 @@ describe Chef::Recipe do
it "defines the resource using the declaration name with short name" do
resource_follower
- run_context.resource_collection.lookup("follower[srst]").should_not be_nil
+ expect(run_context.resource_collection.lookup("follower[srst]")).not_to be_nil
end
end
@@ -216,25 +291,25 @@ describe Chef::Recipe do
it "defines the resource using the declaration name with long name" do
resource_zn_follower
- run_context.resource_collection.lookup("zen_follower[srst]").should_not be_nil
+ expect(run_context.resource_collection.lookup("zen_follower[srst]")).not_to be_nil
end
end
describe "when attempting to create a resource of an invalid type" do
it "gives a sane error message when using method_missing" do
- lambda do
+ expect do
recipe.no_such_resource("foo")
- end.should raise_error(NoMethodError, %q[No resource or method named `no_such_resource' for `Chef::Recipe "test"'])
+ end.to raise_error(NoMethodError, %q[No resource or method named `no_such_resource' for `Chef::Recipe "test"'])
end
it "gives a sane error message when using method_missing 'bare'" do
- lambda do
+ expect do
recipe.instance_eval do
# Giving an argument will change this from NameError to NoMethodError
no_such_resource
end
- end.should raise_error(NameError, %q[No resource, method, or local variable named `no_such_resource' for `Chef::Recipe "test"'])
+ end.to raise_error(NameError, %q[No resource, method, or local variable named `no_such_resource' for `Chef::Recipe "test"'])
end
it "gives a sane error message when using build_resource" do
@@ -250,11 +325,11 @@ describe Chef::Recipe do
describe "when creating a resource that contains an error in the attributes block" do
it "does not obfuscate the error source" do
- lambda do
+ expect do
recipe.zen_master("klopp") do
this_method_doesnt_exist
end
- end.should raise_error(NoMethodError, "undefined method `this_method_doesnt_exist' for Chef::Resource::ZenMaster")
+ end.to raise_error(NoMethodError, "undefined method `this_method_doesnt_exist' for Chef::Resource::ZenMaster")
end
@@ -281,28 +356,28 @@ describe Chef::Recipe do
end
it "copies attributes from the first resource" do
- duplicated_resource.something.should == "bvb09"
+ expect(duplicated_resource.something).to eq("bvb09")
end
it "does not copy the action from the first resource" do
- original_resource.action.should == [:score]
- duplicated_resource.action.should == :nothing
+ expect(original_resource.action).to eq([:score])
+ expect(duplicated_resource.action).to eq(:nothing)
end
it "does not copy the source location of the first resource" do
# sanity check source location:
- original_resource.source_line.should include(__FILE__)
- duplicated_resource.source_line.should include(__FILE__)
+ expect(original_resource.source_line).to include(__FILE__)
+ expect(duplicated_resource.source_line).to include(__FILE__)
# actual test:
- original_resource.source_line.should_not == duplicated_resource.source_line
+ expect(original_resource.source_line).not_to eq(duplicated_resource.source_line)
end
it "sets the cookbook name on the cloned resource to that resource's cookbook" do
- duplicated_resource.cookbook_name.should == "second_cb"
+ expect(duplicated_resource.cookbook_name).to eq("second_cb")
end
it "sets the recipe name on the cloned resource to that resoure's recipe" do
- duplicated_resource.recipe_name.should == "second_recipe"
+ expect(duplicated_resource.recipe_name).to eq("second_recipe")
end
end
@@ -320,8 +395,8 @@ describe Chef::Recipe do
recipe.crow "mine" do
peace true
end
- run_context.resource_collection.resources(:zen_master => "lao tzu").name.should eql("lao tzu")
- run_context.resource_collection.resources(:zen_master => "lao tzu").something.should eql(true)
+ expect(run_context.resource_collection.resources(:zen_master => "lao tzu").name).to eql("lao tzu")
+ expect(run_context.resource_collection.resources(:zen_master => "lao tzu").something).to eql(true)
end
it "should set the node on defined resources" do
@@ -337,7 +412,7 @@ describe Chef::Recipe do
recipe.crow "mine" do
something node[:foo]
end
- recipe.resources(:zen_master => "lao tzu").something.should eql(false)
+ expect(recipe.resources(:zen_master => "lao tzu").something).to eql(false)
end
it "should return the last statement in the definition as the retval" do
@@ -346,9 +421,10 @@ describe Chef::Recipe do
"the return val"
end
run_context.definitions[:crow] = crow_define
- recipe.crow "mine" do
+ crow_block = recipe.crow "mine" do
peace true
- end.should eql("the return val")
+ end
+ expect(crow_block).to eql("the return val")
end
end
@@ -361,8 +437,8 @@ describe Chef::Recipe do
peace = true
end
CODE
- lambda { recipe.instance_eval(code) }.should_not raise_error
- recipe.resources(:zen_master => "gnome").name.should eql("gnome")
+ expect { recipe.instance_eval(code) }.not_to raise_error
+ expect(recipe.resources(:zen_master => "gnome").name).to eql("gnome")
end
end
@@ -371,7 +447,7 @@ describe Chef::Recipe do
code = <<-CODE
exec 'do_not_try_to_exec'
CODE
- lambda { recipe.instance_eval(code) }.should raise_error(Chef::Exceptions::ResourceNotFound)
+ expect { recipe.instance_eval(code) }.to raise_error(Chef::Exceptions::ResourceNotFound)
end
end
@@ -379,52 +455,80 @@ describe Chef::Recipe do
it "should load a resource from a ruby file" do
recipe.from_file(File.join(CHEF_SPEC_DATA, "recipes", "test.rb"))
res = recipe.resources(:file => "/etc/nsswitch.conf")
- res.name.should eql("/etc/nsswitch.conf")
- res.action.should eql([:create])
- res.owner.should eql("root")
- res.group.should eql("root")
- res.mode.should eql(0644)
+ expect(res.name).to eql("/etc/nsswitch.conf")
+ expect(res.action).to eql([:create])
+ expect(res.owner).to eql("root")
+ expect(res.group).to eql("root")
+ expect(res.mode).to eql(0644)
end
it "should raise an exception if the file cannot be found or read" do
- lambda { recipe.from_file("/tmp/monkeydiving") }.should raise_error(IOError)
+ expect { recipe.from_file("/tmp/monkeydiving") }.to raise_error(IOError)
end
end
describe "include_recipe" do
it "should evaluate another recipe with include_recipe" do
- node.should_receive(:loaded_recipe).with(:openldap, "gigantor")
- run_context.stub(:unreachable_cookbook?).with(:openldap).and_return(false)
+ expect(node).to receive(:loaded_recipe).with(:openldap, "gigantor")
+ allow(run_context).to receive(:unreachable_cookbook?).with(:openldap).and_return(false)
run_context.include_recipe "openldap::gigantor"
res = run_context.resource_collection.resources(:cat => "blanket")
- res.name.should eql("blanket")
- res.pretty_kitty.should eql(false)
+ expect(res.name).to eql("blanket")
+ expect(res.pretty_kitty).to eql(false)
end
it "should load the default recipe for a cookbook if include_recipe is called without a ::" do
- node.should_receive(:loaded_recipe).with(:openldap, "default")
- run_context.stub(:unreachable_cookbook?).with(:openldap).and_return(false)
+ expect(node).to receive(:loaded_recipe).with(:openldap, "default")
+ allow(run_context).to receive(:unreachable_cookbook?).with(:openldap).and_return(false)
run_context.include_recipe "openldap"
res = run_context.resource_collection.resources(:cat => "blanket")
- res.name.should eql("blanket")
- res.pretty_kitty.should eql(true)
+ expect(res.name).to eql("blanket")
+ expect(res.pretty_kitty).to eql(true)
end
it "should store that it has seen a recipe in the run_context" do
- node.should_receive(:loaded_recipe).with(:openldap, "default")
- run_context.stub(:unreachable_cookbook?).with(:openldap).and_return(false)
+ expect(node).to receive(:loaded_recipe).with(:openldap, "default")
+ allow(run_context).to receive(:unreachable_cookbook?).with(:openldap).and_return(false)
run_context.include_recipe "openldap"
- run_context.loaded_recipe?("openldap").should be_true
+ expect(run_context.loaded_recipe?("openldap")).to be_truthy
end
it "should not include the same recipe twice" do
- node.should_receive(:loaded_recipe).with(:openldap, "default").exactly(:once)
- run_context.stub(:unreachable_cookbook?).with(:openldap).and_return(false)
- cookbook_collection[:openldap].should_receive(:load_recipe).with("default", run_context)
+ expect(node).to receive(:loaded_recipe).with(:openldap, "default").exactly(:once)
+ allow(run_context).to receive(:unreachable_cookbook?).with(:openldap).and_return(false)
+ expect(cookbook_collection[:openldap]).to receive(:load_recipe).with("default", run_context)
recipe.include_recipe "openldap"
- cookbook_collection[:openldap].should_not_receive(:load_recipe).with("default", run_context)
+ expect(cookbook_collection[:openldap]).not_to receive(:load_recipe).with("default", run_context)
recipe.include_recipe "openldap"
end
+
+ it "will load a recipe out of the current cookbook when include_recipe is called with a leading ::" do
+ openldap_recipe = Chef::Recipe.new("openldap", "test", run_context)
+ expect(node).to receive(:loaded_recipe).with(:openldap, "default").exactly(:once)
+ allow(run_context).to receive(:unreachable_cookbook?).with(:openldap).and_return(false)
+ expect(cookbook_collection[:openldap]).to receive(:load_recipe).with("default", run_context)
+ openldap_recipe.include_recipe "::default"
+ end
+
+ it "will not include the same recipe twice when using leading :: syntax" do
+ openldap_recipe = Chef::Recipe.new("openldap", "test", run_context)
+ expect(node).to receive(:loaded_recipe).with(:openldap, "default").exactly(:once)
+ allow(run_context).to receive(:unreachable_cookbook?).with(:openldap).and_return(false)
+ expect(cookbook_collection[:openldap]).to receive(:load_recipe).with("default", run_context)
+ openldap_recipe.include_recipe "::default"
+ expect(cookbook_collection[:openldap]).not_to receive(:load_recipe).with("default", run_context)
+ openldap_recipe.include_recipe "openldap::default"
+ end
+
+ it "will not include the same recipe twice when using leading :: syntax (reversed order)" do
+ openldap_recipe = Chef::Recipe.new("openldap", "test", run_context)
+ expect(node).to receive(:loaded_recipe).with(:openldap, "default").exactly(:once)
+ allow(run_context).to receive(:unreachable_cookbook?).with(:openldap).and_return(false)
+ expect(cookbook_collection[:openldap]).to receive(:load_recipe).with("default", run_context)
+ openldap_recipe.include_recipe "openldap::default"
+ expect(cookbook_collection[:openldap]).not_to receive(:load_recipe).with("default", run_context)
+ openldap_recipe.include_recipe "::default"
+ end
end
describe "tags" do
@@ -432,55 +536,62 @@ describe Chef::Recipe do
let(:node) { Chef::Node.new }
it "should return false for any tags" do
- recipe.tagged?("foo").should be(false)
+ expect(recipe.tagged?("foo")).to be(false)
end
end
it "should set tags via tag" do
recipe.tag "foo"
- node[:tags].should include("foo")
+ expect(node[:tags]).to include("foo")
end
it "should set multiple tags via tag" do
recipe.tag "foo", "bar"
- node[:tags].should include("foo")
- node[:tags].should include("bar")
+ expect(node[:tags]).to include("foo")
+ expect(node[:tags]).to include("bar")
end
it "should not set the same tag twice via tag" do
recipe.tag "foo"
recipe.tag "foo"
- node[:tags].should eql([ "foo" ])
+ expect(node[:tags]).to eql([ "foo" ])
end
it "should return the current list of tags from tag with no arguments" do
recipe.tag "foo"
- recipe.tag.should eql([ "foo" ])
+ expect(recipe.tag).to eql([ "foo" ])
end
it "should return true from tagged? if node is tagged" do
recipe.tag "foo"
- recipe.tagged?("foo").should be(true)
+ expect(recipe.tagged?("foo")).to be(true)
end
it "should return false from tagged? if node is not tagged" do
- recipe.tagged?("foo").should be(false)
+ expect(recipe.tagged?("foo")).to be(false)
end
it "should return false from tagged? if node is not tagged" do
- recipe.tagged?("foo").should be(false)
+ expect(recipe.tagged?("foo")).to be(false)
end
it "should remove a tag from the tag list via untag" do
recipe.tag "foo"
recipe.untag "foo"
- node[:tags].should eql([])
+ expect(node[:tags]).to eql([])
end
it "should remove multiple tags from the tag list via untag" do
recipe.tag "foo", "bar"
recipe.untag "bar", "foo"
- node[:tags].should eql([])
+ expect(node[:tags]).to eql([])
+ end
+ end
+
+ describe "included DSL" do
+ it "should include features from Chef::DSL::Audit" do
+ expect(recipe.singleton_class.included_modules).to include(Chef::DSL::Audit)
+ expect(recipe.respond_to?(:control_group)).to be true
end
end
end
diff --git a/spec/unit/registry_helper_spec.rb b/spec/unit/registry_helper_spec.rb
index 444a82dc7c..036a0834db 100644
--- a/spec/unit/registry_helper_spec.rb
+++ b/spec/unit/registry_helper_spec.rb
@@ -29,7 +29,7 @@ describe Chef::Provider::RegistryKey do
let(:missing_key_path) {'HKCU\Software'}
before(:each) do
- Chef::Win32::Registry.any_instance.stub(:machine_architecture).and_return(:x86_64)
+ allow_any_instance_of(Chef::Win32::Registry).to receive(:machine_architecture).and_return(:x86_64)
@registry = Chef::Win32::Registry.new()
#Making the values for registry constants available on unix
@@ -49,328 +49,328 @@ describe Chef::Provider::RegistryKey do
describe "get_values" do
it "gets all values for a key if the key exists" do
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @registry.should_receive(:key_exists!).with(key_path).and_return(true)
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
- @reg_mock.should_receive(:map)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@registry).to receive(:key_exists!).with(key_path).and_return(true)
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@reg_mock).to receive(:map)
@registry.get_values(key_path)
end
it "throws an exception if key does not exist" do
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @registry.should_receive(:key_exists!).with(key_path).and_raise(Chef::Exceptions::Win32RegKeyMissing)
- lambda{@registry.get_values(key_path)}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@registry).to receive(:key_exists!).with(key_path).and_raise(Chef::Exceptions::Win32RegKeyMissing)
+ expect{@registry.get_values(key_path)}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
end
describe "set_value" do
it "does nothing if key and hive and value exist" do
- @registry.should_receive(:key_exists!).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @registry.should_receive(:value_exists?).with(key_path, value1).and_return(true)
- @registry.should_receive(:data_exists?).with(key_path, value1).and_return(true)
+ expect(@registry).to receive(:key_exists!).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@registry).to receive(:value_exists?).with(key_path, value1).and_return(true)
+ expect(@registry).to receive(:data_exists?).with(key_path, value1).and_return(true)
@registry.set_value(key_path, value1)
end
it "updates value if key and hive and value exist, but data is different" do
- @registry.should_receive(:key_exists!).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @registry.should_receive(:value_exists?).with(key_path, value1).and_return(true)
- @registry.should_receive(:data_exists?).with(key_path, value1).and_return(false)
- @hive_mock.should_receive(:open).with(key, Win32::Registry::KEY_SET_VALUE | ::Win32::Registry::KEY_QUERY_VALUE | @registry.registry_system_architecture).and_yield(@reg_mock)
- @registry.should_receive(:get_type_from_name).with(:string).and_return(1)
- @reg_mock.should_receive(:write).with("one", 1, "1")
+ expect(@registry).to receive(:key_exists!).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@registry).to receive(:value_exists?).with(key_path, value1).and_return(true)
+ expect(@registry).to receive(:data_exists?).with(key_path, value1).and_return(false)
+ expect(@hive_mock).to receive(:open).with(key, Win32::Registry::KEY_SET_VALUE | ::Win32::Registry::KEY_QUERY_VALUE | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@registry).to receive(:get_type_from_name).with(:string).and_return(1)
+ expect(@reg_mock).to receive(:write).with("one", 1, "1")
@registry.set_value(key_path, value1)
end
it "creates value if the key exists and the value does not exist" do
- @registry.should_receive(:key_exists!).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @registry.should_receive(:value_exists?).with(key_path, value1).and_return(false)
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_SET_VALUE | ::Win32::Registry::KEY_QUERY_VALUE | @registry.registry_system_architecture).and_yield(@reg_mock)
- @registry.should_receive(:get_type_from_name).with(:string).and_return(1)
- @reg_mock.should_receive(:write).with("one", 1, "1")
+ expect(@registry).to receive(:key_exists!).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@registry).to receive(:value_exists?).with(key_path, value1).and_return(false)
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_SET_VALUE | ::Win32::Registry::KEY_QUERY_VALUE | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@registry).to receive(:get_type_from_name).with(:string).and_return(1)
+ expect(@reg_mock).to receive(:write).with("one", 1, "1")
@registry.set_value(key_path, value1)
end
it "should raise an exception if the key does not exist" do
- @registry.should_receive(:key_exists!).with(key_path).and_raise(Chef::Exceptions::Win32RegKeyMissing)
- lambda {@registry.set_value(key_path, value1)}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect(@registry).to receive(:key_exists!).with(key_path).and_raise(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.set_value(key_path, value1)}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
end
describe "delete_value" do
it "deletes value if value exists" do
- @registry.should_receive(:value_exists?).with(key_path, value1).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_SET_VALUE | @registry.registry_system_architecture).and_yield(@reg_mock)
- @reg_mock.should_receive(:delete_value).with("one").and_return(true)
+ expect(@registry).to receive(:value_exists?).with(key_path, value1).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_SET_VALUE | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@reg_mock).to receive(:delete_value).with("one").and_return(true)
@registry.delete_value(key_path, value1)
end
it "raises an exception if the key does not exist" do
- @registry.should_receive(:value_exists?).with(key_path, value1).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_raise(Chef::Exceptions::Win32RegKeyMissing)
+ expect(@registry).to receive(:value_exists?).with(key_path, value1).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_raise(Chef::Exceptions::Win32RegKeyMissing)
@registry.delete_value(key_path, value1)
end
it "does nothing if the value does not exist" do
- @registry.should_receive(:value_exists?).with(key_path, value1).and_return(false)
+ expect(@registry).to receive(:value_exists?).with(key_path, value1).and_return(false)
@registry.delete_value(key_path, value1)
end
end
describe "create_key" do
it "creates key if intermediate keys are missing and recursive is set to true" do
- @registry.should_receive(:keys_missing?).with(key_path).and_return(true)
- @registry.should_receive(:create_missing).with(key_path)
- @registry.should_receive(:key_exists?).with(key_path).and_return(false)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:create).with(key, ::Win32::Registry::KEY_WRITE | @registry.registry_system_architecture)
+ expect(@registry).to receive(:keys_missing?).with(key_path).and_return(true)
+ expect(@registry).to receive(:create_missing).with(key_path)
+ expect(@registry).to receive(:key_exists?).with(key_path).and_return(false)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:create).with(key, ::Win32::Registry::KEY_WRITE | @registry.registry_system_architecture)
@registry.create_key(key_path, true)
end
it "raises an exception if intermediate keys are missing and recursive is set to false" do
- @registry.should_receive(:keys_missing?).with(key_path).and_return(true)
- lambda{@registry.create_key(key_path, false)}.should raise_error(Chef::Exceptions::Win32RegNoRecursive)
+ expect(@registry).to receive(:keys_missing?).with(key_path).and_return(true)
+ expect{@registry.create_key(key_path, false)}.to raise_error(Chef::Exceptions::Win32RegNoRecursive)
end
it "does nothing if the key exists" do
- @registry.should_receive(:keys_missing?).with(key_path).and_return(true)
- @registry.should_receive(:create_missing).with(key_path)
- @registry.should_receive(:key_exists?).with(key_path).and_return(true)
+ expect(@registry).to receive(:keys_missing?).with(key_path).and_return(true)
+ expect(@registry).to receive(:create_missing).with(key_path)
+ expect(@registry).to receive(:key_exists?).with(key_path).and_return(true)
@registry.create_key(key_path, true)
end
it "create key if intermediate keys not missing and recursive is set to false" do
- @registry.should_receive(:keys_missing?).with(key_path).and_return(false)
- @registry.should_receive(:key_exists?).with(key_path).and_return(false)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:create).with(key, ::Win32::Registry::KEY_WRITE | @registry.registry_system_architecture)
+ expect(@registry).to receive(:keys_missing?).with(key_path).and_return(false)
+ expect(@registry).to receive(:key_exists?).with(key_path).and_return(false)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:create).with(key, ::Win32::Registry::KEY_WRITE | @registry.registry_system_architecture)
@registry.create_key(key_path, false)
end
it "create key if intermediate keys not missing and recursive is set to true" do
- @registry.should_receive(:keys_missing?).with(key_path).and_return(false)
- @registry.should_receive(:key_exists?).with(key_path).and_return(false)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:create).with(key, ::Win32::Registry::KEY_WRITE | @registry.registry_system_architecture)
+ expect(@registry).to receive(:keys_missing?).with(key_path).and_return(false)
+ expect(@registry).to receive(:key_exists?).with(key_path).and_return(false)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:create).with(key, ::Win32::Registry::KEY_WRITE | @registry.registry_system_architecture)
@registry.create_key(key_path, true)
end
end
describe "delete_key", :windows_only do
it "deletes key if it has subkeys and recursive is set to true" do
- @registry.should_receive(:key_exists?).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @registry.should_receive(:has_subkeys?).with(key_path).and_return(true)
- @registry.should_receive(:get_subkeys).with(key_path).and_return([sub_key])
- @registry.should_receive(:key_exists?).with(key_path+"\\"+sub_key).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path+"\\"+sub_key).and_return([@hive_mock, key+"\\"+sub_key])
- @registry.should_receive(:has_subkeys?).with(key_path+"\\"+sub_key).and_return(false)
- @registry.should_receive(:delete_key_ex).twice
+ expect(@registry).to receive(:key_exists?).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@registry).to receive(:has_subkeys?).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_subkeys).with(key_path).and_return([sub_key])
+ expect(@registry).to receive(:key_exists?).with(key_path+"\\"+sub_key).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path+"\\"+sub_key).and_return([@hive_mock, key+"\\"+sub_key])
+ expect(@registry).to receive(:has_subkeys?).with(key_path+"\\"+sub_key).and_return(false)
+ expect(@registry).to receive(:delete_key_ex).twice
@registry.delete_key(key_path, true)
end
it "raises an exception if it has subkeys but recursive is set to false" do
- @registry.should_receive(:key_exists?).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @registry.should_receive(:has_subkeys?).with(key_path).and_return(true)
- lambda{@registry.delete_key(key_path, false)}.should raise_error(Chef::Exceptions::Win32RegNoRecursive)
+ expect(@registry).to receive(:key_exists?).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@registry).to receive(:has_subkeys?).with(key_path).and_return(true)
+ expect{@registry.delete_key(key_path, false)}.to raise_error(Chef::Exceptions::Win32RegNoRecursive)
end
it "deletes key if the key exists and has no subkeys" do
- @registry.should_receive(:key_exists?).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @registry.should_receive(:has_subkeys?).with(key_path).and_return(false)
- @registry.should_receive(:delete_key_ex)
+ expect(@registry).to receive(:key_exists?).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@registry).to receive(:has_subkeys?).with(key_path).and_return(false)
+ expect(@registry).to receive(:delete_key_ex)
@registry.delete_key(key_path, true)
end
end
describe "key_exists?" do
it "returns true if key_exists" do
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
- @registry.key_exists?(key_path).should == true
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@registry.key_exists?(key_path)).to eq(true)
end
it "returns false if key does not exist" do
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_raise(::Win32::Registry::Error)
- @registry.key_exists?(key_path).should == false
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_raise(::Win32::Registry::Error)
+ expect(@registry.key_exists?(key_path)).to eq(false)
end
end
describe "key_exists!" do
it "throws an exception if the key_parent does not exist" do
- @registry.should_receive(:key_exists?).with(key_path).and_return(false)
- lambda{@registry.key_exists!(key_path)}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect(@registry).to receive(:key_exists?).with(key_path).and_return(false)
+ expect{@registry.key_exists!(key_path)}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
end
describe "hive_exists?" do
it "returns true if the hive exists" do
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
@registry.hive_exists?(key_path) == true
end
it "returns false if the hive does not exist" do
- @registry.should_receive(:get_hive_and_key).with(key_path).and_raise(Chef::Exceptions::Win32RegHiveMissing)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_raise(Chef::Exceptions::Win32RegHiveMissing)
@registry.hive_exists?(key_path) == false
end
end
describe "has_subkeys?" do
it "returns true if the key has subkeys" do
- @registry.should_receive(:key_exists!).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
- @reg_mock.should_receive(:each_key).and_yield(key)
+ expect(@registry).to receive(:key_exists!).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@reg_mock).to receive(:each_key).and_yield(key)
@registry.has_subkeys?(key_path) == true
end
it "returns false if the key does not have subkeys" do
- @registry.should_receive(:key_exists!).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
- @reg_mock.should_receive(:each_key).and_return(no_args())
- @registry.has_subkeys?(key_path).should == false
+ expect(@registry).to receive(:key_exists!).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@reg_mock).to receive(:each_key).and_return(no_args())
+ expect(@registry.has_subkeys?(key_path)).to eq(false)
end
it "throws an exception if the key does not exist" do
- @registry.should_receive(:key_exists!).with(key_path).and_raise(Chef::Exceptions::Win32RegKeyMissing)
- lambda {@registry.set_value(key_path, value1)}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect(@registry).to receive(:key_exists!).with(key_path).and_raise(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.set_value(key_path, value1)}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
end
describe "get_subkeys" do
it "returns the subkeys if they exist" do
- @registry.should_receive(:key_exists!).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
- @reg_mock.should_receive(:each_key).and_yield(sub_key)
+ expect(@registry).to receive(:key_exists!).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@reg_mock).to receive(:each_key).and_yield(sub_key)
@registry.get_subkeys(key_path)
end
end
describe "value_exists?" do
it "throws an exception if the key does not exist" do
- @registry.should_receive(:key_exists!).with(key_path).and_raise(Chef::Exceptions::Win32RegKeyMissing)
- lambda {@registry.value_exists?(key_path, value1)}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect(@registry).to receive(:key_exists!).with(key_path).and_raise(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.value_exists?(key_path, value1)}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "returns true if the value exists" do
- @registry.should_receive(:key_exists!).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
- @reg_mock.should_receive(:any?).and_yield("one")
+ expect(@registry).to receive(:key_exists!).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@reg_mock).to receive(:any?).and_yield("one")
@registry.value_exists?(key_path, value1) == true
end
it "returns false if the value does not exist" do
- @registry.should_receive(:key_exists!).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
- @reg_mock.should_receive(:any?).and_yield(no_args())
+ expect(@registry).to receive(:key_exists!).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@reg_mock).to receive(:any?).and_yield(no_args())
@registry.value_exists?(key_path, value1) == false
end
end
describe "data_exists?" do
it "throws an exception if the key does not exist" do
- @registry.should_receive(:key_exists!).with(key_path).and_raise(Chef::Exceptions::Win32RegKeyMissing)
- lambda {@registry.data_exists?(key_path, value1)}.should raise_error(Chef::Exceptions::Win32RegKeyMissing)
+ expect(@registry).to receive(:key_exists!).with(key_path).and_raise(Chef::Exceptions::Win32RegKeyMissing)
+ expect {@registry.data_exists?(key_path, value1)}.to raise_error(Chef::Exceptions::Win32RegKeyMissing)
end
it "returns true if the data exists" do
- @registry.should_receive(:key_exists!).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @registry.should_receive(:get_type_from_name).with(:string).and_return(1)
- @reg_mock.should_receive(:each).with(no_args()).and_yield("one", 1, "1")
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
- @registry.data_exists?(key_path, value1).should == true
+ expect(@registry).to receive(:key_exists!).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@registry).to receive(:get_type_from_name).with(:string).and_return(1)
+ expect(@reg_mock).to receive(:each).with(no_args()).and_yield("one", 1, "1")
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@registry.data_exists?(key_path, value1)).to eq(true)
end
it "returns false if the data does not exist" do
- @registry.should_receive(:key_exists!).with(key_path).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
- @registry.should_receive(:get_type_from_name).with(:string).and_return(1)
- @reg_mock.should_receive(:each).with(no_args()).and_yield("one", 1, "2")
- @registry.data_exists?(key_path, value1).should == false
+ expect(@registry).to receive(:key_exists!).with(key_path).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@registry).to receive(:get_type_from_name).with(:string).and_return(1)
+ expect(@reg_mock).to receive(:each).with(no_args()).and_yield("one", 1, "2")
+ expect(@registry.data_exists?(key_path, value1)).to eq(false)
end
end
describe "value_exists!" do
it "does nothing if the value exists" do
- @registry.should_receive(:value_exists?).with(key_path, value1).and_return(true)
+ expect(@registry).to receive(:value_exists?).with(key_path, value1).and_return(true)
@registry.value_exists!(key_path, value1)
end
it "throws an exception if the value does not exist" do
- @registry.should_receive(:value_exists?).with(key_path, value1).and_return(false)
- lambda{@registry.value_exists!(key_path, value1)}.should raise_error(Chef::Exceptions::Win32RegValueMissing)
+ expect(@registry).to receive(:value_exists?).with(key_path, value1).and_return(false)
+ expect{@registry.value_exists!(key_path, value1)}.to raise_error(Chef::Exceptions::Win32RegValueMissing)
end
end
describe "data_exists!" do
it "does nothing if the data exists" do
- @registry.should_receive(:data_exists?).with(key_path, value1).and_return(true)
+ expect(@registry).to receive(:data_exists?).with(key_path, value1).and_return(true)
@registry.data_exists!(key_path, value1)
end
it "throws an exception if the data does not exist" do
- @registry.should_receive(:data_exists?).with(key_path, value1).and_return(false)
- lambda{@registry.data_exists!(key_path, value1)}.should raise_error(Chef::Exceptions::Win32RegDataMissing)
+ expect(@registry).to receive(:data_exists?).with(key_path, value1).and_return(false)
+ expect{@registry.data_exists!(key_path, value1)}.to raise_error(Chef::Exceptions::Win32RegDataMissing)
end
end
describe "type_matches?" do
it "returns true if type matches" do
- @registry.should_receive(:value_exists!).with(key_path, value1).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
- @registry.should_receive(:get_type_from_name).with(:string).and_return(1)
- @reg_mock.should_receive(:each).and_yield("one", 1)
- @registry.type_matches?(key_path, value1).should == true
+ expect(@registry).to receive(:value_exists!).with(key_path, value1).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@registry).to receive(:get_type_from_name).with(:string).and_return(1)
+ expect(@reg_mock).to receive(:each).and_yield("one", 1)
+ expect(@registry.type_matches?(key_path, value1)).to eq(true)
end
it "returns false if type does not match" do
- @registry.should_receive(:value_exists!).with(key_path, value1).and_return(true)
- @registry.should_receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
- @hive_mock.should_receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
- @reg_mock.should_receive(:each).and_yield("two", 2)
- @registry.type_matches?(key_path, value1).should == false
+ expect(@registry).to receive(:value_exists!).with(key_path, value1).and_return(true)
+ expect(@registry).to receive(:get_hive_and_key).with(key_path).and_return([@hive_mock, key])
+ expect(@hive_mock).to receive(:open).with(key, ::Win32::Registry::KEY_READ | @registry.registry_system_architecture).and_yield(@reg_mock)
+ expect(@reg_mock).to receive(:each).and_yield("two", 2)
+ expect(@registry.type_matches?(key_path, value1)).to eq(false)
end
it "throws an exception if value does not exist" do
- @registry.should_receive(:value_exists?).with(key_path, value1).and_return(false)
- lambda{@registry.type_matches?(key_path, value1)}.should raise_error(Chef::Exceptions::Win32RegValueMissing)
+ expect(@registry).to receive(:value_exists?).with(key_path, value1).and_return(false)
+ expect{@registry.type_matches?(key_path, value1)}.to raise_error(Chef::Exceptions::Win32RegValueMissing)
end
end
describe "type_matches!" do
it "does nothing if the type_matches" do
- @registry.should_receive(:type_matches?).with(key_path, value1).and_return(true)
+ expect(@registry).to receive(:type_matches?).with(key_path, value1).and_return(true)
@registry.type_matches!(key_path, value1)
end
it "throws an exception if the type does not match" do
- @registry.should_receive(:type_matches?).with(key_path, value1).and_return(false)
- lambda{@registry.type_matches!(key_path, value1)}.should raise_error(Chef::Exceptions::Win32RegTypesMismatch)
+ expect(@registry).to receive(:type_matches?).with(key_path, value1).and_return(false)
+ expect{@registry.type_matches!(key_path, value1)}.to raise_error(Chef::Exceptions::Win32RegTypesMismatch)
end
end
describe "keys_missing?" do
it "returns true if the keys are missing" do
- @registry.should_receive(:key_exists?).with(missing_key_path).and_return(false)
- @registry.keys_missing?(key_path).should == true
+ expect(@registry).to receive(:key_exists?).with(missing_key_path).and_return(false)
+ expect(@registry.keys_missing?(key_path)).to eq(true)
end
it "returns false if no keys in the path are missing" do
- @registry.should_receive(:key_exists?).with(missing_key_path).and_return(true)
- @registry.keys_missing?(key_path).should == false
+ expect(@registry).to receive(:key_exists?).with(missing_key_path).and_return(true)
+ expect(@registry.keys_missing?(key_path)).to eq(false)
end
end
end
diff --git a/spec/unit/resource/chef_gem_spec.rb b/spec/unit/resource/chef_gem_spec.rb
index 480856d19f..7352a8f5fe 100644
--- a/spec/unit/resource/chef_gem_spec.rb
+++ b/spec/unit/resource/chef_gem_spec.rb
@@ -32,16 +32,130 @@ describe Chef::Resource::ChefGem, "initialize" do
end
describe Chef::Resource::ChefGem, "gem_binary" do
+ let(:resource) { Chef::Resource::ChefGem.new("foo") }
+
before(:each) do
expect(RbConfig::CONFIG).to receive(:[]).with('bindir').and_return("/opt/chef/embedded/bin")
- @resource = Chef::Resource::ChefGem.new("foo")
end
it "should raise an exception when gem_binary is set" do
- expect { @resource.gem_binary("/lol/cats/gem") }.to raise_error(ArgumentError)
+ expect { resource.gem_binary("/lol/cats/gem") }.to raise_error(ArgumentError)
+ end
+
+ it "should set the gem_binary based on computing it from RbConfig" do
+ expect(resource.gem_binary).to eql("/opt/chef/embedded/bin/gem")
end
it "should set the gem_binary based on computing it from RbConfig" do
- expect(@resource.gem_binary).to eql("/opt/chef/embedded/bin/gem")
+ expect(resource.compile_time).to be nil
+ end
+
+ context "when building the resource" do
+ let(:node) do
+ Chef::Node.new.tap {|n| n.normal[:tags] = [] }
+ end
+
+ let(:run_context) do
+ Chef::RunContext.new(node, {}, nil)
+ end
+
+ let(:recipe) do
+ Chef::Recipe.new("hjk", "test", run_context)
+ end
+
+ let(:chef_gem_compile_time) { nil }
+
+ let(:resource) do
+ Chef::Config[:chef_gem_compile_time] = chef_gem_compile_time
+ Chef::Resource::ChefGem.new("foo", run_context)
+ end
+
+ before do
+ expect(Chef::Resource::ChefGem).to receive(:new).and_return(resource)
+ end
+
+ it "runs the install at compile-time by default", :chef_lt_13_only do
+ expect(resource).to receive(:run_action).with(:install)
+ expect(Chef::Log).to receive(:deprecation).at_least(:once)
+ recipe.chef_gem "foo"
+ end
+
+ # the default behavior will change in Chef-13
+ it "does not runs the install at compile-time by default", :chef_gte_13_only do
+ expect(resource).not_to receive(:run_action).with(:install)
+ expect(Chef::Log).not_to receive(:deprecation)
+ recipe.chef_gem "foo"
+ end
+
+ it "compile_time true installs at compile-time" do
+ expect(resource).to receive(:run_action).with(:install)
+ expect(Chef::Log).not_to receive(:deprecation)
+ recipe.chef_gem "foo" do
+ compile_time true
+ end
+ end
+
+ it "compile_time false does not install at compile-time" do
+ expect(resource).not_to receive(:run_action).with(:install)
+ expect(Chef::Log).not_to receive(:deprecation)
+ recipe.chef_gem "foo" do
+ compile_time false
+ end
+ end
+
+ describe "when Chef::Config[:chef_gem_compile_time] is explicitly true" do
+ let(:chef_gem_compile_time) { true }
+
+ before do
+ expect(Chef::Log).not_to receive(:deprecation)
+ end
+
+ it "by default installs at compile-time" do
+ expect(resource).to receive(:run_action).with(:install)
+ recipe.chef_gem "foo"
+ end
+
+ it "compile_time true installs at compile-time" do
+ expect(resource).to receive(:run_action).with(:install)
+ recipe.chef_gem "foo" do
+ compile_time true
+ end
+ end
+
+ it "compile_time false does not install at compile-time" do
+ expect(resource).not_to receive(:run_action).with(:install)
+ recipe.chef_gem "foo" do
+ compile_time false
+ end
+ end
+ end
+
+ describe "when Chef::Config[:chef_gem_compile_time] is explicitly false" do
+
+ let(:chef_gem_compile_time) { false }
+
+ before do
+ expect(Chef::Log).not_to receive(:deprecation)
+ end
+
+ it "by default does not install at compile-time" do
+ expect(resource).not_to receive(:run_action).with(:install)
+ recipe.chef_gem "foo"
+ end
+
+ it "compile_time true installs at compile-time" do
+ expect(resource).to receive(:run_action).with(:install)
+ recipe.chef_gem "foo" do
+ compile_time true
+ end
+ end
+
+ it "compile_time false does not install at compile-time" do
+ expect(resource).not_to receive(:run_action).with(:install)
+ recipe.chef_gem "foo" do
+ compile_time false
+ end
+ end
+ end
end
end
diff --git a/spec/unit/resource/conditional_action_not_nothing_spec.rb b/spec/unit/resource/conditional_action_not_nothing_spec.rb
index 9f29de55f2..d140615cfc 100644
--- a/spec/unit/resource/conditional_action_not_nothing_spec.rb
+++ b/spec/unit/resource/conditional_action_not_nothing_spec.rb
@@ -27,7 +27,7 @@ describe Chef::Resource::ConditionalActionNotNothing do
end
it "indicates that resource convergence should not continue" do
- expect(@conditional.continue?).to be_false
+ expect(@conditional.continue?).to be_falsey
end
end
@@ -38,7 +38,7 @@ describe Chef::Resource::ConditionalActionNotNothing do
end
it "indicates that resource convergence should continue" do
- expect(@conditional.continue?).to be_true
+ expect(@conditional.continue?).to be_truthy
end
end
diff --git a/spec/unit/resource/conditional_spec.rb b/spec/unit/resource/conditional_spec.rb
index cacac925b7..489c1136b1 100644
--- a/spec/unit/resource/conditional_spec.rb
+++ b/spec/unit/resource/conditional_spec.rb
@@ -47,24 +47,45 @@ describe Chef::Resource::Conditional do
end
describe "when created as an `only_if`" do
- describe "after running a successful command" do
+ describe "after running a successful command given as a string" do
before do
@conditional = Chef::Resource::Conditional.only_if(@parent_resource, "true")
end
it "indicates that resource convergence should continue" do
- expect(@conditional.continue?).to be_true
+ expect(@conditional.continue?).to be_truthy
end
end
- describe "after running a negative/false command" do
+ describe "after running a negative/false command given as a string" do
before do
@status.send("success?=", false)
@conditional = Chef::Resource::Conditional.only_if(@parent_resource, "false")
end
it "indicates that resource convergence should not continue" do
- expect(@conditional.continue?).to be_false
+ expect(@conditional.continue?).to be_falsey
+ end
+ end
+
+ describe "after running a successful command given as an array" do
+ before do
+ @conditional = Chef::Resource::Conditional.only_if(@parent_resource, ["true"])
+ end
+
+ it "indicates that resource convergence should continue" do
+ expect(@conditional.continue?).to be true
+ end
+ end
+
+ describe "after running a negative/false command given as an array" do
+ before do
+ @status.send("success?=", false)
+ @conditional = Chef::Resource::Conditional.only_if(@parent_resource, ["false"])
+ end
+
+ it "indicates that resource convergence should not continue" do
+ expect(@conditional.continue?).to be false
end
end
@@ -75,7 +96,7 @@ describe Chef::Resource::Conditional do
end
it 'indicates that resource convergence should not continue' do
- expect(@conditional.continue?).to be_false
+ expect(@conditional.continue?).to be_falsey
end
it 'should log a warning' do
@@ -90,7 +111,7 @@ describe Chef::Resource::Conditional do
end
it "indicates that resource convergence should continue" do
- expect(@conditional.continue?).to be_true
+ expect(@conditional.continue?).to be_truthy
end
end
@@ -100,30 +121,51 @@ describe Chef::Resource::Conditional do
end
it "indicates that resource convergence should not continue" do
- expect(@conditional.continue?).to be_false
+ expect(@conditional.continue?).to be_falsey
end
end
end
describe "when created as a `not_if`" do
- describe "after running a successful/true command" do
+ describe "after running a successful/true command given as a string" do
before do
@conditional = Chef::Resource::Conditional.not_if(@parent_resource, "true")
end
it "indicates that resource convergence should not continue" do
- expect(@conditional.continue?).to be_false
+ expect(@conditional.continue?).to be_falsey
end
end
- describe "after running a failed/false command" do
+ describe "after running a failed/false command given as a string" do
before do
@status.send("success?=", false)
@conditional = Chef::Resource::Conditional.not_if(@parent_resource, "false")
end
it "indicates that resource convergence should continue" do
- expect(@conditional.continue?).to be_true
+ expect(@conditional.continue?).to be_truthy
+ end
+ end
+
+ describe "after running a successful/true command given as an array" do
+ before do
+ @conditional = Chef::Resource::Conditional.not_if(@parent_resource, ["true"])
+ end
+
+ it "indicates that resource convergence should not continue" do
+ expect(@conditional.continue?).to be false
+ end
+ end
+
+ describe "after running a failed/false command given as an array" do
+ before do
+ @status.send("success?=", false)
+ @conditional = Chef::Resource::Conditional.not_if(@parent_resource, ["false"])
+ end
+
+ it "indicates that resource convergence should continue" do
+ expect(@conditional.continue?).to be true
end
end
@@ -134,7 +176,7 @@ describe Chef::Resource::Conditional do
end
it 'indicates that resource convergence should continue' do
- expect(@conditional.continue?).to be_true
+ expect(@conditional.continue?).to be_truthy
end
it 'should log a warning' do
@@ -149,7 +191,7 @@ describe Chef::Resource::Conditional do
end
it "indicates that resource convergence should not continue" do
- expect(@conditional.continue?).to be_false
+ expect(@conditional.continue?).to be_falsey
end
end
@@ -159,9 +201,8 @@ describe Chef::Resource::Conditional do
end
it "indicates that resource convergence should continue" do
- expect(@conditional.continue?).to be_true
+ expect(@conditional.continue?).to be_truthy
end
end
end
-
end
diff --git a/spec/unit/resource/deploy_spec.rb b/spec/unit/resource/deploy_spec.rb
index 6592fae26c..0403a7ba6b 100644
--- a/spec/unit/resource/deploy_spec.rb
+++ b/spec/unit/resource/deploy_spec.rb
@@ -115,9 +115,9 @@ describe Chef::Resource::Deploy do
end
it "has a boolean attribute for svn_force_export defaulting to false" do
- expect(@resource.svn_force_export).to be_false
+ expect(@resource.svn_force_export).to be_falsey
@resource.svn_force_export true
- expect(@resource.svn_force_export).to be_true
+ expect(@resource.svn_force_export).to be_truthy
expect {@resource.svn_force_export(10053)}.to raise_error(ArgumentError)
end
diff --git a/spec/unit/resource/dsc_script_spec.rb b/spec/unit/resource/dsc_script_spec.rb
index eb9d19e553..71103ea590 100644
--- a/spec/unit/resource/dsc_script_spec.rb
+++ b/spec/unit/resource/dsc_script_spec.rb
@@ -70,6 +70,38 @@ describe Chef::Resource::DscScript do
expect(dsc_test_resource.configuration_data_script).to eq(configuration_data_script)
end
+ context "when calling imports" do
+ let(:module_name) { 'FooModule' }
+ let(:module_name_b) { 'BarModule' }
+ let(:dsc_resources) { ['ResourceA', 'ResourceB'] }
+
+ it "allows an arbitrary number of resources to be set for a module to be set" do
+ dsc_test_resource.imports module_name, *dsc_resources
+ module_imports = dsc_test_resource.imports[module_name]
+ expect(module_imports).to eq(dsc_resources)
+ end
+
+ it "adds * to the imports when no resources are set for a moudle" do
+ dsc_test_resource.imports module_name
+ module_imports = dsc_test_resource.imports[module_name]
+ expect(module_imports).to eq(['*'])
+ end
+
+ it "allows an arbitrary number of modules" do
+ dsc_test_resource.imports module_name
+ dsc_test_resource.imports module_name_b
+ expect(dsc_test_resource.imports).to have_key(module_name)
+ expect(dsc_test_resource.imports).to have_key(module_name_b)
+ end
+
+ it "allows resources to be added for a module" do
+ dsc_test_resource.imports module_name, dsc_resources[0]
+ dsc_test_resource.imports module_name, dsc_resources[1]
+ module_imports = dsc_test_resource.imports[module_name]
+ expect(module_imports).to eq(dsc_resources)
+ end
+ end
+
it "raises an ArgumentError exception if an attempt is made to set the code attribute when the command attribute is already set" do
dsc_test_resource.command(configuration_path)
expect { dsc_test_resource.code(configuration_code) }.to raise_error(ArgumentError)
diff --git a/spec/unit/resource/execute_spec.rb b/spec/unit/resource/execute_spec.rb
index 70b9d87d4c..09160ddbd0 100644
--- a/spec/unit/resource/execute_spec.rb
+++ b/spec/unit/resource/execute_spec.rb
@@ -28,4 +28,8 @@ describe Chef::Resource::Execute do
expect(execute_resource.guard_interpreter).to be(:execute)
end
+ it "defaults to not being a guard interpreter" do
+ expect(execute_resource.is_guard_interpreter).to eq(false)
+ end
+
end
diff --git a/spec/unit/resource/file/verification_spec.rb b/spec/unit/resource/file/verification_spec.rb
new file mode 100644
index 0000000000..3609d9d482
--- /dev/null
+++ b/spec/unit/resource/file/verification_spec.rb
@@ -0,0 +1,111 @@
+#
+# Author:: Steven Danna (<steve@chef.io>)
+# Copyright:: Copyright (c) 2014 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 'spec_helper'
+
+describe Chef::Resource::File::Verification do
+ let(:t_block) { Proc.new { true } }
+ let(:f_block) { Proc.new { false } }
+ let(:path_block) { Proc.new { |path| path }}
+ let(:temp_path) { "/tmp/foobar" }
+
+ describe "verification registration" do
+ it "registers a verification for later use" do
+ class Chef::Resource::File::Verification::Wombat < Chef::Resource::File::Verification
+ provides :tabmow
+ end
+ expect(Chef::Resource::File::Verification.lookup(:tabmow)).to eq(Chef::Resource::File::Verification::Wombat)
+ end
+
+ it "raises an error if a verification can't be found" do
+ expect{Chef::Resource::File::Verification.lookup(:dne)}.to raise_error(Chef::Exceptions::VerificationNotFound)
+ end
+ end
+
+ describe "#verify" do
+ let(:parent_resource) { Chef::Resource.new("llama") }
+
+ it "expects a string argument" do
+ v = Chef::Resource::File::Verification.new(parent_resource, nil, {}) {}
+ expect{ v.verify("/foo/bar") }.to_not raise_error
+ expect{ v.verify }.to raise_error
+ end
+
+ it "accepts an options hash" do
+ v = Chef::Resource::File::Verification.new(parent_resource, nil, {}) {}
+ expect{ v.verify("/foo/bar", {:future => true}) }.to_not raise_error
+ end
+
+ context "with a verification block" do
+ it "passes a file path to the block" do
+ v = Chef::Resource::File::Verification.new(parent_resource, nil, {}, &path_block)
+ expect(v.verify(temp_path)).to eq(temp_path)
+ end
+
+ it "returns true if the block returned true" do
+ v = Chef::Resource::File::Verification.new(parent_resource, nil, {}, &t_block)
+ expect(v.verify(temp_path)).to eq(true)
+ end
+
+ it "returns false if the block returned false" do
+ v = Chef::Resource::File::Verification.new(parent_resource, nil, {}, &f_block)
+ expect(v.verify(temp_path)).to eq(false)
+ end
+ end
+
+ context "with a verification command(String)" do
+ it "substitutes \%{file} with the path" do
+ test_command = if windows?
+ "if \"#{temp_path}\" == \"%{file}\" (exit 0) else (exit 1)"
+ else
+ "test #{temp_path} = %{file}"
+ end
+ v = Chef::Resource::File::Verification.new(parent_resource, test_command, {})
+ expect(v.verify(temp_path)).to eq(true)
+ end
+
+ it "returns false if the command fails" do
+ v = Chef::Resource::File::Verification.new(parent_resource, "false", {})
+ expect(v.verify(temp_path)).to eq(false)
+ end
+
+ it "returns true if the command succeeds" do
+ v = Chef::Resource::File::Verification.new(parent_resource, "true", {})
+ expect(v.verify(temp_path)).to eq(true)
+ end
+ end
+
+ context "with a named verification(Symbol)" do
+ before(:each) do
+ class Chef::Resource::File::Verification::Turtle < Chef::Resource::File::Verification
+ provides :cats
+ def verify(path, opts)
+ end
+ end
+ end
+
+ it "delegates to the registered verification" do
+ registered_verification = double()
+ allow(Chef::Resource::File::Verification::Turtle).to receive(:new).and_return(registered_verification)
+ v = Chef::Resource::File::Verification.new(parent_resource, :cats, {})
+ expect(registered_verification).to receive(:verify).with(temp_path, {})
+ v.verify(temp_path, {})
+ end
+ end
+ end
+end
diff --git a/spec/unit/resource/file_spec.rb b/spec/unit/resource/file_spec.rb
index cfa7511673..db52e35004 100644
--- a/spec/unit/resource/file_spec.rb
+++ b/spec/unit/resource/file_spec.rb
@@ -66,6 +66,20 @@ describe Chef::Resource::File do
expect { @resource.action :blues }.to raise_error(ArgumentError)
end
+ it "should accept a block, symbol, or string for verify" do
+ expect {@resource.verify {}}.not_to raise_error
+ expect {@resource.verify ""}.not_to raise_error
+ expect {@resource.verify :json}.not_to raise_error
+ expect {@resource.verify true}.to raise_error
+ expect {@resource.verify false}.to raise_error
+ end
+
+ it "should accept multiple verify statements" do
+ @resource.verify "foo"
+ @resource.verify "bar"
+ @resource.verify.length == 2
+ end
+
it "should use the object name as the path by default" do
expect(@resource.path).to eql("fakey_fakerton")
end
diff --git a/spec/unit/resource/openbsd_package_spec.rb b/spec/unit/resource/openbsd_package_spec.rb
new file mode 100644
index 0000000000..95921c2f02
--- /dev/null
+++ b/spec/unit/resource/openbsd_package_spec.rb
@@ -0,0 +1,49 @@
+#
+# Authors:: AJ Christensen (<aj@opscode.com>)
+# Richard Manyanza (<liseki@nyikacraftsmen.com>)
+# Scott Bonds (<scott@ggr.com>)
+# Copyright:: Copyright (c) 2008 Opscode, Inc.
+# Copyright:: Copyright (c) 2014 Richard Manyanza, Scott Bonds
+# 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 'spec_helper'
+require 'ostruct'
+
+describe Chef::Resource::OpenbsdPackage do
+
+ before(:each) do
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+ @resource = Chef::Resource::OpenbsdPackage.new("foo", @run_context)
+ end
+
+ describe "Initialization" do
+ it "should return a Chef::Resource::OpenbsdPackage" do
+ expect(@resource).to be_a_kind_of(Chef::Resource::OpenbsdPackage)
+ end
+
+ it "should set the resource_name to :openbsd_package" do
+ expect(@resource.resource_name).to eql(:openbsd_package)
+ end
+
+ it "should not set the provider" do
+ expect(@resource.provider).to be_nil
+ end
+ end
+
+end
+
diff --git a/spec/unit/resource/remote_file_spec.rb b/spec/unit/resource/remote_file_spec.rb
index 14d2fb97bc..3731d1aee2 100644
--- a/spec/unit/resource/remote_file_spec.rb
+++ b/spec/unit/resource/remote_file_spec.rb
@@ -113,40 +113,40 @@ describe Chef::Resource::RemoteFile do
describe "ftp_active_mode" do
it "should accept a boolean for the ftp_active_mode object" do
@resource.ftp_active_mode true
- expect(@resource.ftp_active_mode).to be_true
+ expect(@resource.ftp_active_mode).to be_truthy
end
it "should default to false" do
- expect(@resource.ftp_active_mode).to be_false
+ expect(@resource.ftp_active_mode).to be_falsey
end
end
describe "conditional get options" do
it "defaults to using etags and last modified" do
- expect(@resource.use_etags).to be_true
- expect(@resource.use_last_modified).to be_true
+ expect(@resource.use_etags).to be_truthy
+ expect(@resource.use_last_modified).to be_truthy
end
it "enable or disables etag and last modified options as a group" do
@resource.use_conditional_get(false)
- expect(@resource.use_etags).to be_false
- expect(@resource.use_last_modified).to be_false
+ expect(@resource.use_etags).to be_falsey
+ expect(@resource.use_last_modified).to be_falsey
@resource.use_conditional_get(true)
- expect(@resource.use_etags).to be_true
- expect(@resource.use_last_modified).to be_true
+ expect(@resource.use_etags).to be_truthy
+ expect(@resource.use_last_modified).to be_truthy
end
it "disables etags indivdually" do
@resource.use_etags(false)
- expect(@resource.use_etags).to be_false
- expect(@resource.use_last_modified).to be_true
+ expect(@resource.use_etags).to be_falsey
+ expect(@resource.use_last_modified).to be_truthy
end
it "disables last modified individually" do
@resource.use_last_modified(false)
- expect(@resource.use_last_modified).to be_false
- expect(@resource.use_etags).to be_true
+ expect(@resource.use_last_modified).to be_falsey
+ expect(@resource.use_etags).to be_truthy
end
end
diff --git a/spec/unit/resource/resource_notification_spec.rb b/spec/unit/resource/resource_notification_spec.rb
index 8d8eeb4503..7f6b124d4d 100644
--- a/spec/unit/resource/resource_notification_spec.rb
+++ b/spec/unit/resource/resource_notification_spec.rb
@@ -24,34 +24,34 @@ describe Chef::Resource::Notification do
end
it "has a resource to be notified" do
- @notification.resource.should == :service_apache
+ expect(@notification.resource).to eq(:service_apache)
end
it "has an action to take on the service" do
- @notification.action.should == :restart
+ expect(@notification.action).to eq(:restart)
end
it "has a notifying resource" do
- @notification.notifying_resource.should == :template_httpd_conf
+ expect(@notification.notifying_resource).to eq(:template_httpd_conf)
end
it "is a duplicate of another notification with the same target resource and action" do
other = Chef::Resource::Notification.new(:service_apache, :restart, :sync_web_app_code)
- @notification.duplicates?(other).should be_true
+ expect(@notification.duplicates?(other)).to be_truthy
end
it "is not a duplicate of another notification if the actions differ" do
other = Chef::Resource::Notification.new(:service_apache, :enable, :install_apache)
- @notification.duplicates?(other).should be_false
+ expect(@notification.duplicates?(other)).to be_falsey
end
it "is not a duplicate of another notification if the target resources differ" do
other = Chef::Resource::Notification.new(:service_sshd, :restart, :template_httpd_conf)
- @notification.duplicates?(other).should be_false
+ expect(@notification.duplicates?(other)).to be_falsey
end
it "raises an ArgumentError if you try to check a non-ducktype object for duplication" do
- lambda {@notification.duplicates?(:not_a_notification)}.should raise_error(ArgumentError)
+ expect {@notification.duplicates?(:not_a_notification)}.to raise_error(ArgumentError)
end
it "takes no action to resolve a resource reference that doesn't need to be resolved" do
@@ -62,7 +62,7 @@ describe Chef::Resource::Notification do
@resource_collection = Chef::ResourceCollection.new
# would raise an error since the resource is not in the collection
@notification.resolve_resource_reference(@resource_collection)
- @notification.resource.should == @keyboard_cat
+ expect(@notification.resource).to eq(@keyboard_cat)
end
it "resolves a lazy reference to a resource" do
@@ -73,7 +73,7 @@ describe Chef::Resource::Notification do
@long_cat = Chef::Resource::Cat.new("long_cat")
@notification.notifying_resource = @long_cat
@notification.resolve_resource_reference(@resource_collection)
- @notification.resource.should == @keyboard_cat
+ expect(@notification.resource).to eq(@keyboard_cat)
end
it "resolves a lazy reference to its notifying resource" do
@@ -84,7 +84,7 @@ describe Chef::Resource::Notification do
@resource_collection = Chef::ResourceCollection.new
@resource_collection << @long_cat
@notification.resolve_resource_reference(@resource_collection)
- @notification.notifying_resource.should == @long_cat
+ expect(@notification.notifying_resource).to eq(@long_cat)
end
it "resolves lazy references to both its resource and its notifying resource" do
@@ -96,8 +96,8 @@ describe Chef::Resource::Notification do
@long_cat = Chef::Resource::Cat.new("long_cat")
@resource_collection << @long_cat
@notification.resolve_resource_reference(@resource_collection)
- @notification.resource.should == @keyboard_cat
- @notification.notifying_resource.should == @long_cat
+ expect(@notification.resource).to eq(@keyboard_cat)
+ expect(@notification.notifying_resource).to eq(@long_cat)
end
it "raises a RuntimeError if you try to reference multiple resources" do
@@ -109,7 +109,7 @@ describe Chef::Resource::Notification do
@resource_collection << @cheez_cat
@long_cat = Chef::Resource::Cat.new("long_cat")
@notification.notifying_resource = @long_cat
- lambda {@notification.resolve_resource_reference(@resource_collection)}.should raise_error(RuntimeError)
+ expect {@notification.resolve_resource_reference(@resource_collection)}.to raise_error(RuntimeError)
end
it "raises a RuntimeError if you try to reference multiple notifying resources" do
@@ -121,7 +121,7 @@ describe Chef::Resource::Notification do
@resource_collection << @cheez_cat
@keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
@notification.resource = @keyboard_cat
- lambda {@notification.resolve_resource_reference(@resource_collection)}.should raise_error(RuntimeError)
+ expect {@notification.resolve_resource_reference(@resource_collection)}.to raise_error(RuntimeError)
end
it "raises a RuntimeError if it can't find a resource in the resource collection when resolving a lazy reference" do
@@ -131,7 +131,7 @@ describe Chef::Resource::Notification do
@resource_collection << @cheez_cat
@long_cat = Chef::Resource::Cat.new("long_cat")
@notification.notifying_resource = @long_cat
- lambda {@notification.resolve_resource_reference(@resource_collection)}.should raise_error(RuntimeError)
+ expect {@notification.resolve_resource_reference(@resource_collection)}.to raise_error(RuntimeError)
end
it "raises a RuntimeError if it can't find a notifying resource in the resource collection when resolving a lazy reference" do
@@ -141,7 +141,7 @@ describe Chef::Resource::Notification do
@resource_collection << @cheez_cat
@keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
@notification.resource = @keyboard_cat
- lambda {@notification.resolve_resource_reference(@resource_collection)}.should raise_error(RuntimeError)
+ expect {@notification.resolve_resource_reference(@resource_collection)}.to raise_error(RuntimeError)
end
it "raises an ArgumentError if improper syntax is used in the lazy reference to its resource" do
@@ -151,7 +151,7 @@ describe Chef::Resource::Notification do
@resource_collection << @keyboard_cat
@long_cat = Chef::Resource::Cat.new("long_cat")
@notification.notifying_resource = @long_cat
- lambda {@notification.resolve_resource_reference(@resource_collection)}.should raise_error(ArgumentError)
+ expect {@notification.resolve_resource_reference(@resource_collection)}.to raise_error(ArgumentError)
end
it "raises an ArgumentError if improper syntax is used in the lazy reference to its notifying resource" do
@@ -161,7 +161,7 @@ describe Chef::Resource::Notification do
@resource_collection << @long_cat
@keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
@notification.resource = @keyboard_cat
- lambda {@notification.resolve_resource_reference(@resource_collection)}.should raise_error(ArgumentError)
+ expect {@notification.resolve_resource_reference(@resource_collection)}.to raise_error(ArgumentError)
end
# Create test to resolve lazy references to both notifying resource and dest. resource
diff --git a/spec/unit/resource/rpm_package_spec.rb b/spec/unit/resource/rpm_package_spec.rb
index d209c6a5a2..d3b505fff5 100644
--- a/spec/unit/resource/rpm_package_spec.rb
+++ b/spec/unit/resource/rpm_package_spec.rb
@@ -32,3 +32,15 @@ describe Chef::Resource::RpmPackage, "initialize" do
end
end
+
+describe Chef::Resource::RpmPackage, "allow_downgrade" do
+ before(:each) do
+ @resource = Chef::Resource::RpmPackage.new("foo")
+ end
+
+ it "should allow you to specify whether allow_downgrade is true or false" do
+ expect { @resource.allow_downgrade true }.not_to raise_error
+ expect { @resource.allow_downgrade false }.not_to raise_error
+ expect { @resource.allow_downgrade "monkey" }.to raise_error(ArgumentError)
+ end
+end
diff --git a/spec/unit/resource/scm_spec.rb b/spec/unit/resource/scm_spec.rb
index daabdd03ba..72319277ab 100644
--- a/spec/unit/resource/scm_spec.rb
+++ b/spec/unit/resource/scm_spec.rb
@@ -110,22 +110,22 @@ describe Chef::Resource::Scm do
it "takes a boolean for #enable_submodules" do
@resource.enable_submodules true
- expect(@resource.enable_submodules).to be_true
+ expect(@resource.enable_submodules).to be_truthy
expect {@resource.enable_submodules "lolz"}.to raise_error(ArgumentError)
end
it "defaults to not enabling submodules" do
- expect(@resource.enable_submodules).to be_false
+ expect(@resource.enable_submodules).to be_falsey
end
it "takes a boolean for #enable_checkout" do
@resource.enable_checkout true
- expect(@resource.enable_checkout).to be_true
+ expect(@resource.enable_checkout).to be_truthy
expect {@resource.enable_checkout "lolz"}.to raise_error(ArgumentError)
end
it "defaults to enabling checkout" do
- expect(@resource.enable_checkout).to be_true
+ expect(@resource.enable_checkout).to be_truthy
end
it "takes a string for the remote" do
diff --git a/spec/unit/resource/script_spec.rb b/spec/unit/resource/script_spec.rb
index 9d744baaa5..4affee8e8c 100644
--- a/spec/unit/resource/script_spec.rb
+++ b/spec/unit/resource/script_spec.rb
@@ -29,18 +29,16 @@ describe Chef::Resource::Script do
expect(script_resource.interpreter).to eql("naaaaNaNaNaaNaaNaaNaa")
end
- describe "when it has interpreter and flags" do
+ context "when it has interpreter and flags" do
before do
- script_resource.command("grep")
script_resource.interpreter("gcc")
script_resource.flags("-al")
end
- it "returns the command as its identity" do
- expect(script_resource.identity).to eq("grep")
+ it "returns the name as its identity" do
+ expect(script_resource.identity).to eq(resource_instance_name)
end
end
it_behaves_like "a script resource"
end
-
diff --git a/spec/unit/resource/subversion_spec.rb b/spec/unit/resource/subversion_spec.rb
index 4cbca9be11..5cd5d0de80 100644
--- a/spec/unit/resource/subversion_spec.rb
+++ b/spec/unit/resource/subversion_spec.rb
@@ -62,6 +62,6 @@ describe Chef::Resource::Subversion do
it "hides password from custom exception message" do
@svn.svn_password "l33th4x0rpa$$w0rd"
e = @svn.customize_exception(Chef::Exceptions::Exec.new "Exception with password #{@svn.svn_password}")
- expect(e.message.include?(@svn.svn_password)).to be_false
+ expect(e.message.include?(@svn.svn_password)).to be_falsey
end
end
diff --git a/spec/unit/resource_builder_spec.rb b/spec/unit/resource_builder_spec.rb
new file mode 100644
index 0000000000..e38c7fb63a
--- /dev/null
+++ b/spec/unit/resource_builder_spec.rb
@@ -0,0 +1 @@
+# see spec/unit/recipe_spec.rb
diff --git a/spec/unit/resource_collection/resource_list_spec.rb b/spec/unit/resource_collection/resource_list_spec.rb
index 641fe55c8d..1e6c477854 100644
--- a/spec/unit/resource_collection/resource_list_spec.rb
+++ b/spec/unit/resource_collection/resource_list_spec.rb
@@ -60,7 +60,7 @@ describe Chef::ResourceCollection::ResourceList do
end
it "should be empty by default" do
- expect(resource_list.empty?).to be_true
+ expect(resource_list.empty?).to be_truthy
end
describe "when resources are inserted" do
@@ -100,7 +100,7 @@ describe Chef::ResourceCollection::ResourceList do
end
it "should be able to check if the list is empty" do
- expect(resource_list.empty?).to be_false
+ expect(resource_list.empty?).to be_falsey
end
end
end
diff --git a/spec/unit/resource_collection/resource_set_spec.rb b/spec/unit/resource_collection/resource_set_spec.rb
index 8be31cd9f6..0e25934216 100644
--- a/spec/unit/resource_collection/resource_set_spec.rb
+++ b/spec/unit/resource_collection/resource_set_spec.rb
@@ -166,15 +166,15 @@ describe Chef::ResourceCollection::ResourceSet do
describe "validate_lookup_spec!" do
it "accepts a string of the form 'resource_type[resource_name]'" do
- expect(collection.validate_lookup_spec!("resource_type[resource_name]")).to be_true
+ expect(collection.validate_lookup_spec!("resource_type[resource_name]")).to be_truthy
end
it "accepts a single-element :resource_type => 'resource_name' Hash" do
- expect(collection.validate_lookup_spec!(:service => "apache2")).to be_true
+ expect(collection.validate_lookup_spec!(:service => "apache2")).to be_truthy
end
it "accepts a chef resource object" do
- expect(collection.validate_lookup_spec!(zen_master)).to be_true
+ expect(collection.validate_lookup_spec!(zen_master)).to be_truthy
end
it "rejects a malformed query string" do
diff --git a/spec/unit/resource_collection/stepable_iterator_spec.rb b/spec/unit/resource_collection/stepable_iterator_spec.rb
index b649f8be6e..b34b7140fe 100644
--- a/spec/unit/resource_collection/stepable_iterator_spec.rb
+++ b/spec/unit/resource_collection/stepable_iterator_spec.rb
@@ -21,7 +21,7 @@ describe Chef::ResourceCollection::StepableIterator do
CRSI = Chef::ResourceCollection::StepableIterator
it "has an empty array for its collection by default" do
- CRSI.new.collection.should == []
+ expect(CRSI.new.collection).to eq([])
end
describe "doing basic iteration" do
@@ -31,8 +31,8 @@ describe Chef::ResourceCollection::StepableIterator do
end
it "re-initializes the instance with a collection" do
- @iterator.collection.should equal(@simple_collection)
- @iterator.size.should == 4
+ expect(@iterator.collection).to equal(@simple_collection)
+ expect(@iterator.size).to eq(4)
end
it "iterates over the collection" do
@@ -40,7 +40,7 @@ describe Chef::ResourceCollection::StepableIterator do
@iterator.each do |int|
sum += int
end
- sum.should == 10
+ expect(sum).to eq(10)
end
it "iterates over the collection with each_index" do
@@ -48,8 +48,8 @@ describe Chef::ResourceCollection::StepableIterator do
@iterator.each_index do |idx|
collected_by_index << @simple_collection[idx]
end
- collected_by_index.should == @simple_collection
- collected_by_index.should_not equal(@simple_collection)
+ expect(collected_by_index).to eq(@simple_collection)
+ expect(collected_by_index).not_to equal(@simple_collection)
end
it "iterates over the collection with index and element" do
@@ -57,7 +57,7 @@ describe Chef::ResourceCollection::StepableIterator do
@iterator.each_with_index do |element, index|
collected[index] = element
end
- collected.should == {0=>1, 1=>2, 2=>3, 3=>4}
+ expect(collected).to eq({0=>1, 1=>2, 2=>3, 3=>4})
end
end
@@ -76,49 +76,49 @@ describe Chef::ResourceCollection::StepableIterator do
end
it "allows the iteration to be paused" do
- @snitch_var.should == 23
+ expect(@snitch_var).to eq(23)
end
it "allows the iteration to be resumed" do
- @snitch_var.should == 23
+ expect(@snitch_var).to eq(23)
@iterator.resume
- @snitch_var.should == 42
+ expect(@snitch_var).to eq(42)
end
it "allows iteration to be rewound" do
@iterator.skip_back(2)
@iterator.resume
- @snitch_var.should == 23
+ expect(@snitch_var).to eq(23)
@iterator.resume
- @snitch_var.should == 42
+ expect(@snitch_var).to eq(42)
end
it "allows iteration to be fast forwarded" do
@iterator.skip_forward
@iterator.resume
- @snitch_var.should == 23
+ expect(@snitch_var).to eq(23)
end
it "allows iteration to be rewound" do
@snitch_var = nil
@iterator.rewind
- @iterator.position.should == 0
+ expect(@iterator.position).to eq(0)
@iterator.resume
- @snitch_var.should == 23
+ expect(@snitch_var).to eq(23)
end
it "allows iteration to be stepped" do
@snitch_var = nil
@iterator.rewind
@iterator.step
- @iterator.position.should == 1
- @snitch_var.should == 23
+ expect(@iterator.position).to eq(1)
+ expect(@snitch_var).to eq(23)
end
it "doesn't step if there are no more steps" do
- @iterator.step.should == 3
- lambda {@iterator.step}.should_not raise_error
- @iterator.step.should be_nil
+ expect(@iterator.step).to eq(3)
+ expect {@iterator.step}.not_to raise_error
+ expect(@iterator.step).to be_nil
end
it "allows the iteration to start by being stepped" do
@@ -126,17 +126,17 @@ describe Chef::ResourceCollection::StepableIterator do
@iterator = CRSI.for_collection(@collection)
@iterator.iterate_on(:element) { |proc| proc.call }
@iterator.step
- @iterator.position.should == 1
- @snitch_var.should == 23
+ expect(@iterator.position).to eq(1)
+ expect(@snitch_var).to eq(23)
end
it "should work correctly when elements are added to the collection during iteration" do
@collection.insert(2, lambda { @snitch_var = 815})
@collection.insert(3, lambda { @iterator.pause })
@iterator.resume
- @snitch_var.should == 815
+ expect(@snitch_var).to eq(815)
@iterator.resume
- @snitch_var.should == 42
+ expect(@snitch_var).to eq(42)
end
end
diff --git a/spec/unit/resource_collection_spec.rb b/spec/unit/resource_collection_spec.rb
index 5966fdd1f2..b43b012dfc 100644
--- a/spec/unit/resource_collection_spec.rb
+++ b/spec/unit/resource_collection_spec.rb
@@ -29,39 +29,39 @@ describe Chef::ResourceCollection do
describe "initialize" do
it "should return a Chef::ResourceCollection" do
- rc.should be_kind_of(Chef::ResourceCollection)
+ expect(rc).to be_kind_of(Chef::ResourceCollection)
end
end
describe "[]" do
it "should accept Chef::Resources through [index]" do
- lambda { rc[0] = resource }.should_not raise_error
- lambda { rc[0] = "string" }.should raise_error(ArgumentError)
+ expect { rc[0] = resource }.not_to raise_error
+ expect { rc[0] = "string" }.to raise_error(ArgumentError)
end
it "should allow you to fetch Chef::Resources by position" do
rc[0] = resource
- rc[0].should eql(resource)
+ expect(rc[0]).to eql(resource)
end
end
describe "push" do
it "should accept Chef::Resources through pushing" do
- lambda { rc.push(resource) }.should_not raise_error
- lambda { rc.push("string") }.should raise_error(ArgumentError)
+ expect { rc.push(resource) }.not_to raise_error
+ expect { rc.push("string") }.to raise_error(ArgumentError)
end
end
describe "<<" do
it "should accept the << operator" do
- lambda { rc << resource }.should_not raise_error
+ expect { rc << resource }.not_to raise_error
end
end
describe "insert" do
it "should accept only Chef::Resources" do
- lambda { rc.insert(resource) }.should_not raise_error
- lambda { rc.insert("string") }.should raise_error(ArgumentError)
+ expect { rc.insert(resource) }.not_to raise_error
+ expect { rc.insert("string") }.to raise_error(ArgumentError)
end
it "should accept named arguments in any order" do
@@ -73,8 +73,8 @@ describe Chef::ResourceCollection do
zmr = Chef::Resource::ZenMaster.new("there is no spoon")
rc.insert(resource)
rc.insert(zmr)
- rc[0].should eql(resource)
- rc[1].should eql(zmr)
+ expect(rc[0]).to eql(resource)
+ expect(rc[1]).to eql(zmr)
end
it "should insert resources to the middle of the collection if called while executing a run" do
@@ -88,9 +88,9 @@ describe Chef::ResourceCollection do
rc.insert(resource_to_inject) if resource == zmr
end
- rc[0].should eql(zmr)
- rc[1].should eql(resource_to_inject)
- rc[2].should eql(dummy)
+ expect(rc[0]).to eql(zmr)
+ expect(rc[1]).to eql(resource_to_inject)
+ expect(rc[2]).to eql(dummy)
end
end
@@ -98,19 +98,19 @@ describe Chef::ResourceCollection do
it "should allow you to iterate over every resource in the collection" do
load_up_resources
results = Array.new
- lambda {
+ expect {
rc.each do |r|
results << r.name
end
- }.should_not raise_error
+ }.not_to raise_error
results.each_index do |i|
case i
when 0
- results[i].should eql("dog")
+ expect(results[i]).to eql("dog")
when 1
- results[i].should eql("cat")
+ expect(results[i]).to eql("cat")
when 2
- results[i].should eql("monkey")
+ expect(results[i]).to eql("monkey")
end
end
end
@@ -120,19 +120,19 @@ describe Chef::ResourceCollection do
it "should allow you to iterate over every resource by index" do
load_up_resources
results = Array.new
- lambda {
+ expect {
rc.each_index do |i|
results << rc[i].name
end
- }.should_not raise_error
+ }.not_to raise_error
results.each_index do |i|
case i
when 0
- results[i].should eql("dog")
+ expect(results[i]).to eql("dog")
when 1
- results[i].should eql("cat")
+ expect(results[i]).to eql("cat")
when 2
- results[i].should eql("monkey")
+ expect(results[i]).to eql("monkey")
end
end
end
@@ -142,23 +142,23 @@ describe Chef::ResourceCollection do
it "should allow you to find resources by name via lookup" do
zmr = Chef::Resource::ZenMaster.new("dog")
rc << zmr
- rc.lookup(zmr.to_s).should eql(zmr)
+ expect(rc.lookup(zmr.to_s)).to eql(zmr)
zmr = Chef::Resource::ZenMaster.new("cat")
rc[0] = zmr
- rc.lookup(zmr).should eql(zmr)
+ expect(rc.lookup(zmr)).to eql(zmr)
zmr = Chef::Resource::ZenMaster.new("monkey")
rc.push(zmr)
- rc.lookup(zmr).should eql(zmr)
+ expect(rc.lookup(zmr)).to eql(zmr)
end
it "should raise an exception if you send something strange to lookup" do
- lambda { rc.lookup(:symbol) }.should raise_error(ArgumentError)
+ expect { rc.lookup(:symbol) }.to raise_error(ArgumentError)
end
it "should raise an exception if it cannot find a resource with lookup" do
- lambda { rc.lookup("zen_master[dog]") }.should raise_error(Chef::Exceptions::ResourceNotFound)
+ expect { rc.lookup("zen_master[dog]") }.to raise_error(Chef::Exceptions::ResourceNotFound)
end
end
@@ -166,81 +166,81 @@ describe Chef::ResourceCollection do
it "should find a resource by symbol and name (:zen_master => monkey)" do
load_up_resources
- rc.resources(:zen_master => "monkey").name.should eql("monkey")
+ expect(rc.resources(:zen_master => "monkey").name).to eql("monkey")
end
it "should find a resource by symbol and array of names (:zen_master => [a,b])" do
load_up_resources
results = rc.resources(:zen_master => [ "monkey", "dog" ])
- results.length.should eql(2)
+ expect(results.length).to eql(2)
check_by_names(results, "monkey", "dog")
end
it "should find resources of multiple kinds (:zen_master => a, :file => b)" do
load_up_resources
results = rc.resources(:zen_master => "monkey", :file => "something")
- results.length.should eql(2)
+ expect(results.length).to eql(2)
check_by_names(results, "monkey", "something")
end
it "should find a resource by string zen_master[a]" do
load_up_resources
- rc.resources("zen_master[monkey]").name.should eql("monkey")
+ expect(rc.resources("zen_master[monkey]").name).to eql("monkey")
end
it "should find resources by strings of zen_master[a,b]" do
load_up_resources
results = rc.resources("zen_master[monkey,dog]")
- results.length.should eql(2)
+ expect(results.length).to eql(2)
check_by_names(results, "monkey", "dog")
end
it "should find resources of multiple types by strings of zen_master[a]" do
load_up_resources
results = rc.resources("zen_master[monkey]", "file[something]")
- results.length.should eql(2)
+ expect(results.length).to eql(2)
check_by_names(results, "monkey", "something")
end
it "should raise an exception if you pass a bad name to resources" do
- lambda { rc.resources("michael jackson") }.should raise_error(ArgumentError)
+ expect { rc.resources("michael jackson") }.to raise_error(ArgumentError)
end
it "should raise an exception if you pass something other than a string or hash to resource" do
- lambda { rc.resources([Array.new]) }.should raise_error(ArgumentError)
+ expect { rc.resources([Array.new]) }.to raise_error(ArgumentError)
end
it "raises an error when attempting to find a resource that does not exist" do
- lambda {rc.find("script[nonesuch]")}.should raise_error(Chef::Exceptions::ResourceNotFound)
+ expect {rc.find("script[nonesuch]")}.to raise_error(Chef::Exceptions::ResourceNotFound)
end
end
describe "when validating a resource query object" do
it "accepts a string of the form 'resource_type[resource_name]'" do
- rc.validate_lookup_spec!("resource_type[resource_name]").should be_true
+ expect(rc.validate_lookup_spec!("resource_type[resource_name]")).to be_truthy
end
it "accepts a single-element :resource_type => 'resource_name' Hash" do
- rc.validate_lookup_spec!(:service => "apache2").should be_true
+ expect(rc.validate_lookup_spec!(:service => "apache2")).to be_truthy
end
it "accepts a chef resource object" do
res = Chef::Resource.new("foo", nil)
- rc.validate_lookup_spec!(res).should be_true
+ expect(rc.validate_lookup_spec!(res)).to be_truthy
end
it "rejects a malformed query string" do
- lambda do
+ expect do
rc.validate_lookup_spec!("resource_type[missing-end-bracket")
- end.should raise_error(Chef::Exceptions::InvalidResourceSpecification)
+ end.to raise_error(Chef::Exceptions::InvalidResourceSpecification)
end
it "rejects an argument that is not a String, Hash, or Chef::Resource" do
- lambda do
+ expect do
rc.validate_lookup_spec!(Object.new)
- end.should raise_error(Chef::Exceptions::InvalidResourceSpecification)
+ end.to raise_error(Chef::Exceptions::InvalidResourceSpecification)
end
end
@@ -248,8 +248,8 @@ describe Chef::ResourceCollection do
describe "to_json" do
it "should serialize to json" do
json = rc.to_json
- json.should =~ /json_class/
- json.should =~ /instance_vars/
+ expect(json).to match(/json_class/)
+ expect(json).to match(/instance_vars/)
end
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
@@ -266,27 +266,27 @@ describe Chef::ResourceCollection do
rc << resource
json = Chef::JSONCompat.to_json(rc)
s_rc = Chef::JSONCompat.from_json(json)
- s_rc.should be_a_kind_of(Chef::ResourceCollection)
- s_rc[0].name.should eql(resource.name)
+ expect(s_rc).to be_a_kind_of(Chef::ResourceCollection)
+ expect(s_rc[0].name).to eql(resource.name)
end
end
describe "provides access to the raw resources array" do
it "returns the resources via the all_resources method" do
- rc.all_resources.should equal(rc.instance_variable_get(:@resource_list).instance_variable_get(:@resources))
+ expect(rc.all_resources).to equal(rc.instance_variable_get(:@resource_list).instance_variable_get(:@resources))
end
end
describe "provides access to stepable iterator" do
it "returns the iterator object" do
rc.instance_variable_get(:@resource_list).instance_variable_set(:@iterator, :fooboar)
- rc.iterator.should == :fooboar
+ expect(rc.iterator).to eq(:fooboar)
end
end
def check_by_names(results, *names)
names.each do |res_name|
- results.detect{ |res| res.name == res_name }.should_not eql(nil)
+ expect(results.detect{ |res| res.name == res_name }).not_to eql(nil)
end
end
diff --git a/spec/unit/resource_definition_spec.rb b/spec/unit/resource_definition_spec.rb
index 01e28bf091..1371a8b9a6 100644
--- a/spec/unit/resource_definition_spec.rb
+++ b/spec/unit/resource_definition_spec.rb
@@ -85,7 +85,7 @@ describe Chef::ResourceDefinition do
expect(defn.recipe.call).to eql("I am what I am")
end
- it "should set paramaters based on method_missing" do
+ it "should set parameters based on method_missing" do
defn.mind "to fly"
expect(defn.params[:mind]).to eql("to fly")
end
diff --git a/spec/unit/resource_reporter_spec.rb b/spec/unit/resource_reporter_spec.rb
index 1a89cbdce1..4f3a085584 100644
--- a/spec/unit/resource_reporter_spec.rb
+++ b/spec/unit/resource_reporter_spec.rb
@@ -37,13 +37,13 @@ describe Chef::ResourceReporter do
@node = Chef::Node.new
@node.name("spitfire")
@rest_client = double("Chef::REST (mock)")
- @rest_client.stub(:post_rest).and_return(true)
+ allow(@rest_client).to receive(:post_rest).and_return(true)
@resource_reporter = Chef::ResourceReporter.new(@rest_client)
@new_resource = Chef::Resource::File.new("/tmp/a-file.txt")
@cookbook_name = "monkey"
@new_resource.cookbook_name = @cookbook_name
@cookbook_version = double("Cookbook::Version", :version => "1.2.3")
- @new_resource.stub(:cookbook_version).and_return(@cookbook_version)
+ allow(@new_resource).to receive(:cookbook_version).and_return(@cookbook_version)
@current_resource = Chef::Resource::File.new("/tmp/a-file.txt")
@start_time = Time.new
@end_time = Time.new + 20
@@ -51,25 +51,25 @@ describe Chef::ResourceReporter do
@run_context = Chef::RunContext.new(@node, {}, @events)
@run_status = Chef::RunStatus.new(@node, @events)
@run_id = @run_status.run_id
- Time.stub(:now).and_return(@start_time, @end_time)
+ allow(Time).to receive(:now).and_return(@start_time, @end_time)
end
context "when first created" do
it "has no updated resources" do
- @resource_reporter.should have(0).updated_resources
+ expect(@resource_reporter.updated_resources.size).to eq(0)
end
it "reports a successful run" do
- @resource_reporter.status.should == "success"
+ expect(@resource_reporter.status).to eq("success")
end
it "assumes the resource history feature is supported" do
- @resource_reporter.reporting_enabled?.should be_true
+ expect(@resource_reporter.reporting_enabled?).to be_truthy
end
it "should have no error_descriptions" do
- @resource_reporter.error_descriptions.should eq({})
+ expect(@resource_reporter.error_descriptions).to eq({})
# @resource_reporter.error_descriptions.should be_empty
# @resource_reporter.should have(0).error_descriptions
end
@@ -82,16 +82,16 @@ describe Chef::ResourceReporter do
end
it "reports a successful run" do
- pending "refactor how node gets set."
- @resource_reporter.status.should == "success"
+ skip "refactor how node gets set."
+ expect(@resource_reporter.status).to eq("success")
end
end
context "when chef fails" do
before do
- @rest_client.stub(:create_url).and_return("reports/nodes/spitfire/runs/#{@run_id}");
- @rest_client.stub(:raw_http_request).and_return({"result"=>"ok"});
- @rest_client.stub(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/spitfire/runs/#{@run_id}"});
+ allow(@rest_client).to receive(:create_url).and_return("reports/nodes/spitfire/runs/#{@run_id}");
+ allow(@rest_client).to receive(:raw_http_request).and_return({"result"=>"ok"});
+ allow(@rest_client).to receive(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/spitfire/runs/#{@run_id}"});
end
@@ -103,11 +103,11 @@ describe Chef::ResourceReporter do
end
it "sets the run status to 'failure'" do
- @resource_reporter.status.should == "failure"
+ expect(@resource_reporter.status).to eq("failure")
end
it "keeps the exception data" do
- @resource_reporter.exception.should == @exception
+ expect(@resource_reporter.exception).to eq(@exception)
end
end
@@ -121,12 +121,12 @@ describe Chef::ResourceReporter do
end
it "collects the resource as an updated resource" do
- @resource_reporter.should have(1).updated_resources
+ expect(@resource_reporter.updated_resources.size).to eq(1)
end
it "collects the desired state of the resource" do
update_record = @resource_reporter.updated_resources.first
- update_record.new_resource.should == @new_resource
+ expect(update_record.new_resource).to eq(@new_resource)
end
end
@@ -145,7 +145,7 @@ describe Chef::ResourceReporter do
end
it "has no updated resources" do
- @resource_reporter.should have(0).updated_resources
+ expect(@resource_reporter.updated_resources.size).to eq(0)
end
end
@@ -158,17 +158,17 @@ describe Chef::ResourceReporter do
end
it "collects the updated resource" do
- @resource_reporter.should have(1).updated_resources
+ expect(@resource_reporter.updated_resources.size).to eq(1)
end
it "collects the old state of the resource" do
update_record = @resource_reporter.updated_resources.first
- update_record.current_resource.should == @current_resource
+ expect(update_record.current_resource).to eq(@current_resource)
end
it "collects the new state of the resource" do
update_record = @resource_reporter.updated_resources.first
- update_record.new_resource.should == @new_resource
+ expect(update_record.new_resource).to eq(@new_resource)
end
context "and a subsequent resource fails before loading current resource" do
@@ -182,12 +182,12 @@ describe Chef::ResourceReporter do
it "collects the desired state of the failed resource" do
failed_resource_update = @resource_reporter.updated_resources.last
- failed_resource_update.new_resource.should == @next_new_resource
+ expect(failed_resource_update.new_resource).to eq(@next_new_resource)
end
it "does not have the current state of the failed resource" do
failed_resource_update = @resource_reporter.updated_resources.last
- failed_resource_update.current_resource.should be_nil
+ expect(failed_resource_update.current_resource).to be_nil
end
end
end
@@ -208,7 +208,7 @@ describe Chef::ResourceReporter do
end
it "does not collect data about the nested resource" do
- @resource_reporter.should have(1).updated_resources
+ expect(@resource_reporter.updated_resources.size).to eq(1)
end
end
@@ -224,7 +224,7 @@ describe Chef::ResourceReporter do
end
it "does not collect data about the nested resource" do
- @resource_reporter.should have(1).updated_resources
+ expect(@resource_reporter.updated_resources.size).to eq(1)
end
end
@@ -237,17 +237,17 @@ describe Chef::ResourceReporter do
end
it "collects the resource as an updated resource" do
- @resource_reporter.should have(1).updated_resources
+ expect(@resource_reporter.updated_resources.size).to eq(1)
end
it "collects the desired state of the resource" do
update_record = @resource_reporter.updated_resources.first
- update_record.new_resource.should == @new_resource
+ expect(update_record.new_resource).to eq(@new_resource)
end
it "collects the current state of the resource" do
update_record = @resource_reporter.updated_resources.first
- update_record.current_resource.should == @current_resource
+ expect(update_record.current_resource).to eq(@current_resource)
end
end
@@ -257,9 +257,9 @@ describe Chef::ResourceReporter do
describe "when generating a report for the server" do
before do
- @rest_client.stub(:create_url).and_return("reports/nodes/spitfire/runs/#{@run_id}");
- @rest_client.stub(:raw_http_request).and_return({"result"=>"ok"});
- @rest_client.stub(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/spitfire/runs/#{@run_id}"});
+ allow(@rest_client).to receive(:create_url).and_return("reports/nodes/spitfire/runs/#{@run_id}");
+ allow(@rest_client).to receive(:raw_http_request).and_return({"result"=>"ok"});
+ allow(@rest_client).to receive(:post_rest).and_return({"uri"=>"https://example.com/reports/nodes/spitfire/runs/#{@run_id}"});
@resource_reporter.run_started(@run_status)
end
@@ -268,8 +268,8 @@ describe Chef::ResourceReporter do
context "the new_resource name and id are nil" do
before do
@bad_resource = Chef::Resource::File.new("/tmp/nameless_file.txt")
- @bad_resource.stub(:name).and_return(nil)
- @bad_resource.stub(:identity).and_return(nil)
+ allow(@bad_resource).to receive(:name).and_return(nil)
+ allow(@bad_resource).to receive(:identity).and_return(nil)
@resource_reporter.resource_action_start(@bad_resource, :create)
@resource_reporter.resource_current_state_loaded(@bad_resource, :create, @current_resource)
@resource_reporter.resource_updated(@bad_resource, :create)
@@ -280,19 +280,19 @@ describe Chef::ResourceReporter do
end
it "resource_name in prepared_run_data is a string" do
- @first_update_report["name"].class.should == String
+ expect(@first_update_report["name"].class).to eq(String)
end
it "resource_id in prepared_run_data is a string" do
- @first_update_report["id"].class.should == String
+ expect(@first_update_report["id"].class).to eq(String)
end
end
context "the new_resource name and id are hashes" do
before do
@bad_resource = Chef::Resource::File.new("/tmp/filename_as_hash.txt")
- @bad_resource.stub(:name).and_return({:foo=>:bar})
- @bad_resource.stub(:identity).and_return({:foo=>:bar})
+ allow(@bad_resource).to receive(:name).and_return({:foo=>:bar})
+ allow(@bad_resource).to receive(:identity).and_return({:foo=>:bar})
@resource_reporter.resource_action_start(@bad_resource, :create)
@resource_reporter.resource_current_state_loaded(@bad_resource, :create, @current_resource)
@resource_reporter.resource_updated(@bad_resource, :create)
@@ -309,11 +309,11 @@ describe Chef::ResourceReporter do
# => "{:foo=>:bar}"
# Hence checking for the class instead of the actual value.
it "resource_name in prepared_run_data is a string" do
- @first_update_report["name"].class.should == String
+ expect(@first_update_report["name"].class).to eq(String)
end
it "resource_id in prepared_run_data is a string" do
- @first_update_report["id"].class.should == String
+ expect(@first_update_report["id"].class).to eq(String)
end
end
end
@@ -360,73 +360,73 @@ describe Chef::ResourceReporter do
end
it "includes the run's status" do
- @report.should have_key("status")
+ expect(@report).to have_key("status")
end
it "includes a list of updated resources" do
- @report.should have_key("resources")
+ expect(@report).to have_key("resources")
end
it "includes an updated resource's type" do
- @first_update_report.should have_key("type")
+ expect(@first_update_report).to have_key("type")
end
it "includes an updated resource's initial state" do
- @first_update_report["before"].should == current_resource.state
+ expect(@first_update_report["before"]).to eq(current_resource.state)
end
it "includes an updated resource's final state" do
- @first_update_report["after"].should == new_resource.state
+ expect(@first_update_report["after"]).to eq(new_resource.state)
end
it "includes the resource's name" do
- @first_update_report["name"].should == new_resource.name
+ expect(@first_update_report["name"]).to eq(new_resource.name)
end
it "includes the resource's id attribute" do
- @first_update_report["id"].should == new_resource.identity
+ expect(@first_update_report["id"]).to eq(new_resource.identity)
end
it "includes the elapsed time for the resource to converge" do
# TODO: API takes integer number of milliseconds as a string. This
# should be an int.
- @first_update_report.should have_key("duration")
- @first_update_report["duration"].to_i.should be_within(100).of(0)
+ expect(@first_update_report).to have_key("duration")
+ expect(@first_update_report["duration"].to_i).to be_within(100).of(0)
end
it "includes the action executed by the resource" do
# TODO: rename as "action"
- @first_update_report["result"].should == "create"
+ expect(@first_update_report["result"]).to eq("create")
end
it "includes the cookbook name of the resource" do
- @first_update_report.should have_key("cookbook_name")
- @first_update_report["cookbook_name"].should == @cookbook_name
+ expect(@first_update_report).to have_key("cookbook_name")
+ expect(@first_update_report["cookbook_name"]).to eq(@cookbook_name)
end
it "includes the cookbook version of the resource" do
- @first_update_report.should have_key("cookbook_version")
- @first_update_report["cookbook_version"].should == "1.2.3"
+ expect(@first_update_report).to have_key("cookbook_version")
+ expect(@first_update_report["cookbook_version"]).to eq("1.2.3")
end
it "includes the total resource count" do
- @report.should have_key("total_res_count")
- @report["total_res_count"].should == "1"
+ expect(@report).to have_key("total_res_count")
+ expect(@report["total_res_count"]).to eq("1")
end
it "includes the data hash" do
- @report.should have_key("data")
- @report["data"].should == {}
+ expect(@report).to have_key("data")
+ expect(@report["data"]).to eq({})
end
it "includes the run_list" do
- @report.should have_key("run_list")
- @report["run_list"].should == Chef::JSONCompat.to_json(@run_status.node.run_list)
+ expect(@report).to have_key("run_list")
+ expect(@report["run_list"]).to eq(Chef::JSONCompat.to_json(@run_status.node.run_list))
end
it "includes the end_time" do
- @report.should have_key("end_time")
- @report["end_time"].should == @run_status.end_time.to_s
+ expect(@report).to have_key("end_time")
+ expect(@report["end_time"]).to eq(@run_status.end_time.to_s)
end
end
@@ -442,8 +442,8 @@ describe Chef::ResourceReporter do
let(:new_resource) do
resource = Chef::Resource::RegistryKey.new('Wubba\Lubba\Dub\Dubs')
resource.values([ { :name => 'rick', :type => :binary, :data => 255.chr * 1 } ])
- resource.stub(:cookbook_name).and_return(@cookbook_name)
- resource.stub(:cookbook_version).and_return(@cookbook_version)
+ allow(resource).to receive(:cookbook_name).and_return(@cookbook_name)
+ allow(resource).to receive(:cookbook_version).and_return(@cookbook_version)
resource
end
@@ -463,33 +463,33 @@ describe Chef::ResourceReporter do
@node = Chef::Node.new
@node.name("spitfire")
@exception = ArgumentError.new
- @exception.stub(:inspect).and_return("Net::HTTPServerException")
- @exception.stub(:message).and_return("Object not found")
- @exception.stub(:backtrace).and_return(@backtrace)
+ allow(@exception).to receive(:inspect).and_return("Net::HTTPServerException")
+ allow(@exception).to receive(:message).and_return("Object not found")
+ allow(@exception).to receive(:backtrace).and_return(@backtrace)
@resource_reporter.run_list_expand_failed(@node, @exception)
@resource_reporter.run_failed(@exception)
@report = @resource_reporter.prepare_run_data
end
it "includes the exception type in the event data" do
- @report.should have_key("data")
- @report["data"]["exception"].should have_key("class")
- @report["data"]["exception"]["class"].should == "Net::HTTPServerException"
+ expect(@report).to have_key("data")
+ expect(@report["data"]["exception"]).to have_key("class")
+ expect(@report["data"]["exception"]["class"]).to eq("Net::HTTPServerException")
end
it "includes the exception message in the event data" do
- @report["data"]["exception"].should have_key("message")
- @report["data"]["exception"]["message"].should == "Object not found"
+ expect(@report["data"]["exception"]).to have_key("message")
+ expect(@report["data"]["exception"]["message"]).to eq("Object not found")
end
it "includes the exception trace in the event data" do
- @report["data"]["exception"].should have_key("backtrace")
- @report["data"]["exception"]["backtrace"].should == Chef::JSONCompat.to_json(@backtrace)
+ expect(@report["data"]["exception"]).to have_key("backtrace")
+ expect(@report["data"]["exception"]["backtrace"]).to eq(Chef::JSONCompat.to_json(@backtrace))
end
it "includes the error inspector output in the event data" do
- @report["data"]["exception"].should have_key("description")
- @report["data"]["exception"]["description"].should include({"title"=>"Error expanding the run_list:", "sections"=>[{"Unexpected Error:" => "ArgumentError: Object not found"}]})
+ expect(@report["data"]["exception"]).to have_key("description")
+ expect(@report["data"]["exception"]["description"]).to include({"title"=>"Error expanding the run_list:", "sections"=>[{"Unexpected Error:" => "ArgumentError: Object not found"}]})
end
end
@@ -509,39 +509,39 @@ describe Chef::ResourceReporter do
end
it "includes an updated resource's initial state" do
- @first_update_report["before"].should == @current_resource.state
+ expect(@first_update_report["before"]).to eq(@current_resource.state)
end
it "includes an updated resource's final state" do
- @first_update_report["after"].should == @new_resource.state
+ expect(@first_update_report["after"]).to eq(@new_resource.state)
end
it "includes the resource's name" do
- @first_update_report["name"].should == @new_resource.name
+ expect(@first_update_report["name"]).to eq(@new_resource.name)
end
it "includes the resource's id attribute" do
- @first_update_report["id"].should == @new_resource.identity
+ expect(@first_update_report["id"]).to eq(@new_resource.identity)
end
it "includes the elapsed time for the resource to converge" do
# TODO: API takes integer number of milliseconds as a string. This
# should be an int.
- @first_update_report.should have_key("duration")
- @first_update_report["duration"].to_i.should be_within(100).of(0)
+ expect(@first_update_report).to have_key("duration")
+ expect(@first_update_report["duration"].to_i).to be_within(100).of(0)
end
it "includes the action executed by the resource" do
# TODO: rename as "action"
- @first_update_report["result"].should == "create"
+ expect(@first_update_report["result"]).to eq("create")
end
it "does not include a cookbook name for the resource" do
- @first_update_report.should_not have_key("cookbook_name")
+ expect(@first_update_report).not_to have_key("cookbook_name")
end
it "does not include a cookbook version for the resource" do
- @first_update_report.should_not have_key("cookbook_version")
+ expect(@first_update_report).not_to have_key("cookbook_version")
end
end
@@ -562,13 +562,13 @@ describe Chef::ResourceReporter do
end
it "sets before to {} instead of nil" do
- @first_update_report.should have_key("before")
- @first_update_report['before'].should eq({})
+ expect(@first_update_report).to have_key("before")
+ expect(@first_update_report['before']).to eq({})
end
it "sets after to {} instead of 'Running'" do
- @first_update_report.should have_key("after")
- @first_update_report['after'].should eq({})
+ expect(@first_update_report).to have_key("after")
+ expect(@first_update_report['after']).to eq({})
end
end
@@ -585,7 +585,7 @@ describe Chef::ResourceReporter do
# 404 getting the run_id
@response = Net::HTTPNotFound.new("a response body", "404", "Not Found")
@error = Net::HTTPServerException.new("404 message", @response)
- @rest_client.should_receive(:post_rest).
+ expect(@rest_client).to receive(:post_rest).
with("reports/nodes/spitfire/runs", {:action => :start, :run_id => @run_id,
:start_time => @start_time.to_s},
{'X-Ops-Reporting-Protocol-Version' => Chef::ResourceReporter::PROTOCOL_VERSION}).
@@ -594,17 +594,17 @@ describe Chef::ResourceReporter do
it "assumes the feature is not enabled" do
@resource_reporter.run_started(@run_status)
- @resource_reporter.reporting_enabled?.should be_false
+ expect(@resource_reporter.reporting_enabled?).to be_falsey
end
it "does not send a resource report to the server" do
@resource_reporter.run_started(@run_status)
- @rest_client.should_not_receive(:post_rest)
+ expect(@rest_client).not_to receive(:post_rest)
@resource_reporter.run_completed(@node)
end
it "prints an error about the 404" do
- Chef::Log.should_receive(:debug).with(/404/)
+ expect(Chef::Log).to receive(:debug).with(/404/)
@resource_reporter.run_started(@run_status)
end
@@ -615,7 +615,7 @@ describe Chef::ResourceReporter do
# 500 getting the run_id
@response = Net::HTTPInternalServerError.new("a response body", "500", "Internal Server Error")
@error = Net::HTTPServerException.new("500 message", @response)
- @rest_client.should_receive(:post_rest).
+ expect(@rest_client).to receive(:post_rest).
with("reports/nodes/spitfire/runs", {:action => :start, :run_id => @run_id, :start_time => @start_time.to_s},
{'X-Ops-Reporting-Protocol-Version' => Chef::ResourceReporter::PROTOCOL_VERSION}).
and_raise(@error)
@@ -623,17 +623,17 @@ describe Chef::ResourceReporter do
it "assumes the feature is not enabled" do
@resource_reporter.run_started(@run_status)
- @resource_reporter.reporting_enabled?.should be_false
+ expect(@resource_reporter.reporting_enabled?).to be_falsey
end
it "does not send a resource report to the server" do
@resource_reporter.run_started(@run_status)
- @rest_client.should_not_receive(:post_rest)
+ expect(@rest_client).not_to receive(:post_rest)
@resource_reporter.run_completed(@node)
end
it "prints an error about the error" do
- Chef::Log.should_receive(:info).with(/500/)
+ expect(Chef::Log).to receive(:info).with(/500/)
@resource_reporter.run_started(@run_status)
end
end
@@ -645,7 +645,7 @@ describe Chef::ResourceReporter do
# 500 getting the run_id
@response = Net::HTTPInternalServerError.new("a response body", "500", "Internal Server Error")
@error = Net::HTTPServerException.new("500 message", @response)
- @rest_client.should_receive(:post_rest).
+ expect(@rest_client).to receive(:post_rest).
with("reports/nodes/spitfire/runs", {:action => :start, :run_id => @run_id, :start_time => @start_time.to_s},
{'X-Ops-Reporting-Protocol-Version' => Chef::ResourceReporter::PROTOCOL_VERSION}).
and_raise(@error)
@@ -656,17 +656,17 @@ describe Chef::ResourceReporter do
end
it "fails the run and prints an message about the error" do
- Chef::Log.should_receive(:error).with(/500/)
- lambda {
+ expect(Chef::Log).to receive(:error).with(/500/)
+ expect {
@resource_reporter.run_started(@run_status)
- }.should raise_error(Net::HTTPServerException)
+ }.to raise_error(Net::HTTPServerException)
end
end
context "after creating the run history document" do
before do
response = {"uri"=>"https://example.com/reports/nodes/spitfire/runs/@run_id"}
- @rest_client.should_receive(:post_rest).
+ expect(@rest_client).to receive(:post_rest).
with("reports/nodes/spitfire/runs", {:action => :start, :run_id => @run_id, :start_time => @start_time.to_s},
{'X-Ops-Reporting-Protocol-Version' => Chef::ResourceReporter::PROTOCOL_VERSION}).
and_return(response)
@@ -674,7 +674,7 @@ describe Chef::ResourceReporter do
end
it "creates a run document on the server at the start of the run" do
- @resource_reporter.run_id.should == @run_id
+ expect(@resource_reporter.run_id).to eq(@run_id)
end
it "updates the run document with resource updates at the end of the run" do
@@ -683,25 +683,25 @@ describe Chef::ResourceReporter do
@resource_reporter.resource_current_state_loaded(@new_resource, :create, @current_resource)
@resource_reporter.resource_updated(@new_resource, :create)
- @resource_reporter.stub(:end_time).and_return(@end_time)
+ allow(@resource_reporter).to receive(:end_time).and_return(@end_time)
@expected_data = @resource_reporter.prepare_run_data
post_url = "https://chef_server/example_url"
response = {"result"=>"ok"}
- @rest_client.should_receive(:create_url).
+ expect(@rest_client).to receive(:create_url).
with("reports/nodes/spitfire/runs/#{@run_id}").
ordered.
and_return(post_url)
- @rest_client.should_receive(:raw_http_request).ordered do |method, url, headers, data|
- method.should eq(:POST)
- url.should eq(post_url)
- headers.should eq({'Content-Encoding' => 'gzip',
+ expect(@rest_client).to receive(:raw_http_request).ordered do |method, url, headers, data|
+ expect(method).to eq(:POST)
+ expect(url).to eq(post_url)
+ expect(headers).to eq({'Content-Encoding' => 'gzip',
'X-Ops-Reporting-Protocol-Version' => Chef::ResourceReporter::PROTOCOL_VERSION
})
data_stream = Zlib::GzipReader.new(StringIO.new(data))
data = data_stream.read
- data.should eq(Chef::JSONCompat.to_json(@expected_data))
+ expect(data).to eq(Chef::JSONCompat.to_json(@expected_data))
response
end
@@ -714,7 +714,7 @@ describe Chef::ResourceReporter do
@enable_reporting_url_fatals = Chef::Config[:enable_reporting_url_fatals]
Chef::Config[:enable_reporting_url_fatals] = true
# this call doesn't matter for this context
- @rest_client.stub(:create_url)
+ allow(@rest_client).to receive(:create_url)
end
after do
@@ -724,8 +724,8 @@ describe Chef::ResourceReporter do
it "should log 4xx errors" do
response = Net::HTTPClientError.new("forbidden", "403", "Forbidden")
error = Net::HTTPServerException.new("403 message", response)
- @rest_client.stub(:raw_http_request).and_raise(error)
- Chef::Log.should_receive(:error).with(/403/)
+ allow(@rest_client).to receive(:raw_http_request).and_raise(error)
+ expect(Chef::Log).to receive(:error).with(/403/)
@resource_reporter.post_reporting_data
end
@@ -733,26 +733,26 @@ describe Chef::ResourceReporter do
it "should log error 5xx errors" do
response = Net::HTTPServerError.new("internal error", "500", "Internal Server Error")
error = Net::HTTPFatalError.new("500 message", response)
- @rest_client.stub(:raw_http_request).and_raise(error)
- Chef::Log.should_receive(:error).with(/500/)
+ allow(@rest_client).to receive(:raw_http_request).and_raise(error)
+ expect(Chef::Log).to receive(:error).with(/500/)
@resource_reporter.post_reporting_data
end
it "should log if a socket error happens" do
- @rest_client.stub(:raw_http_request).and_raise(SocketError.new("test socket error"))
- Chef::Log.should_receive(:error).with(/test socket error/)
+ allow(@rest_client).to receive(:raw_http_request).and_raise(SocketError.new("test socket error"))
+ expect(Chef::Log).to receive(:error).with(/test socket error/)
@resource_reporter.post_reporting_data
end
it "should raise if an unkwown error happens" do
- @rest_client.stub(:raw_http_request).and_raise(Exception.new)
+ allow(@rest_client).to receive(:raw_http_request).and_raise(Exception.new)
- lambda {
+ expect {
@resource_reporter.post_reporting_data
- }.should raise_error(Exception)
+ }.to raise_error(Exception)
end
end
end
diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb
index 1a4ee6b0fe..8214021f65 100644
--- a/spec/unit/resource_spec.rb
+++ b/spec/unit/resource_spec.rb
@@ -39,33 +39,33 @@ describe Chef::Resource do
it "adds an entry to a list of subclasses" do
subclass = Class.new(Chef::Resource)
- Chef::Resource.resource_classes.should include(subclass)
+ expect(Chef::Resource.resource_classes).to include(subclass)
end
it "keeps track of subclasses of subclasses" do
subclass = Class.new(Chef::Resource)
subclass_of_subclass = Class.new(subclass)
- Chef::Resource.resource_classes.should include(subclass_of_subclass)
+ expect(Chef::Resource.resource_classes).to include(subclass_of_subclass)
end
end
describe "when declaring the identity attribute" do
it "has no identity attribute by default" do
- Chef::Resource.identity_attr.should be_nil
+ expect(Chef::Resource.identity_attr).to be_nil
end
it "sets an identity attribute" do
resource_class = Class.new(Chef::Resource)
resource_class.identity_attr(:path)
- resource_class.identity_attr.should == :path
+ expect(resource_class.identity_attr).to eq(:path)
end
it "inherits an identity attribute from a superclass" do
resource_class = Class.new(Chef::Resource)
resource_subclass = Class.new(resource_class)
resource_class.identity_attr(:package_name)
- resource_subclass.identity_attr.should == :package_name
+ expect(resource_subclass.identity_attr).to eq(:package_name)
end
it "overrides the identity attribute from a superclass when the identity attr is set" do
@@ -73,7 +73,7 @@ describe Chef::Resource do
resource_subclass = Class.new(resource_class)
resource_class.identity_attr(:package_name)
resource_subclass.identity_attr(:something_else)
- resource_subclass.identity_attr.should == :something_else
+ expect(resource_subclass.identity_attr).to eq(:something_else)
end
end
@@ -85,7 +85,7 @@ describe Chef::Resource do
# Would rather force identity attributes to be set for everything,
# but that's not plausible for back compat reasons.
it "uses the name as the identity" do
- @resource_sans_id.identity.should == "my-name"
+ expect(@resource_sans_id.identity).to eq("my-name")
end
end
@@ -101,26 +101,26 @@ describe Chef::Resource do
end
it "gives the value of its identity attribute" do
- @file_resource.identity.should == "/tmp/foo.txt"
+ expect(@file_resource.identity).to eq("/tmp/foo.txt")
end
end
describe "when declaring state attributes" do
it "has no state_attrs by default" do
- Chef::Resource.state_attrs.should be_empty
+ expect(Chef::Resource.state_attrs).to be_empty
end
it "sets a list of state attributes" do
resource_class = Class.new(Chef::Resource)
resource_class.state_attrs(:checksum, :owner, :group, :mode)
- resource_class.state_attrs.should =~ [:checksum, :owner, :group, :mode]
+ expect(resource_class.state_attrs).to match_array([:checksum, :owner, :group, :mode])
end
it "inherits state attributes from the superclass" do
resource_class = Class.new(Chef::Resource)
resource_subclass = Class.new(resource_class)
resource_class.state_attrs(:checksum, :owner, :group, :mode)
- resource_subclass.state_attrs.should =~ [:checksum, :owner, :group, :mode]
+ expect(resource_subclass.state_attrs).to match_array([:checksum, :owner, :group, :mode])
end
it "combines inherited state attributes with non-inherited state attributes" do
@@ -128,7 +128,7 @@ describe Chef::Resource do
resource_subclass = Class.new(resource_class)
resource_class.state_attrs(:checksum, :owner)
resource_subclass.state_attrs(:group, :mode)
- resource_subclass.state_attrs.should =~ [:checksum, :owner, :group, :mode]
+ expect(resource_subclass.state_attrs).to match_array([:checksum, :owner, :group, :mode])
end
end
@@ -154,15 +154,15 @@ describe Chef::Resource do
it "describes its state" do
resource_state = @file_resource.state
- resource_state.keys.should =~ [:checksum, :owner, :group, :mode]
- resource_state[:checksum].should == "abc123"
- resource_state[:owner].should == "root"
- resource_state[:group].should == "wheel"
- resource_state[:mode].should == "0644"
+ expect(resource_state.keys).to match_array([:checksum, :owner, :group, :mode])
+ expect(resource_state[:checksum]).to eq("abc123")
+ expect(resource_state[:owner]).to eq("root")
+ expect(resource_state[:group]).to eq("wheel")
+ expect(resource_state[:mode]).to eq("0644")
end
end
- describe "load_prior_resource" do
+ describe "load_from" do
before(:each) do
@prior_resource = Chef::Resource.new("funk")
@prior_resource.supports(:funky => true)
@@ -174,40 +174,40 @@ describe Chef::Resource do
end
it "should load the attributes of a prior resource" do
- @resource.load_prior_resource(@resource.resource_name, @resource.name)
- @resource.supports.should == { :funky => true }
+ @resource.load_from(@prior_resource)
+ expect(@resource.supports).to eq({ :funky => true })
end
it "should not inherit the action from the prior resource" do
- @resource.load_prior_resource(@resource.resource_name, @resource.name)
- @resource.action.should_not == @prior_resource.action
+ @resource.load_from(@prior_resource)
+ expect(@resource.action).not_to eq(@prior_resource.action)
end
end
describe "name" do
it "should have a name" do
- @resource.name.should eql("funk")
+ expect(@resource.name).to eql("funk")
end
it "should let you set a new name" do
@resource.name "monkey"
- @resource.name.should eql("monkey")
+ expect(@resource.name).to eql("monkey")
end
- it "should not be valid without a name" do
- lambda { @resource.name false }.should raise_error(ArgumentError)
+ it "coerces arrays to names" do
+ expect(@resource.name ['a', 'b']).to eql('a, b')
end
- it "should always have a string for name" do
- lambda { @resource.name Hash.new }.should raise_error(ArgumentError)
+ it "should coerce objects to a string" do
+ expect(@resource.name Object.new).to be_a(String)
end
end
describe "noop" do
it "should accept true or false for noop" do
- lambda { @resource.noop true }.should_not raise_error
- lambda { @resource.noop false }.should_not raise_error
- lambda { @resource.noop "eat it" }.should raise_error(ArgumentError)
+ expect { @resource.noop true }.not_to raise_error
+ expect { @resource.noop false }.not_to raise_error
+ expect { @resource.noop "eat it" }.to raise_error(ArgumentError)
end
end
@@ -215,48 +215,54 @@ describe Chef::Resource do
it "should make notified resources appear in the actions hash" do
@run_context.resource_collection << Chef::Resource::ZenMaster.new("coffee")
@resource.notifies :reload, @run_context.resource_collection.find(:zen_master => "coffee")
- @resource.delayed_notifications.detect{|e| e.resource.name == "coffee" && e.action == :reload}.should_not be_nil
+ expect(@resource.delayed_notifications.detect{|e| e.resource.name == "coffee" && e.action == :reload}).not_to be_nil
end
it "should make notified resources be capable of acting immediately" do
@run_context.resource_collection << Chef::Resource::ZenMaster.new("coffee")
@resource.notifies :reload, @run_context.resource_collection.find(:zen_master => "coffee"), :immediate
- @resource.immediate_notifications.detect{|e| e.resource.name == "coffee" && e.action == :reload}.should_not be_nil
+ expect(@resource.immediate_notifications.detect{|e| e.resource.name == "coffee" && e.action == :reload}).not_to be_nil
end
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")
- lambda {
+ expect {
@resource.notifies :reload, @run_context.resource_collection.find(:zen_master => "coffee"), :someday
- }.should raise_error(ArgumentError)
+ }.to raise_error(ArgumentError)
end
it "should allow multiple notified resources appear in the actions hash" do
@run_context.resource_collection << Chef::Resource::ZenMaster.new("coffee")
@resource.notifies :reload, @run_context.resource_collection.find(:zen_master => "coffee")
- @resource.delayed_notifications.detect{|e| e.resource.name == "coffee" && e.action == :reload}.should_not be_nil
+ expect(@resource.delayed_notifications.detect{|e| e.resource.name == "coffee" && e.action == :reload}).not_to be_nil
@run_context.resource_collection << Chef::Resource::ZenMaster.new("beans")
@resource.notifies :reload, @run_context.resource_collection.find(:zen_master => "beans")
- @resource.delayed_notifications.detect{|e| e.resource.name == "beans" && e.action == :reload}.should_not be_nil
+ expect(@resource.delayed_notifications.detect{|e| e.resource.name == "beans" && e.action == :reload}).not_to be_nil
end
it "creates a notification for a resource that is not yet in the resource collection" do
@resource.notifies(:restart, :service => 'apache')
expected_notification = Chef::Resource::Notification.new({:service => "apache"}, :restart, @resource)
- @resource.delayed_notifications.should include(expected_notification)
+ expect(@resource.delayed_notifications).to include(expected_notification)
end
it "notifies another resource immediately" do
@resource.notifies_immediately(:restart, :service => 'apache')
expected_notification = Chef::Resource::Notification.new({:service => "apache"}, :restart, @resource)
- @resource.immediate_notifications.should include(expected_notification)
+ expect(@resource.immediate_notifications).to include(expected_notification)
end
it "notifies a resource to take action at the end of the chef run" do
@resource.notifies_delayed(:restart, :service => "apache")
expected_notification = Chef::Resource::Notification.new({:service => "apache"}, :restart, @resource)
- @resource.delayed_notifications.should include(expected_notification)
+ expect(@resource.delayed_notifications).to include(expected_notification)
+ end
+
+ it "notifies a resource with an array for its name via its prettified string name" do
+ @run_context.resource_collection << Chef::Resource::ZenMaster.new(["coffee", "tea"])
+ @resource.notifies :reload, @run_context.resource_collection.find(:zen_master => "coffee, tea")
+ expect(@resource.delayed_notifications.detect{|e| e.resource.name == "coffee, tea" && e.action == :reload}).not_to be_nil
end
end
@@ -265,76 +271,76 @@ describe Chef::Resource do
@run_context.resource_collection << Chef::Resource::ZenMaster.new("coffee")
zr = @run_context.resource_collection.find(:zen_master => "coffee")
@resource.subscribes :reload, zr
- zr.delayed_notifications.detect{|e| e.resource.name == "funk" && e.action == :reload}.should_not be_nil
+ expect(zr.delayed_notifications.detect{|e| e.resource.name == "funk" && e.action == :reload}).not_to be_nil
end
it "should make resources appear in the actions hash of subscribed nodes" do
@run_context.resource_collection << Chef::Resource::ZenMaster.new("coffee")
zr = @run_context.resource_collection.find(:zen_master => "coffee")
@resource.subscribes :reload, zr
- zr.delayed_notifications.detect{|e| e.resource.name == @resource.name && e.action == :reload}.should_not be_nil
+ expect(zr.delayed_notifications.detect{|e| e.resource.name == @resource.name && e.action == :reload}).not_to be_nil
@run_context.resource_collection << Chef::Resource::ZenMaster.new("bean")
zrb = @run_context.resource_collection.find(:zen_master => "bean")
zrb.subscribes :reload, zr
- zr.delayed_notifications.detect{|e| e.resource.name == @resource.name && e.action == :reload}.should_not be_nil
+ expect(zr.delayed_notifications.detect{|e| e.resource.name == @resource.name && e.action == :reload}).not_to be_nil
end
it "should make subscribed resources be capable of acting immediately" do
@run_context.resource_collection << Chef::Resource::ZenMaster.new("coffee")
zr = @run_context.resource_collection.find(:zen_master => "coffee")
@resource.subscribes :reload, zr, :immediately
- zr.immediate_notifications.detect{|e| e.resource.name == @resource.name && e.action == :reload}.should_not be_nil
+ expect(zr.immediate_notifications.detect{|e| e.resource.name == @resource.name && e.action == :reload}).not_to be_nil
end
end
describe "defined_at" do
it "should correctly parse source_line on unix-like operating systems" do
@resource.source_line = "/some/path/to/file.rb:80:in `wombat_tears'"
- @resource.defined_at.should == "/some/path/to/file.rb line 80"
+ expect(@resource.defined_at).to eq("/some/path/to/file.rb line 80")
end
it "should correctly parse source_line on Windows" do
@resource.source_line = "C:/some/path/to/file.rb:80 in 1`wombat_tears'"
- @resource.defined_at.should == "C:/some/path/to/file.rb line 80"
+ expect(@resource.defined_at).to eq("C:/some/path/to/file.rb line 80")
end
it "should include the cookbook and recipe when it knows it" do
@resource.source_line = "/some/path/to/file.rb:80:in `wombat_tears'"
@resource.recipe_name = "wombats"
@resource.cookbook_name = "animals"
- @resource.defined_at.should == "animals::wombats line 80"
+ expect(@resource.defined_at).to eq("animals::wombats line 80")
end
it "should recognize dynamically defined resources" do
- @resource.defined_at.should == "dynamically defined"
+ expect(@resource.defined_at).to eq("dynamically defined")
end
end
describe "to_s" do
it "should become a string like resource_name[name]" do
zm = Chef::Resource::ZenMaster.new("coffee")
- zm.to_s.should eql("zen_master[coffee]")
+ expect(zm.to_s).to eql("zen_master[coffee]")
end
end
describe "is" do
it "should return the arguments passed with 'is'" do
zm = Chef::Resource::ZenMaster.new("coffee")
- zm.is("one", "two", "three").should == %w|one two three|
+ expect(zm.is("one", "two", "three")).to eq(%w|one two three|)
end
- it "should allow arguments preceeded by is to methods" do
+ it "should allow arguments preceded by is to methods" do
@resource.noop(@resource.is(true))
- @resource.noop.should eql(true)
+ expect(@resource.noop).to eql(true)
end
end
describe "to_json" do
it "should serialize to json" do
json = @resource.to_json
- json.should =~ /json_class/
- json.should =~ /instance_vars/
+ expect(json).to match(/json_class/)
+ expect(json).to match(/instance_vars/)
end
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
@@ -350,9 +356,9 @@ describe Chef::Resource do
:noop, :ignore_failure, :name, :source_line,
:action, :retries, :retry_delay, :elapsed_time,
:default_guard_interpreter, :guard_interpreter, :sensitive ]
- (hash.keys - expected_keys).should == []
- (expected_keys - hash.keys).should == []
- hash[:name].should eql("funk")
+ expect(hash.keys - expected_keys).to eq([])
+ expect(expected_keys - hash.keys).to eq([])
+ expect(hash[:name]).to eql("funk")
end
end
@@ -360,8 +366,8 @@ describe Chef::Resource do
it "should deserialize itself from json" do
json = Chef::JSONCompat.to_json(@resource)
serialized_node = Chef::JSONCompat.from_json(json)
- serialized_node.should be_a_kind_of(Chef::Resource)
- serialized_node.name.should eql(@resource.name)
+ expect(serialized_node).to be_a_kind_of(Chef::Resource)
+ expect(serialized_node.name).to eql(@resource.name)
end
end
@@ -369,27 +375,27 @@ describe Chef::Resource do
it "should allow you to set what features this resource supports" do
support_hash = { :one => :two }
@resource.supports(support_hash)
- @resource.supports.should eql(support_hash)
+ expect(@resource.supports).to eql(support_hash)
end
it "should return the current value of supports" do
- @resource.supports.should == {}
+ expect(@resource.supports).to eq({})
end
end
describe "ignore_failure" do
it "should default to throwing an error if a provider fails for a resource" do
- @resource.ignore_failure.should == false
+ expect(@resource.ignore_failure).to eq(false)
end
it "should allow you to set whether a provider should throw exceptions with ignore_failure" do
@resource.ignore_failure(true)
- @resource.ignore_failure.should == true
+ expect(@resource.ignore_failure).to eq(true)
end
it "should allow you to epic_fail" do
@resource.epic_fail(true)
- @resource.epic_fail.should == true
+ expect(@resource.epic_fail).to eq(true)
end
end
@@ -404,21 +410,21 @@ describe Chef::Resource do
end
it "should default to not retrying if a provider fails for a resource" do
- @retriable_resource.retries.should == 0
+ expect(@retriable_resource.retries).to eq(0)
end
it "should allow you to set how many retries a provider should attempt after a failure" do
@retriable_resource.retries(2)
- @retriable_resource.retries.should == 2
+ expect(@retriable_resource.retries).to eq(2)
end
it "should default to a retry delay of 2 seconds" do
- @retriable_resource.retry_delay.should == 2
+ expect(@retriable_resource.retry_delay).to eq(2)
end
it "should allow you to set the retry delay" do
@retriable_resource.retry_delay(10)
- @retriable_resource.retry_delay.should == 10
+ expect(@retriable_resource.retry_delay).to eq(10)
end
it "should keep given value of retries intact after the provider fails for a resource" do
@@ -426,29 +432,29 @@ describe Chef::Resource do
@retriable_resource.retry_delay(0) # No need to wait.
provider = Chef::Provider::SnakeOil.new(@retriable_resource, @run_context)
- Chef::Provider::SnakeOil.stub(:new).and_return(provider)
- provider.stub(:action_purr).and_raise
+ allow(Chef::Provider::SnakeOil).to receive(:new).and_return(provider)
+ allow(provider).to receive(:action_purr).and_raise
- @retriable_resource.should_receive(:sleep).exactly(3).times
+ expect(@retriable_resource).to receive(:sleep).exactly(3).times
expect { @retriable_resource.run_action(:purr) }.to raise_error
- @retriable_resource.retries.should == 3
+ expect(@retriable_resource.retries).to eq(3)
end
end
describe "setting the base provider class for the resource" do
it "defaults to Chef::Provider for the base class" do
- Chef::Resource.provider_base.should == Chef::Provider
+ expect(Chef::Resource.provider_base).to eq(Chef::Provider)
end
it "allows the base provider to be overriden by a " do
- ResourceTestHarness.provider_base.should == Chef::Provider::Package
+ expect(ResourceTestHarness.provider_base).to eq(Chef::Provider::Package)
end
end
it "runs an action by finding its provider, loading the current resource and then running the action" do
- pending
+ skip
end
describe "when updated by a provider" do
@@ -457,11 +463,11 @@ describe Chef::Resource do
end
it "records that it was updated" do
- @resource.should be_updated
+ expect(@resource).to be_updated
end
it "records that the last action updated the resource" do
- @resource.should be_updated_by_last_action
+ expect(@resource).to be_updated_by_last_action
end
describe "and then run again without being updated" do
@@ -470,11 +476,11 @@ describe Chef::Resource do
end
it "reports that it is updated" do
- @resource.should be_updated
+ expect(@resource).to be_updated
end
it "reports that it was not updated by the last action" do
- @resource.should_not be_updated_by_last_action
+ expect(@resource).not_to be_updated_by_last_action
end
end
@@ -498,10 +504,10 @@ describe Chef::Resource do
it "runs runs an only_if when one is given" do
snitch_variable = nil
@resource.only_if { snitch_variable = true }
- @resource.only_if.first.positivity.should == :only_if
+ expect(@resource.only_if.first.positivity).to eq(:only_if)
#Chef::Mixin::Command.should_receive(:only_if).with(true, {}).and_return(false)
@resource.run_action(:purr)
- snitch_variable.should be_true
+ expect(snitch_variable).to be_truthy
end
it "runs multiple only_if conditionals" do
@@ -509,25 +515,25 @@ describe Chef::Resource do
@resource.only_if { snitch_var1 = 1 }
@resource.only_if { snitch_var2 = 2 }
@resource.run_action(:purr)
- snitch_var1.should == 1
- snitch_var2.should == 2
+ expect(snitch_var1).to eq(1)
+ expect(snitch_var2).to eq(2)
end
it "accepts command options for only_if conditionals" do
- Chef::Resource::Conditional.any_instance.should_receive(:evaluate_command).at_least(1).times
+ expect_any_instance_of(Chef::Resource::Conditional).to receive(:evaluate_command).at_least(1).times
@resource.only_if("true", :cwd => '/tmp')
- @resource.only_if.first.command_opts.should == {:cwd => '/tmp'}
+ expect(@resource.only_if.first.command_opts).to eq({:cwd => '/tmp'})
@resource.run_action(:purr)
end
it "runs not_if as a command when it is a string" do
- Chef::Resource::Conditional.any_instance.should_receive(:evaluate_command).at_least(1).times
+ expect_any_instance_of(Chef::Resource::Conditional).to receive(:evaluate_command).at_least(1).times
@resource.not_if "pwd"
@resource.run_action(:purr)
end
it "runs not_if as a block when it is a ruby block" do
- Chef::Resource::Conditional.any_instance.should_receive(:evaluate_block).at_least(1).times
+ expect_any_instance_of(Chef::Resource::Conditional).to receive(:evaluate_block).at_least(1).times
@resource.not_if { puts 'foo' }
@resource.run_action(:purr)
end
@@ -540,7 +546,7 @@ describe Chef::Resource do
it "accepts command options for not_if conditionals" do
@resource.not_if("pwd" , :cwd => '/tmp')
- @resource.not_if.first.command_opts.should == {:cwd => '/tmp'}
+ expect(@resource.not_if.first.command_opts).to eq({:cwd => '/tmp'})
end
it "accepts multiple not_if conditionals" do
@@ -548,27 +554,27 @@ describe Chef::Resource do
@resource.not_if {snitch_var1 = nil}
@resource.not_if {snitch_var2 = false}
@resource.run_action(:purr)
- snitch_var1.should be_nil
- snitch_var2.should be_false
+ expect(snitch_var1).to be_nil
+ expect(snitch_var2).to be_falsey
end
it "reports 0 elapsed time if actual elapsed time is < 0" do
expected = Time.now
- Time.stub(:now).and_return(expected, expected - 1)
+ allow(Time).to receive(:now).and_return(expected, expected - 1)
@resource.run_action(:purr)
- @resource.elapsed_time.should == 0
+ expect(@resource.elapsed_time).to eq(0)
end
describe "guard_interpreter attribute" do
let(:resource) { @resource }
it "should be set to :default by default" do
- resource.guard_interpreter.should == :default
+ expect(resource.guard_interpreter).to eq(:default)
end
it "if set to :default should return :default when read" do
resource.guard_interpreter(:default)
- resource.guard_interpreter.should == :default
+ expect(resource.guard_interpreter).to eq(:default)
end
it "should raise Chef::Exceptions::ValidationFailed on an attempt to set the guard_interpreter attribute to something other than a Symbol" do
@@ -576,7 +582,7 @@ describe Chef::Resource do
end
it "should not raise an exception when setting the guard interpreter attribute to a Symbol" do
- Chef::GuardInterpreter::ResourceGuardInterpreter.stub(:new).and_return(nil)
+ allow(Chef::GuardInterpreter::ResourceGuardInterpreter).to receive(:new).and_return(nil)
expect { resource.guard_interpreter(:command_dot_com) }.not_to raise_error
end
end
@@ -588,63 +594,63 @@ describe Chef::Resource do
end
it "should return false by default" do
- @resource.should_skip?(:purr).should be_false
+ expect(@resource.should_skip?(:purr)).to be_falsey
end
it "should return false when only_if is met" do
@resource.only_if { true }
- @resource.should_skip?(:purr).should be_false
+ expect(@resource.should_skip?(:purr)).to be_falsey
end
it "should return true when only_if is not met" do
@resource.only_if { false }
- @resource.should_skip?(:purr).should be_true
+ expect(@resource.should_skip?(:purr)).to be_truthy
end
it "should return true when not_if is met" do
@resource.not_if { true }
- @resource.should_skip?(:purr).should be_true
+ expect(@resource.should_skip?(:purr)).to be_truthy
end
it "should return false when not_if is not met" do
@resource.not_if { false }
- @resource.should_skip?(:purr).should be_false
+ expect(@resource.should_skip?(:purr)).to be_falsey
end
it "should return true when only_if is met but also not_if is met" do
@resource.only_if { true }
@resource.not_if { true }
- @resource.should_skip?(:purr).should be_true
+ expect(@resource.should_skip?(:purr)).to be_truthy
end
it "should return true when one of multiple only_if's is not met" do
@resource.only_if { true }
@resource.only_if { false }
@resource.only_if { true }
- @resource.should_skip?(:purr).should be_true
+ expect(@resource.should_skip?(:purr)).to be_truthy
end
it "should return true when one of multiple not_if's is met" do
@resource.not_if { false }
@resource.not_if { true }
@resource.not_if { false }
- @resource.should_skip?(:purr).should be_true
+ expect(@resource.should_skip?(:purr)).to be_truthy
end
it "should return true when action is :nothing" do
- @resource.should_skip?(:nothing).should be_true
+ expect(@resource.should_skip?(:nothing)).to be_truthy
end
it "should return true when action is :nothing ignoring only_if/not_if conditionals" do
@resource.only_if { true }
@resource.not_if { false }
- @resource.should_skip?(:nothing).should be_true
+ expect(@resource.should_skip?(:nothing)).to be_truthy
end
it "should print \"skipped due to action :nothing\" message for doc formatter when action is :nothing" do
fdoc = Chef::Formatters.new(:doc, STDOUT, STDERR)
- @run_context.stub(:events).and_return(fdoc)
- fdoc.should_receive(:puts).with(" (skipped due to action :nothing)", anything())
+ allow(@run_context).to receive(:events).and_return(fdoc)
+ expect(fdoc).to receive(:puts).with(" (skipped due to action :nothing)", anything())
@resource.should_skip?(:nothing)
end
@@ -664,7 +670,7 @@ describe Chef::Resource do
@resource1.only_if { snitch_var1 = 1 }
@resource1.not_if { snitch_var1 = 2 }
@resource1.run_action(:nothing)
- snitch_var1.should == 0
+ expect(snitch_var1).to eq(0)
end
it "should run only_if/not_if conditionals when notified to run another action (CHEF-972)" do
@@ -685,8 +691,8 @@ describe Chef::Resource do
@run_context.resource_collection << @resource2
@runner.converge
- snitch_var1.should == 1
- snitch_var2.should == 2
+ expect(snitch_var1).to eq(1)
+ expect(snitch_var2).to eq(2)
end
end
@@ -750,10 +756,10 @@ describe Chef::Resource do
describe "resource_for_node" do
it "returns a resource by short_name and node" do
- Chef::Resource.resource_for_node(:dinobot, @node).should eql(Grimlock)
+ expect(Chef::Resource.resource_for_node(:dinobot, @node)).to eql(Grimlock)
end
it "returns a resource by short_name if nothing else matches" do
- Chef::Resource.resource_for_node(:soundwave, @node).should eql(Soundwave)
+ expect(Chef::Resource.resource_for_node(:soundwave, @node)).to eql(Soundwave)
end
end
@@ -765,30 +771,30 @@ describe Chef::Resource do
it "creates a delayed notification when timing is not specified" do
@resource.notifies(:run, "execute[foo]")
- @run_context.delayed_notification_collection.should have(1).notifications
+ expect(@run_context.delayed_notification_collection.size).to eq(1)
end
it "creates a delayed notification when :delayed is not specified" do
@resource.notifies(:run, "execute[foo]", :delayed)
- @run_context.delayed_notification_collection.should have(1).notifications
+ expect(@run_context.delayed_notification_collection.size).to eq(1)
end
it "creates an immediate notification when :immediate is specified" do
@resource.notifies(:run, "execute[foo]", :immediate)
- @run_context.immediate_notification_collection.should have(1).notifications
+ expect(@run_context.immediate_notification_collection.size).to eq(1)
end
it "creates an immediate notification when :immediately is specified" do
@resource.notifies(:run, "execute[foo]", :immediately)
- @run_context.immediate_notification_collection.should have(1).notifications
+ expect(@run_context.immediate_notification_collection.size).to eq(1)
end
describe "with a syntax error in the resource spec" do
it "raises an exception immmediately" do
- lambda do
+ expect do
@resource.notifies(:run, "typo[missing-closing-bracket")
- end.should raise_error(Chef::Exceptions::InvalidResourceSpecification)
+ end.to raise_error(Chef::Exceptions::InvalidResourceSpecification)
end
end
end
@@ -800,22 +806,22 @@ describe Chef::Resource do
it "creates a delayed notification when timing is not specified" do
@resource.notifies(:run, @notified_resource)
- @run_context.delayed_notification_collection.should have(1).notifications
+ expect(@run_context.delayed_notification_collection.size).to eq(1)
end
it "creates a delayed notification when :delayed is not specified" do
@resource.notifies(:run, @notified_resource, :delayed)
- @run_context.delayed_notification_collection.should have(1).notifications
+ expect(@run_context.delayed_notification_collection.size).to eq(1)
end
it "creates an immediate notification when :immediate is specified" do
@resource.notifies(:run, @notified_resource, :immediate)
- @run_context.immediate_notification_collection.should have(1).notifications
+ expect(@run_context.immediate_notification_collection.size).to eq(1)
end
it "creates an immediate notification when :immediately is specified" do
@resource.notifies(:run, @notified_resource, :immediately)
- @run_context.immediate_notification_collection.should have(1).notifications
+ expect(@run_context.immediate_notification_collection.size).to eq(1)
end
end
@@ -837,19 +843,19 @@ describe Chef::Resource do
end
it "set to false by default" do
- @resource.sensitive.should be_false
+ expect(@resource.sensitive).to be_falsey
end
it "when set to false should show compiled resource for failed resource" do
expect { @resource_file.run_action(@action) }.to raise_error { |err|
- compiled_resource_data(@resource_file, @action, err).should match 'path "/nonexistent/CHEF-5098/file"'
+ expect(compiled_resource_data(@resource_file, @action, err)).to match 'path "/nonexistent/CHEF-5098/file"'
}
end
it "when set to true should show compiled resource for failed resource" do
@resource_file.sensitive true
expect { @resource_file.run_action(@action) }.to raise_error { |err|
- compiled_resource_data(@resource_file, @action, err).should eql("suppressed sensitive resource output")
+ expect(compiled_resource_data(@resource_file, @action, err)).to eql("suppressed sensitive resource output")
}
end
diff --git a/spec/unit/rest/auth_credentials_spec.rb b/spec/unit/rest/auth_credentials_spec.rb
index 477da0faec..3465156b90 100644
--- a/spec/unit/rest/auth_credentials_spec.rb
+++ b/spec/unit/rest/auth_credentials_spec.rb
@@ -62,18 +62,18 @@ describe Chef::REST::AuthCredentials do
end
it "has a client name" do
- @auth_credentials.client_name.should == "client-name"
+ expect(@auth_credentials.client_name).to eq("client-name")
end
it "loads the private key when initialized with the path to the key" do
- @auth_credentials.key.should respond_to(:private_encrypt)
- @auth_credentials.key.to_s.should == KEY_DOT_PEM
+ expect(@auth_credentials.key).to respond_to(:private_encrypt)
+ expect(@auth_credentials.key.to_s).to eq(KEY_DOT_PEM)
end
describe "when loading the private key" do
it "strips extra whitespace before checking the key" do
key_file_fixture = CHEF_SPEC_DATA + '/ssl/private_key_with_whitespace.pem'
- lambda {Chef::REST::AuthCredentials.new("client-name", @key_file_fixture)}.should_not raise_error
+ expect {Chef::REST::AuthCredentials.new("client-name", @key_file_fixture)}.not_to raise_error
end
end
@@ -84,19 +84,19 @@ describe Chef::REST::AuthCredentials do
end
it "generates signature headers for the request" do
- Time.stub(:now).and_return(@request_time)
+ allow(Time).to receive(:now).and_return(@request_time)
actual = @auth_credentials.signature_headers(@request_params)
- actual["HOST"].should == "localhost"
- actual["X-OPS-AUTHORIZATION-1"].should == "kBssX1ENEwKtNYFrHElN9vYGWS7OeowepN9EsYc9csWfh8oUovryPKDxytQ/"
- actual["X-OPS-AUTHORIZATION-2"].should == "Wc2/nSSyxdWJjjfHzrE+YrqNQTaArOA7JkAf5p75eTUonCWcvNPjFrZVgKGS"
- actual["X-OPS-AUTHORIZATION-3"].should == "yhzHJQh+lcVA9wwARg5Hu9q+ddS8xBOdm3Vp5atl5NGHiP0loiigMYvAvzPO"
- actual["X-OPS-AUTHORIZATION-4"].should == "r9853eIxwYMhn5hLGhAGFQznJbE8+7F/lLU5Zmk2t2MlPY8q3o1Q61YD8QiJ"
- actual["X-OPS-AUTHORIZATION-5"].should == "M8lIt53ckMyUmSU0DDURoiXLVkE9mag/6Yq2tPNzWq2AdFvBqku9h2w+DY5k"
- actual["X-OPS-AUTHORIZATION-6"].should == "qA5Rnzw5rPpp3nrWA9jKkPw4Wq3+4ufO2Xs6w7GCjA=="
- actual["X-OPS-CONTENT-HASH"].should == "1tuzs5XKztM1ANrkGNPah6rW9GY="
- actual["X-OPS-SIGN"].should =~ %r{(version=1\.0)|(algorithm=sha1;version=1.0;)}
- actual["X-OPS-TIMESTAMP"].should == "2010-04-10T17:34:20Z"
- actual["X-OPS-USERID"].should == "client-name"
+ expect(actual["HOST"]).to eq("localhost")
+ expect(actual["X-OPS-AUTHORIZATION-1"]).to eq("kBssX1ENEwKtNYFrHElN9vYGWS7OeowepN9EsYc9csWfh8oUovryPKDxytQ/")
+ expect(actual["X-OPS-AUTHORIZATION-2"]).to eq("Wc2/nSSyxdWJjjfHzrE+YrqNQTaArOA7JkAf5p75eTUonCWcvNPjFrZVgKGS")
+ expect(actual["X-OPS-AUTHORIZATION-3"]).to eq("yhzHJQh+lcVA9wwARg5Hu9q+ddS8xBOdm3Vp5atl5NGHiP0loiigMYvAvzPO")
+ expect(actual["X-OPS-AUTHORIZATION-4"]).to eq("r9853eIxwYMhn5hLGhAGFQznJbE8+7F/lLU5Zmk2t2MlPY8q3o1Q61YD8QiJ")
+ expect(actual["X-OPS-AUTHORIZATION-5"]).to eq("M8lIt53ckMyUmSU0DDURoiXLVkE9mag/6Yq2tPNzWq2AdFvBqku9h2w+DY5k")
+ expect(actual["X-OPS-AUTHORIZATION-6"]).to eq("qA5Rnzw5rPpp3nrWA9jKkPw4Wq3+4ufO2Xs6w7GCjA==")
+ expect(actual["X-OPS-CONTENT-HASH"]).to eq("1tuzs5XKztM1ANrkGNPah6rW9GY=")
+ expect(actual["X-OPS-SIGN"]).to match(%r{(version=1\.0)|(algorithm=sha1;version=1.0;)})
+ expect(actual["X-OPS-TIMESTAMP"]).to eq("2010-04-10T17:34:20Z")
+ expect(actual["X-OPS-USERID"]).to eq("client-name")
end
@@ -110,13 +110,13 @@ describe Chef::REST::AuthCredentials do
end
it "generates the correct signature for version 1.1" do
- Time.stub(:now).and_return(@request_time)
+ allow(Time).to receive(:now).and_return(@request_time)
actual = @auth_credentials.signature_headers(@request_params)
- actual["HOST"].should == "localhost"
- actual["X-OPS-CONTENT-HASH"].should == "1tuzs5XKztM1ANrkGNPah6rW9GY="
- actual["X-OPS-SIGN"].should == "algorithm=sha1;version=1.1;"
- actual["X-OPS-TIMESTAMP"].should == "2010-04-10T17:34:20Z"
- actual["X-OPS-USERID"].should == "client-name"
+ expect(actual["HOST"]).to eq("localhost")
+ expect(actual["X-OPS-CONTENT-HASH"]).to eq("1tuzs5XKztM1ANrkGNPah6rW9GY=")
+ expect(actual["X-OPS-SIGN"]).to eq("algorithm=sha1;version=1.1;")
+ expect(actual["X-OPS-TIMESTAMP"]).to eq("2010-04-10T17:34:20Z")
+ expect(actual["X-OPS-USERID"]).to eq("client-name")
# mixlib-authN will test the actual signature stuff for each version of
# the protocol so we won't test it again here.
@@ -143,63 +143,63 @@ describe Chef::REST::RESTRequest do
end
it "stores the url it was created with" do
- @request.url.should == @url
+ expect(@request.url).to eq(@url)
end
it "stores the HTTP method" do
- @request.method.should == :POST
+ expect(@request.method).to eq(:POST)
end
it "adds the chef version header" do
- @request.headers.should == @headers.merge("X-Chef-Version" => ::Chef::VERSION)
+ expect(@request.headers).to eq(@headers.merge("X-Chef-Version" => ::Chef::VERSION))
end
describe "configuring the HTTP request" do
it "configures GET requests" do
@req_body = nil
rest_req = new_request(:GET)
- rest_req.http_request.should be_a_kind_of(Net::HTTP::Get)
- rest_req.http_request.path.should == "/?q=chef_is_awesome"
- rest_req.http_request.body.should be_nil
+ expect(rest_req.http_request).to be_a_kind_of(Net::HTTP::Get)
+ expect(rest_req.http_request.path).to eq("/?q=chef_is_awesome")
+ expect(rest_req.http_request.body).to be_nil
end
it "configures POST requests, including the body" do
- @request.http_request.should be_a_kind_of(Net::HTTP::Post)
- @request.http_request.path.should == "/?q=chef_is_awesome"
- @request.http_request.body.should == @req_body
+ expect(@request.http_request).to be_a_kind_of(Net::HTTP::Post)
+ expect(@request.http_request.path).to eq("/?q=chef_is_awesome")
+ expect(@request.http_request.body).to eq(@req_body)
end
it "configures PUT requests, including the body" do
rest_req = new_request(:PUT)
- rest_req.http_request.should be_a_kind_of(Net::HTTP::Put)
- rest_req.http_request.path.should == "/?q=chef_is_awesome"
- rest_req.http_request.body.should == @req_body
+ expect(rest_req.http_request).to be_a_kind_of(Net::HTTP::Put)
+ expect(rest_req.http_request.path).to eq("/?q=chef_is_awesome")
+ expect(rest_req.http_request.body).to eq(@req_body)
end
it "configures DELETE requests" do
rest_req = new_request(:DELETE)
- rest_req.http_request.should be_a_kind_of(Net::HTTP::Delete)
- rest_req.http_request.path.should == "/?q=chef_is_awesome"
- rest_req.http_request.body.should be_nil
+ expect(rest_req.http_request).to be_a_kind_of(Net::HTTP::Delete)
+ expect(rest_req.http_request.path).to eq("/?q=chef_is_awesome")
+ expect(rest_req.http_request.body).to be_nil
end
it "configures HTTP basic auth" do
@url = URI.parse("http://homie:theclown@chef.example.com:4000/?q=chef_is_awesome")
rest_req = new_request(:GET)
- rest_req.http_request.to_hash["authorization"].should == ["Basic aG9taWU6dGhlY2xvd24="]
+ expect(rest_req.http_request.to_hash["authorization"]).to eq(["Basic aG9taWU6dGhlY2xvd24="])
end
end
describe "configuring the HTTP client" do
it "configures the HTTP client for the host and port" do
http_client = new_request.http_client
- http_client.address.should == "chef.example.com"
- http_client.port.should == 4000
+ expect(http_client.address).to eq("chef.example.com")
+ expect(http_client.port).to eq(4000)
end
it "configures the HTTP client with the read timeout set in the config file" do
Chef::Config[:rest_timeout] = 9001
- new_request.http_client.read_timeout.should == 9001
+ expect(new_request.http_client.read_timeout).to eq(9001)
end
describe "for proxy" do
@@ -226,21 +226,21 @@ describe Chef::REST::RESTRequest do
describe "with :no_proxy nil" do
it "configures the proxy address and port when using http scheme" do
http_client = new_request.http_client
- http_client.proxy?.should == true
- http_client.proxy_address.should == "proxy.example.com"
- http_client.proxy_port.should == 3128
- http_client.proxy_user.should be_nil
- http_client.proxy_pass.should be_nil
+ expect(http_client.proxy?).to eq(true)
+ expect(http_client.proxy_address).to eq("proxy.example.com")
+ expect(http_client.proxy_port).to eq(3128)
+ expect(http_client.proxy_user).to be_nil
+ expect(http_client.proxy_pass).to be_nil
end
it "configures the proxy address and port when using https scheme" do
@url.scheme = "https"
http_client = new_request.http_client
- http_client.proxy?.should == true
- http_client.proxy_address.should == "sproxy.example.com"
- http_client.proxy_port.should == 3129
- http_client.proxy_user.should be_nil
- http_client.proxy_pass.should be_nil
+ expect(http_client.proxy?).to eq(true)
+ expect(http_client.proxy_address).to eq("sproxy.example.com")
+ expect(http_client.proxy_port).to eq(3129)
+ expect(http_client.proxy_user).to be_nil
+ expect(http_client.proxy_pass).to be_nil
end
end
@@ -251,21 +251,21 @@ describe Chef::REST::RESTRequest do
it "does not configure the proxy address and port when using http scheme" do
http_client = new_request.http_client
- http_client.proxy?.should == false
- http_client.proxy_address.should be_nil
- http_client.proxy_port.should be_nil
- http_client.proxy_user.should be_nil
- http_client.proxy_pass.should be_nil
+ expect(http_client.proxy?).to eq(false)
+ expect(http_client.proxy_address).to be_nil
+ expect(http_client.proxy_port).to be_nil
+ expect(http_client.proxy_user).to be_nil
+ expect(http_client.proxy_pass).to be_nil
end
it "does not configure the proxy address and port when using https scheme" do
@url.scheme = "https"
http_client = new_request.http_client
- http_client.proxy?.should == false
- http_client.proxy_address.should be_nil
- http_client.proxy_port.should be_nil
- http_client.proxy_user.should be_nil
- http_client.proxy_pass.should be_nil
+ expect(http_client.proxy?).to eq(false)
+ expect(http_client.proxy_address).to be_nil
+ expect(http_client.proxy_port).to be_nil
+ expect(http_client.proxy_user).to be_nil
+ expect(http_client.proxy_pass).to be_nil
end
end
@@ -282,17 +282,17 @@ describe Chef::REST::RESTRequest do
it "configures the proxy user and pass when using http scheme" do
http_client = new_request.http_client
- http_client.proxy?.should == true
- http_client.proxy_user.should == "homie"
- http_client.proxy_pass.should == "theclown"
+ expect(http_client.proxy?).to eq(true)
+ expect(http_client.proxy_user).to eq("homie")
+ expect(http_client.proxy_pass).to eq("theclown")
end
it "does not configure the proxy user and pass when using https scheme" do
@url.scheme = "https"
http_client = new_request.http_client
- http_client.proxy?.should == true
- http_client.proxy_user.should be_nil
- http_client.proxy_pass.should be_nil
+ expect(http_client.proxy?).to eq(true)
+ expect(http_client.proxy_user).to be_nil
+ expect(http_client.proxy_pass).to be_nil
end
end
@@ -309,17 +309,17 @@ describe Chef::REST::RESTRequest do
it "does not configure the proxy user and pass when using http scheme" do
http_client = new_request.http_client
- http_client.proxy?.should == true
- http_client.proxy_user.should be_nil
- http_client.proxy_pass.should be_nil
+ expect(http_client.proxy?).to eq(true)
+ expect(http_client.proxy_user).to be_nil
+ expect(http_client.proxy_pass).to be_nil
end
it "configures the proxy user and pass when using https scheme" do
@url.scheme = "https"
http_client = new_request.http_client
- http_client.proxy?.should == true
- http_client.proxy_user.should == "homie"
- http_client.proxy_pass.should == "theclown"
+ expect(http_client.proxy?).to eq(true)
+ expect(http_client.proxy_user).to eq("homie")
+ expect(http_client.proxy_pass).to eq("theclown")
end
end
end
diff --git a/spec/unit/rest_spec.rb b/spec/unit/rest_spec.rb
index 3047366c47..1aa7ac84ee 100644
--- a/spec/unit/rest_spec.rb
+++ b/spec/unit/rest_spec.rb
@@ -83,7 +83,7 @@ describe Chef::REST do
expect(content_length).not_to be_nil
expect(decompressor).not_to be_nil
- expect(decompressor < content_length).to be_true
+ expect(decompressor < content_length).to be_truthy
end
it "should allow the options hash to be frozen" do
@@ -214,7 +214,7 @@ describe Chef::REST do
it "indicates that requests should not be signed when it has no credentials" do
rest = Chef::REST.new(base_url, nil, nil)
- expect(rest.sign_requests?).to be_false
+ expect(rest.sign_requests?).to be_falsey
end
it "raises PrivateKeyMissing when the key file doesn't exist" do
@@ -462,7 +462,7 @@ describe Chef::REST do
end
it "should return `false`" do
- expect(rest.request(:GET, url)).to be_false
+ expect(rest.request(:GET, url)).to be_falsey
end
end
@@ -616,10 +616,10 @@ describe Chef::REST do
tempfile_path = nil
rest.streaming_request(url, {}) do |tempfile|
tempfile_path = tempfile.path
- expect(File.exist?(tempfile.path)).to be_true
+ expect(File.exist?(tempfile.path)).to be_truthy
expect(IO.read(tempfile.path).chomp).to eq("realultimatepower")
end
- expect(File.exist?(tempfile_path)).to be_false
+ expect(File.exist?(tempfile_path)).to be_falsey
end
it "does not raise a divide by zero exception if the content's actual size is 0" do
@@ -648,7 +648,7 @@ describe Chef::REST do
tempfile_path = tempfile.path
expect(IO.read(tempfile.path).chomp).to eq("realultimatepower")
end
- expect(File.exist?(tempfile_path)).to be_false
+ expect(File.exist?(tempfile_path)).to be_falsey
end
it "closes and unlinks the tempfile if there is an error while streaming the content to the tempfile" do
@@ -656,7 +656,7 @@ describe Chef::REST do
expect(path).not_to be_nil
allow(tempfile).to receive(:write).and_raise(IOError)
rest.fetch("cookbooks/a_cookbook") {|tmpfile| "shouldn't get here"}
- expect(File.exists?(path)).to be_false
+ expect(File.exists?(path)).to be_falsey
end
it "closes and unlinks the tempfile when the response is a redirect" do
@@ -683,7 +683,7 @@ describe Chef::REST do
rest.fetch("cookbooks/a_cookbook") do |tmpfile|
block_called = true
end
- expect(block_called).to be_true
+ expect(block_called).to be_truthy
end
end
end
@@ -718,15 +718,15 @@ describe Chef::REST do
it "does not sign the redirected request when sign_on_redirect is false" do
rest.sign_on_redirect = false
- rest.follow_redirect { expect(rest.sign_requests?).to be_false }
+ rest.follow_redirect { expect(rest.sign_requests?).to be_falsey }
end
it "resets sign_requests to the original value after following an unsigned redirect" do
rest.sign_on_redirect = false
- expect(rest.sign_requests?).to be_true
+ expect(rest.sign_requests?).to be_truthy
- rest.follow_redirect { expect(rest.sign_requests?).to be_false }
- expect(rest.sign_requests?).to be_true
+ rest.follow_redirect { expect(rest.sign_requests?).to be_falsey }
+ expect(rest.sign_requests?).to be_truthy
end
it "configures the redirect limit" do
diff --git a/spec/unit/role_spec.rb b/spec/unit/role_spec.rb
index 1a108c4247..5421b5a7b3 100644
--- a/spec/unit/role_spec.rb
+++ b/spec/unit/role_spec.rb
@@ -21,21 +21,21 @@ require 'chef/role'
describe Chef::Role do
before(:each) do
- Chef::Platform.stub(:windows?) { false }
+ allow(Chef::Platform).to receive(:windows?) { false }
@role = Chef::Role.new
@role.name("ops_master")
end
it "has a name" do
- @role.name("ops_master").should == "ops_master"
+ expect(@role.name("ops_master")).to eq("ops_master")
end
it "does not accept a name with spaces" do
- lambda { @role.name "ops master" }.should raise_error(ArgumentError)
+ expect { @role.name "ops master" }.to raise_error(ArgumentError)
end
it "does not accept non-String objects for the name" do
- lambda { @role.name({}) }.should raise_error(ArgumentError)
+ expect { @role.name({}) }.to raise_error(ArgumentError)
end
describe "when a run list is set" do
@@ -46,7 +46,7 @@ describe Chef::Role do
it "returns the run list" do
- @role.run_list.should == %w{ nginx recipe[ree] role[base]}
+ expect(@role.run_list).to eq(%w{ nginx recipe[ree] role[base]})
end
describe "and per-environment run lists are set" do
@@ -58,28 +58,28 @@ describe Chef::Role do
end
it "uses the default run list as *the* run_list" do
- @role.run_list.should == Chef::RunList.new("recipe[nagios::client]", "recipe[tims-acl::bork]")
+ expect(@role.run_list).to eq(Chef::RunList.new("recipe[nagios::client]", "recipe[tims-acl::bork]"))
end
it "gives the default run list as the when getting the _default run list" do
- @role.run_list_for("_default").should == @role.run_list
+ expect(@role.run_list_for("_default")).to eq(@role.run_list)
end
it "gives an environment specific run list" do
- @role.run_list_for("prod").should == Chef::RunList.new("recipe[nagios::client]", "recipe[tims-acl::bork]", "recipe[prod-base]")
+ expect(@role.run_list_for("prod")).to eq(Chef::RunList.new("recipe[nagios::client]", "recipe[tims-acl::bork]", "recipe[prod-base]"))
end
it "gives the default run list when no run list exists for the given environment" do
- @role.run_list_for("qa").should == @role.run_list
+ expect(@role.run_list_for("qa")).to eq(@role.run_list)
end
it "gives the environment specific run list even if it is empty" do
- @role.run_list_for("dev").should == Chef::RunList.new
+ expect(@role.run_list_for("dev")).to eq(Chef::RunList.new)
end
it "env_run_lists can only be set with _default run list in it" do
long_exception_name = Chef::Exceptions::InvalidEnvironmentRunListSpecification
- lambda {@role.env_run_lists({})}.should raise_error(long_exception_name)
+ expect {@role.env_run_lists({})}.to raise_error(long_exception_name)
end
end
@@ -87,17 +87,17 @@ describe Chef::Role do
describe "using the old #recipes API" do
it "should let you set the recipe array" do
- @role.recipes([ "one", "two" ]).should == [ "one", "two" ]
+ expect(@role.recipes([ "one", "two" ])).to eq([ "one", "two" ])
end
it "should let you return the recipe array" do
@role.recipes([ "one", "two" ])
- @role.recipes.should == [ "one", "two" ]
+ expect(@role.recipes).to eq([ "one", "two" ])
end
it "should not list roles in the recipe array" do
@role.run_list([ "one", "role[two]"])
- @role.recipes.should == [ "recipe[one]", "role[two]" ]
+ expect(@role.recipes).to eq([ "recipe[one]", "role[two]" ])
end
end
@@ -108,31 +108,31 @@ describe Chef::Role do
describe "default_attributes" do
it "should let you set the default attributes hash explicitly" do
- @role.default_attributes({ :one => 'two' }).should == { :one => 'two' }
+ expect(@role.default_attributes({ :one => 'two' })).to eq({ :one => 'two' })
end
it "should let you return the default attributes hash" do
@role.default_attributes({ :one => 'two' })
- @role.default_attributes.should == { :one => 'two' }
+ expect(@role.default_attributes).to eq({ :one => 'two' })
end
it "should throw an ArgumentError if we aren't a kind of hash" do
- lambda { @role.default_attributes(Array.new) }.should raise_error(ArgumentError)
+ expect { @role.default_attributes(Array.new) }.to raise_error(ArgumentError)
end
end
describe "override_attributes" do
it "should let you set the override attributes hash explicitly" do
- @role.override_attributes({ :one => 'two' }).should == { :one => 'two' }
+ expect(@role.override_attributes({ :one => 'two' })).to eq({ :one => 'two' })
end
it "should let you return the override attributes hash" do
@role.override_attributes({ :one => 'two' })
- @role.override_attributes.should == { :one => 'two' }
+ expect(@role.override_attributes).to eq({ :one => 'two' })
end
it "should throw an ArgumentError if we aren't a kind of hash" do
- lambda { @role.override_attributes(Array.new) }.should raise_error(ArgumentError)
+ expect { @role.override_attributes(Array.new) }.to raise_error(ArgumentError)
end
end
@@ -154,11 +154,11 @@ describe Chef::Role do
it "should update all fields except for name" do
@role.update_from!(@example)
- @role.name.should == "mars_volta"
- @role.description.should == @example.description
- @role.run_list.should == @example.run_list
- @role.default_attributes.should == @example.default_attributes
- @role.override_attributes.should == @example.override_attributes
+ expect(@role.name).to eq("mars_volta")
+ expect(@role.description).to eq(@example.description)
+ expect(@role.run_list).to eq(@example.run_list)
+ expect(@role.default_attributes).to eq(@example.default_attributes)
+ expect(@role.override_attributes).to eq(@example.override_attributes)
end
end
@@ -173,29 +173,29 @@ describe Chef::Role do
end
it "should serialize to a json hash" do
- Chef::JSONCompat.to_json(@role).should match(/^\{.+\}$/)
+ expect(Chef::JSONCompat.to_json(@role)).to match(/^\{.+\}$/)
end
it "includes the name in the JSON output" do
- @serialized_role.should =~ /"name":"mars_volta"/
+ expect(@serialized_role).to match(/"name":"mars_volta"/)
end
it "includes its description in the JSON" do
- @serialized_role.should match(/"description":"Great band!"/)
+ expect(@serialized_role).to match(/"description":"Great band!"/)
end
it "should include 'default_attributes'" do
- @serialized_role.should =~ /"default_attributes":\{"el_groupo":"nuevo"\}/
+ expect(@serialized_role).to match(/"default_attributes":\{"el_groupo":"nuevo"\}/)
end
it "should include 'override_attributes'" do
- @serialized_role.should =~ /"override_attributes":\{"deloused":"in the comatorium"\}/
+ expect(@serialized_role).to match(/"override_attributes":\{"deloused":"in the comatorium"\}/)
end
it "should include 'run_list'" do
#Activesupport messes with Chef json formatting
#This test should pass with and without activesupport
- @serialized_role.should =~ /"run_list":\["recipe\[one\]","recipe\[two\]","role\[a\]"\]/
+ expect(@serialized_role).to match(/"run_list":\["recipe\[one\]","recipe\[two\]","role\[a\]"\]/)
end
describe "and it has per-environment run lists" do
@@ -207,12 +207,12 @@ describe Chef::Role do
it "includes the per-environment run lists" do
#Activesupport messes with Chef json formatting
#This test should pass with and without activesupport
- @serialized_role["env_run_lists"]["production"].should == ['role[monitoring]', 'role[auditing]', 'role[apache]']
- @serialized_role["env_run_lists"]["dev"].should == ["role[nginx]"]
+ expect(@serialized_role["env_run_lists"]["production"]).to eq(['role[monitoring]', 'role[auditing]', 'role[apache]'])
+ expect(@serialized_role["env_run_lists"]["dev"]).to eq(["role[nginx]"])
end
it "does not include the default environment in the per-environment run lists" do
- @serialized_role["env_run_lists"].should_not have_key("_default")
+ expect(@serialized_role["env_run_lists"]).not_to have_key("_default")
end
end
@@ -233,7 +233,7 @@ describe Chef::Role do
end
it "should deserialize to a Chef::Role object" do
- @deserial.should be_a_kind_of(Chef::Role)
+ expect(@deserial).to be_a_kind_of(Chef::Role)
end
%w{
@@ -244,7 +244,7 @@ describe Chef::Role do
run_list
}.each do |t|
it "should preserves the '#{t}' attribute from the JSON object" do
- @deserial.send(t.to_sym).should == @role.send(t.to_sym)
+ expect(@deserial.send(t.to_sym)).to eq(@role.send(t.to_sym))
end
end
end
@@ -257,56 +257,57 @@ EOR
describe "when loading from disk" do
before do
default_cache_path = windows? ? 'C:\chef' : '/var/chef'
- Chef::Config.stub(:cache_path).and_return(default_cache_path)
+ allow(Chef::Config).to receive(:cache_path).and_return(default_cache_path)
end
it "should return a Chef::Role object from JSON" do
- Dir.should_receive(:glob).and_return(["#{Chef::Config[:role_path]}/memes", "#{Chef::Config[:role_path]}/memes/lolcat.json"])
+ expect(Dir).to receive(:glob).and_return(["#{Chef::Config[:role_path]}/memes", "#{Chef::Config[:role_path]}/memes/lolcat.json"])
file_path = File.join(Chef::Config[:role_path], 'memes/lolcat.json')
- File.should_receive(:exists?).with(file_path).exactly(1).times.and_return(true)
- IO.should_receive(:read).with(file_path).and_return('{"name": "ceiling_cat", "json_class": "Chef::Role" }')
- @role.should be_a_kind_of(Chef::Role)
+ expect(File).to receive(:exists?).with(file_path).exactly(1).times.and_return(true)
+ expect(IO).to receive(:read).with(file_path).and_return('{"name": "ceiling_cat", "json_class": "Chef::Role" }')
+ expect(@role).to be_a_kind_of(Chef::Role)
@role.class.from_disk("lolcat")
end
it "should return a Chef::Role object from a Ruby DSL" do
- Dir.should_receive(:glob).and_return(["#{Chef::Config[:role_path]}/memes", "#{Chef::Config[:role_path]}/memes/lolcat.rb"])
+ expect(Dir).to receive(:glob).and_return(["#{Chef::Config[:role_path]}/memes", "#{Chef::Config[:role_path]}/memes/lolcat.rb"])
rb_path = File.join(Chef::Config[:role_path], 'memes/lolcat.rb')
- File.should_receive(:exists?).with(rb_path).exactly(2).times.and_return(true)
- File.should_receive(:readable?).with(rb_path).exactly(1).times.and_return(true)
- IO.should_receive(:read).with(rb_path).and_return(ROLE_DSL)
- @role.should be_a_kind_of(Chef::Role)
+ expect(File).to receive(:exists?).with(rb_path).exactly(2).times.and_return(true)
+ expect(File).to receive(:readable?).with(rb_path).exactly(1).times.and_return(true)
+ expect(IO).to receive(:read).with(rb_path).and_return(ROLE_DSL)
+ expect(@role).to be_a_kind_of(Chef::Role)
@role.class.from_disk("lolcat")
end
it "should prefer a Chef::Role Object from JSON over one from a Ruby DSL" do
- Dir.should_receive(:glob).and_return(["#{Chef::Config[:role_path]}/memes", "#{Chef::Config[:role_path]}/memes/lolcat.json", "#{Chef::Config[:role_path]}/memes/lolcat.rb"])
+ expect(Dir).to receive(:glob).and_return(["#{Chef::Config[:role_path]}/memes", "#{Chef::Config[:role_path]}/memes/lolcat.json", "#{Chef::Config[:role_path]}/memes/lolcat.rb"])
js_path = File.join(Chef::Config[:role_path], 'memes/lolcat.json')
rb_path = File.join(Chef::Config[:role_path], 'memes/lolcat.rb')
- File.should_receive(:exists?).with(js_path).exactly(1).times.and_return(true)
- File.should_not_receive(:exists?).with(rb_path)
- IO.should_receive(:read).with(js_path).and_return('{"name": "ceiling_cat", "json_class": "Chef::Role" }')
- @role.should be_a_kind_of(Chef::Role)
+ expect(File).to receive(:exists?).with(js_path).exactly(1).times.and_return(true)
+ expect(File).not_to receive(:exists?).with(rb_path)
+ expect(IO).to receive(:read).with(js_path).and_return('{"name": "ceiling_cat", "json_class": "Chef::Role" }')
+ expect(@role).to be_a_kind_of(Chef::Role)
@role.class.from_disk("lolcat")
end
it "should raise an exception if the file does not exist" do
- Dir.should_receive(:glob).and_return(["#{Chef::Config[:role_path]}/meme.rb"])
- File.should_not_receive(:exists?)
- lambda {@role.class.from_disk("lolcat")}.should raise_error(Chef::Exceptions::RoleNotFound)
+ expect(Dir).to receive(:glob).and_return(["#{Chef::Config[:role_path]}/meme.rb"])
+ expect(File).not_to receive(:exists?)
+ expect {@role.class.from_disk("lolcat")}.to raise_error(Chef::Exceptions::RoleNotFound)
end
it "should raise an exception if two files exist with the same name" do
- Dir.should_receive(:glob).and_return(["#{Chef::Config[:role_path]}/memes/lolcat.rb", "#{Chef::Config[:role_path]}/lolcat.rb"])
- File.should_not_receive(:exists?)
- lambda {@role.class.from_disk("lolcat")}.should raise_error(Chef::Exceptions::DuplicateRole)
+ expect(Dir).to receive(:glob).and_return(["#{Chef::Config[:role_path]}/memes/lolcat.rb", "#{Chef::Config[:role_path]}/lolcat.rb"])
+ expect(File).not_to receive(:exists?)
+ expect {@role.class.from_disk("lolcat")}.to raise_error(Chef::Exceptions::DuplicateRole)
end
it "should not raise an exception if two files exist with a similar name" do
- Dir.should_receive(:glob).and_return(["#{Chef::Config[:role_path]}/memes/lolcat.rb", "#{Chef::Config[:role_path]}/super_lolcat.rb"])
- File.should_not_receive(:exists?)
- lambda {@role.class.from_disk("lolcat")}.should_not raise_error(Chef::Exceptions::DuplicateRole)
- end
+ expect(Dir).to receive(:glob).and_return(["#{Chef::Config[:role_path]}/memes/lolcat.rb", "#{Chef::Config[:role_path]}/super_lolcat.rb"])
+ expect(File).to receive(:exists?).with("#{Chef::Config[:role_path]}/memes/lolcat.rb").and_return(true)
+ allow_any_instance_of(Chef::Role).to receive(:from_file).with("#{Chef::Config[:role_path]}/memes/lolcat.rb")
+ expect{ @role.class.from_disk("lolcat") }.not_to raise_error
+ end
end
describe "when loading from disk and role_path is an array" do
@@ -316,45 +317,45 @@ EOR
end
it "should return a Chef::Role object from JSON" do
- Dir.should_receive(:glob).with(File.join('/path1', '**', '**')).exactly(1).times.and_return(['/path1/lolcat.json'])
- File.should_receive(:exists?).with('/path1/lolcat.json').exactly(1).times.and_return(true)
- IO.should_receive(:read).with('/path1/lolcat.json').and_return('{"name": "ceiling_cat", "json_class": "Chef::Role" }')
- @role.should be_a_kind_of(Chef::Role)
+ expect(Dir).to receive(:glob).with(File.join('/path1', '**', '**')).exactly(1).times.and_return(['/path1/lolcat.json'])
+ expect(File).to receive(:exists?).with('/path1/lolcat.json').exactly(1).times.and_return(true)
+ expect(IO).to receive(:read).with('/path1/lolcat.json').and_return('{"name": "ceiling_cat", "json_class": "Chef::Role" }')
+ expect(@role).to be_a_kind_of(Chef::Role)
@role.class.from_disk("lolcat")
end
it "should return a Chef::Role object from JSON when role is in the second path" do
- Dir.should_receive(:glob).with(File.join('/path1', '**', '**')).exactly(1).times.and_return([])
- Dir.should_receive(:glob).with(File.join('/path/path2', '**', '**')).exactly(1).times.and_return(['/path/path2/lolcat.json'])
- File.should_receive(:exists?).with('/path/path2/lolcat.json').exactly(1).times.and_return(true)
- IO.should_receive(:read).with('/path/path2/lolcat.json').and_return('{"name": "ceiling_cat", "json_class": "Chef::Role" }')
- @role.should be_a_kind_of(Chef::Role)
+ expect(Dir).to receive(:glob).with(File.join('/path1', '**', '**')).exactly(1).times.and_return([])
+ expect(Dir).to receive(:glob).with(File.join('/path/path2', '**', '**')).exactly(1).times.and_return(['/path/path2/lolcat.json'])
+ expect(File).to receive(:exists?).with('/path/path2/lolcat.json').exactly(1).times.and_return(true)
+ expect(IO).to receive(:read).with('/path/path2/lolcat.json').and_return('{"name": "ceiling_cat", "json_class": "Chef::Role" }')
+ expect(@role).to be_a_kind_of(Chef::Role)
@role.class.from_disk("lolcat")
end
it "should return a Chef::Role object from a Ruby DSL" do
- Dir.should_receive(:glob).with(File.join('/path1', '**', '**')).exactly(1).times.and_return(['/path1/lolcat.rb'])
- File.should_receive(:exists?).with('/path1/lolcat.rb').exactly(2).times.and_return(true)
- File.should_receive(:readable?).with('/path1/lolcat.rb').and_return(true)
- IO.should_receive(:read).with('/path1/lolcat.rb').exactly(1).times.and_return(ROLE_DSL)
- @role.should be_a_kind_of(Chef::Role)
+ expect(Dir).to receive(:glob).with(File.join('/path1', '**', '**')).exactly(1).times.and_return(['/path1/lolcat.rb'])
+ expect(File).to receive(:exists?).with('/path1/lolcat.rb').exactly(2).times.and_return(true)
+ expect(File).to receive(:readable?).with('/path1/lolcat.rb').and_return(true)
+ expect(IO).to receive(:read).with('/path1/lolcat.rb').exactly(1).times.and_return(ROLE_DSL)
+ expect(@role).to be_a_kind_of(Chef::Role)
@role.class.from_disk("lolcat")
end
it "should return a Chef::Role object from a Ruby DSL when role is in the second path" do
- Dir.should_receive(:glob).with(File.join('/path1', '**', '**')).exactly(1).times.and_return([])
- Dir.should_receive(:glob).with(File.join('/path/path2', '**', '**')).exactly(1).times.and_return(['/path/path2/lolcat.rb'])
- File.should_receive(:exists?).with('/path/path2/lolcat.rb').exactly(2).times.and_return(true)
- File.should_receive(:readable?).with('/path/path2/lolcat.rb').and_return(true)
- IO.should_receive(:read).with('/path/path2/lolcat.rb').exactly(1).times.and_return(ROLE_DSL)
- @role.should be_a_kind_of(Chef::Role)
+ expect(Dir).to receive(:glob).with(File.join('/path1', '**', '**')).exactly(1).times.and_return([])
+ expect(Dir).to receive(:glob).with(File.join('/path/path2', '**', '**')).exactly(1).times.and_return(['/path/path2/lolcat.rb'])
+ expect(File).to receive(:exists?).with('/path/path2/lolcat.rb').exactly(2).times.and_return(true)
+ expect(File).to receive(:readable?).with('/path/path2/lolcat.rb').and_return(true)
+ expect(IO).to receive(:read).with('/path/path2/lolcat.rb').exactly(1).times.and_return(ROLE_DSL)
+ expect(@role).to be_a_kind_of(Chef::Role)
@role.class.from_disk("lolcat")
end
it "should raise an exception if the file does not exist" do
- Dir.should_receive(:glob).with(File.join('/path1', '**', '**')).exactly(1).times.and_return([])
- Dir.should_receive(:glob).with(File.join('/path/path2', '**', '**')).exactly(1).times.and_return([])
- lambda {@role.class.from_disk("lolcat")}.should raise_error(Chef::Exceptions::RoleNotFound)
+ expect(Dir).to receive(:glob).with(File.join('/path1', '**', '**')).exactly(1).times.and_return([])
+ expect(Dir).to receive(:glob).with(File.join('/path/path2', '**', '**')).exactly(1).times.and_return([])
+ expect {@role.class.from_disk("lolcat")}.to raise_error(Chef::Exceptions::RoleNotFound)
end
end
diff --git a/spec/unit/run_context/cookbook_compiler_spec.rb b/spec/unit/run_context/cookbook_compiler_spec.rb
index 5c50c3dd4b..20ec1d2ef7 100644
--- a/spec/unit/run_context/cookbook_compiler_spec.rb
+++ b/spec/unit/run_context/cookbook_compiler_spec.rb
@@ -62,7 +62,7 @@ describe Chef::RunContext::CookbookCompiler do
node.run_list("dependency1::default")
compiler.compile_attributes
- node[:attr_load_order].should == ["dependency1::default", "dependency1::aa_first", "dependency1::zz_last"]
+ expect(node[:attr_load_order]).to eq(["dependency1::default", "dependency1::aa_first", "dependency1::zz_last"])
end
it "loads dependencies before loading the depending cookbook's attributes" do
@@ -73,11 +73,11 @@ describe Chef::RunContext::CookbookCompiler do
compiler.compile_attributes
# dependencies are stored in a hash so therefore unordered, but they should be loaded in sort order
- node[:attr_load_order].should == ["dependency1::default",
+ expect(node[:attr_load_order]).to eq(["dependency1::default",
"dependency1::aa_first",
"dependency1::zz_last",
"dependency2::default",
- "test-with-deps::default"]
+ "test-with-deps::default"])
end
it "does not follow infinite dependency loops" do
@@ -86,7 +86,7 @@ describe Chef::RunContext::CookbookCompiler do
# Circular deps should not cause infinite loops
compiler.compile_attributes
- node[:attr_load_order].should == ["circular-dep2::default", "circular-dep1::default", "test-with-circular-deps::default"]
+ expect(node[:attr_load_order]).to eq(["circular-dep2::default", "circular-dep1::default", "test-with-circular-deps::default"])
end
it "loads attributes from cookbooks that don't have a default.rb attribute file" do
@@ -94,7 +94,7 @@ describe Chef::RunContext::CookbookCompiler do
compiler.compile_attributes
- node[:attr_load_order].should == ["no-default-attr::server"]
+ expect(node[:attr_load_order]).to eq(["no-default-attr::server"])
end
end
@@ -108,7 +108,7 @@ describe Chef::RunContext::CookbookCompiler do
node.run_list("test-with-deps::default", "test-with-circular-deps::default")
compiler.compile_libraries
- LibraryLoadOrder.load_order.should == ["dependency1", "dependency2", "test-with-deps", "circular-dep2", "circular-dep1", "test-with-circular-deps"]
+ expect(LibraryLoadOrder.load_order).to eq(["dependency1", "dependency2", "test-with-deps", "circular-dep2", "circular-dep1", "test-with-circular-deps"])
end
end
@@ -122,7 +122,7 @@ describe Chef::RunContext::CookbookCompiler do
node.run_list("test-with-deps::default", "test-with-circular-deps::default")
compiler.compile_lwrps
- LibraryLoadOrder.load_order.should == ["dependency1-provider",
+ expect(LibraryLoadOrder.load_order).to eq(["dependency1-provider",
"dependency1-resource",
"dependency2-provider",
"dependency2-resource",
@@ -133,7 +133,7 @@ describe Chef::RunContext::CookbookCompiler do
"circular-dep1-provider",
"circular-dep1-resource",
"test-with-circular-deps-provider",
- "test-with-circular-deps-resource"]
+ "test-with-circular-deps-resource"])
end
end
@@ -148,12 +148,12 @@ describe Chef::RunContext::CookbookCompiler do
node.run_list("test-with-deps::default", "test-with-circular-deps::default")
compiler.compile_resource_definitions
- LibraryLoadOrder.load_order.should == ["dependency1-definition",
+ expect(LibraryLoadOrder.load_order).to eq(["dependency1-definition",
"dependency2-definition",
"test-with-deps-definition",
"circular-dep2-definition",
"circular-dep1-definition",
- "test-with-circular-deps-definition"]
+ "test-with-circular-deps-definition"])
end
end
@@ -166,19 +166,19 @@ describe Chef::RunContext::CookbookCompiler do
it "should return an array of cookbook names as symbols without duplicates" do
node.run_list("test-with-circular-deps::default", "circular-dep1::default", "circular-dep2::default")
- compiler.cookbook_order.should == [:"circular-dep2",
+ expect(compiler.cookbook_order).to eq([:"circular-dep2",
:"circular-dep1",
- :"test-with-circular-deps"]
+ :"test-with-circular-deps"])
end
it "determines if a cookbook is in the list of cookbooks reachable by dependency" do
node.run_list("test-with-deps::default", "test-with-deps::server")
- compiler.cookbook_order.should == [:dependency1, :dependency2, :"test-with-deps"]
- compiler.unreachable_cookbook?(:dependency1).should be_false
- compiler.unreachable_cookbook?(:dependency2).should be_false
- compiler.unreachable_cookbook?(:'test-with-deps').should be_false
- compiler.unreachable_cookbook?(:'circular-dep1').should be_true
- compiler.unreachable_cookbook?(:'circular-dep2').should be_true
+ expect(compiler.cookbook_order).to eq([:dependency1, :dependency2, :"test-with-deps"])
+ expect(compiler.unreachable_cookbook?(:dependency1)).to be_falsey
+ expect(compiler.unreachable_cookbook?(:dependency2)).to be_falsey
+ expect(compiler.unreachable_cookbook?(:'test-with-deps')).to be_falsey
+ expect(compiler.unreachable_cookbook?(:'circular-dep1')).to be_truthy
+ expect(compiler.unreachable_cookbook?(:'circular-dep2')).to be_truthy
end
diff --git a/spec/unit/run_context_spec.rb b/spec/unit/run_context_spec.rb
index ca0c4dd354..d656111a7d 100644
--- a/spec/unit/run_context_spec.rb
+++ b/spec/unit/run_context_spec.rb
@@ -21,8 +21,6 @@
require 'spec_helper'
require 'support/lib/library_load_order'
-Chef::Log.level = :debug
-
describe Chef::RunContext do
let(:chef_repo_path) { File.expand_path(File.join(CHEF_SPEC_DATA, "run_context", "cookbooks")) }
let(:cookbook_collection) {
@@ -38,12 +36,21 @@ describe Chef::RunContext do
let(:events) { Chef::EventDispatch::Dispatcher.new }
let(:run_context) { Chef::RunContext.new(node, cookbook_collection, events) }
+ before(:each) do
+ @original_log_level = Chef::Log.level
+ Chef::Log.level = :debug
+ end
+
+ after(:each) do
+ Chef::Log.level = @original_log_level
+ end
+
it "has a cookbook collection" do
- run_context.cookbook_collection.should == cookbook_collection
+ expect(run_context.cookbook_collection).to eq(cookbook_collection)
end
it "has a node" do
- run_context.node.should == node
+ expect(run_context.node).to eq(node)
end
describe "loading cookbooks for a run list" do
@@ -56,47 +63,52 @@ describe Chef::RunContext do
end
node.run_list << "test" << "test::one" << "test::two"
- node.should_receive(:loaded_recipe).with(:test, "default")
- node.should_receive(:loaded_recipe).with(:test, "one")
- node.should_receive(:loaded_recipe).with(:test, "two")
+ expect(node).to receive(:loaded_recipe).with(:test, "default")
+ expect(node).to receive(:loaded_recipe).with(:test, "one")
+ expect(node).to receive(:loaded_recipe).with(:test, "two")
run_context.load(node.run_list.expand('_default'))
end
it "should load all the definitions in the cookbooks for this node" do
- run_context.definitions.should have_key(:new_cat)
- run_context.definitions.should have_key(:new_badger)
- run_context.definitions.should have_key(:new_dog)
+ expect(run_context.definitions).to have_key(:new_cat)
+ expect(run_context.definitions).to have_key(:new_badger)
+ expect(run_context.definitions).to have_key(:new_dog)
end
it "should load all the recipes specified for this node" do
- run_context.resource_collection[0].to_s.should == "cat[einstein]"
- run_context.resource_collection[1].to_s.should == "cat[loulou]"
- run_context.resource_collection[2].to_s.should == "cat[birthday]"
- run_context.resource_collection[3].to_s.should == "cat[peanut]"
- run_context.resource_collection[4].to_s.should == "cat[fat peanut]"
+ expect(run_context.resource_collection[0].to_s).to eq("cat[einstein]")
+ expect(run_context.resource_collection[1].to_s).to eq("cat[loulou]")
+ expect(run_context.resource_collection[2].to_s).to eq("cat[birthday]")
+ expect(run_context.resource_collection[3].to_s).to eq("cat[peanut]")
+ expect(run_context.resource_collection[4].to_s).to eq("cat[fat peanut]")
end
it "loads all the attribute files in the cookbook collection" do
- run_context.loaded_fully_qualified_attribute?("test", "george").should be_true
- node[:george].should == "washington"
+ expect(run_context.loaded_fully_qualified_attribute?("test", "george")).to be_truthy
+ expect(node[:george]).to eq("washington")
end
it "registers attributes files as loaded so they won't be reloaded" do
# This test unfortunately is pretty tightly intertwined with the
# implementation of how nodes load attribute files, but is the only
# convenient way to test this behavior.
- node.should_not_receive(:from_file)
+ expect(node).not_to receive(:from_file)
node.include_attribute("test::george")
end
it "raises an error when attempting to include_recipe from a cookbook not reachable by run list or dependencies" do
- node.should_receive(:loaded_recipe).with(:ancient, "aliens")
- lambda do
+ expect(node).to receive(:loaded_recipe).with(:ancient, "aliens")
+ expect do
run_context.include_recipe("ancient::aliens")
# In CHEF-5120, this becomes a Chef::Exceptions::MissingCookbookDependency error:
- end.should raise_error(Chef::Exceptions::CookbookNotFound)
+ end.to raise_error(Chef::Exceptions::CookbookNotFound)
end
+ it "raises an error on a recipe with a leading :: with no current_cookbook" do
+ expect do
+ run_context.include_recipe("::aliens")
+ end.to raise_error(RuntimeError)
+ end
end
describe "querying the contents of cookbooks" do
@@ -110,8 +122,8 @@ describe Chef::RunContext do
}
it "queries whether a given cookbook has a specific template" do
- run_context.should have_template_in_cookbook("openldap", "test.erb")
- run_context.should_not have_template_in_cookbook("openldap", "missing.erb")
+ expect(run_context).to have_template_in_cookbook("openldap", "test.erb")
+ expect(run_context).not_to have_template_in_cookbook("openldap", "missing.erb")
end
it "errors when querying for a template in a not-available cookbook" do
@@ -121,8 +133,8 @@ describe Chef::RunContext do
end
it "queries whether a given cookbook has a specific cookbook_file" do
- run_context.should have_cookbook_file_in_cookbook("java", "java.response")
- run_context.should_not have_cookbook_file_in_cookbook("java", "missing.txt")
+ expect(run_context).to have_cookbook_file_in_cookbook("java", "java.response")
+ expect(run_context).not_to have_cookbook_file_in_cookbook("java", "missing.txt")
end
it "errors when querying for a cookbook_file in a not-available cookbook" do
@@ -140,52 +152,11 @@ describe Chef::RunContext do
it "stores and deletes the reboot request" do
run_context.request_reboot(expected)
expect(run_context.reboot_info).to eq(expected)
- expect(run_context.reboot_requested?).to be_true
+ expect(run_context.reboot_requested?).to be_truthy
run_context.cancel_reboot
expect(run_context.reboot_info).to eq({})
- expect(run_context.reboot_requested?).to be_false
- end
- end
-
- describe "notifications" do
- let(:notification) { Chef::Resource::Notification.new(nil, nil, notifying_resource) }
-
- shared_context "notifying resource is a Chef::Resource" do
- let(:notifying_resource) { Chef::Resource.new("gerbil") }
-
- it "should be keyed off the resource name" do
- run_context.send(setter, notification)
- expect(run_context.send(getter, notifying_resource)).to eq([notification])
- end
- end
-
- shared_context "notifying resource is a subclass of Chef::Resource" do
- let(:declared_type) { :alpaca }
- let(:notifying_resource) {
- r = Class.new(Chef::Resource).new("guinea pig")
- r.declared_type = declared_type
- r
- }
-
- it "should be keyed off the resource declared key" do
- run_context.send(setter, notification)
- expect(run_context.send(getter, notifying_resource)).to eq([notification])
- end
- end
-
- describe "of the immediate kind" do
- let(:setter) { :notifies_immediately }
- let(:getter) { :immediate_notifications }
- include_context "notifying resource is a Chef::Resource"
- include_context "notifying resource is a subclass of Chef::Resource"
- end
-
- describe "of the delayed kind" do
- let(:setter) { :notifies_delayed }
- let(:getter) { :delayed_notifications }
- include_context "notifying resource is a Chef::Resource"
- include_context "notifying resource is a subclass of Chef::Resource"
+ expect(run_context.reboot_requested?).to be_falsey
end
end
end
diff --git a/spec/unit/run_list/run_list_expansion_spec.rb b/spec/unit/run_list/run_list_expansion_spec.rb
index 907e3d3985..859219d346 100644
--- a/spec/unit/run_list/run_list_expansion_spec.rb
+++ b/spec/unit/run_list/run_list_expansion_spec.rb
@@ -27,23 +27,23 @@ describe Chef::RunList::RunListExpansion do
describe "before expanding the run list" do
it "has an array of run list items" do
- @expansion.run_list_items.should == @run_list.run_list_items
+ expect(@expansion.run_list_items).to eq(@run_list.run_list_items)
end
it "has default_attrs" do
- @expansion.default_attrs.should == Mash.new
+ expect(@expansion.default_attrs).to eq(Mash.new)
end
it "has override attrs" do
- @expansion.override_attrs.should == Mash.new
+ expect(@expansion.override_attrs).to eq(Mash.new)
end
it "it has an empty list of recipes" do
- @expansion.should have(0).recipes
+ expect(@expansion.recipes.size).to eq(0)
end
it "has not applied its roles" do
- @expansion.applied_role?('rage').should be_false
+ expect(@expansion.applied_role?('rage')).to be_falsey
end
end
@@ -54,28 +54,28 @@ describe Chef::RunList::RunListExpansion do
r.env_run_lists('_default' => [], "prod" => ["recipe[prod-only]"])
end
@expansion = Chef::RunList::RunListExpansion.new("prod", @run_list.run_list_items)
- @expansion.should_receive(:fetch_role).and_return(@rage_role)
+ expect(@expansion).to receive(:fetch_role).and_return(@rage_role)
@expansion.expand
end
it "has the correct list of recipes for the given environment" do
- @expansion.recipes.should == ["lobster", "prod-only", "fist"]
+ expect(@expansion.recipes).to eq(["lobster", "prod-only", "fist"])
end
end
describe "after applying a role" do
before do
- @expansion.stub(:fetch_role).and_return(Chef::Role.new)
+ allow(@expansion).to receive(:fetch_role).and_return(Chef::Role.new)
@expansion.inflate_role('rage', "role[base]")
end
it "tracks the applied role" do
- @expansion.applied_role?('rage').should be_true
+ expect(@expansion.applied_role?('rage')).to be_truthy
end
it "does not inflate the role again" do
- @expansion.inflate_role('rage', "role[base]").should be_false
+ expect(@expansion.inflate_role('rage', "role[base]")).to be_falsey
end
end
@@ -89,39 +89,39 @@ describe Chef::RunList::RunListExpansion do
@second_role.run_list('recipe[crabrevenge]')
@second_role.default_attributes({'foo' => 'boo'})
@second_role.override_attributes({'baz' => 'bux'})
- @expansion.stub(:fetch_role).and_return(@first_role, @second_role)
+ allow(@expansion).to receive(:fetch_role).and_return(@first_role, @second_role)
@expansion.expand
end
it "has the ordered list of recipes" do
- @expansion.recipes.should == ['lobster', 'crabrevenge', 'fist']
+ expect(@expansion.recipes).to eq(['lobster', 'crabrevenge', 'fist'])
end
- it "has the merged attributes from the roles with outer roles overridding inner" do
- @expansion.default_attrs.should == {'foo' => 'bar'}
- @expansion.override_attrs.should == {'baz' => 'qux'}
+ it "has the merged attributes from the roles with outer roles overriding inner" do
+ expect(@expansion.default_attrs).to eq({'foo' => 'bar'})
+ expect(@expansion.override_attrs).to eq({'baz' => 'qux'})
end
it "has the list of all roles applied" do
# this is the correct order, but 1.8 hash order is not stable
- @expansion.roles.should =~ ['rage', 'mollusk']
+ expect(@expansion.roles).to match_array(['rage', 'mollusk'])
end
end
- describe "after expanding a run list with a non existant role" do
+ describe "after expanding a run list with a non existent role" do
before do
- @expansion.stub(:fetch_role) { @expansion.role_not_found('crabrevenge', "role[base]") }
+ allow(@expansion).to receive(:fetch_role) { @expansion.role_not_found('crabrevenge', "role[base]") }
@expansion.expand
end
it "is invalid" do
- @expansion.should be_invalid
- @expansion.errors?.should be_true # aliases
+ expect(@expansion).to be_invalid
+ expect(@expansion.errors?).to be_truthy # aliases
end
it "has a list of invalid role names" do
- @expansion.errors.should include('crabrevenge')
+ expect(@expansion.errors).to include('crabrevenge')
end
end
diff --git a/spec/unit/run_list/run_list_item_spec.rb b/spec/unit/run_list/run_list_item_spec.rb
index 6b9de713da..16832c1b7d 100644
--- a/spec/unit/run_list/run_list_item_spec.rb
+++ b/spec/unit/run_list/run_list_item_spec.rb
@@ -22,16 +22,16 @@ describe Chef::RunList::RunListItem do
describe "when creating from a Hash" do
it "raises an exception when the hash doesn't have a :type key" do
- lambda {Chef::RunList::RunListItem.new(:name => "tatft")}.should raise_error(ArgumentError)
+ expect {Chef::RunList::RunListItem.new(:name => "tatft")}.to raise_error(ArgumentError)
end
it "raises an exception when the hash doesn't have an :name key" do
- lambda {Chef::RunList::RunListItem.new(:type => 'R') }.should raise_error(ArgumentError)
+ expect {Chef::RunList::RunListItem.new(:type => 'R') }.to raise_error(ArgumentError)
end
it "sets the name and type as given in the hash" do
item = Chef::RunList::RunListItem.new(:type => 'fuuu', :name => 'uuuu')
- item.to_s.should == 'fuuu[uuuu]'
+ expect(item.to_s).to eq('fuuu[uuuu]')
end
end
@@ -39,47 +39,47 @@ describe Chef::RunList::RunListItem do
describe "when creating an item from a string" do
it "parses a qualified recipe" do
item = Chef::RunList::RunListItem.new("recipe[rage]")
- item.should be_a_recipe
- item.should_not be_a_role
- item.to_s.should == 'recipe[rage]'
- item.name.should == 'rage'
+ expect(item).to be_a_recipe
+ expect(item).not_to be_a_role
+ expect(item.to_s).to eq('recipe[rage]')
+ expect(item.name).to eq('rage')
end
it "parses a qualified recipe with a version" do
item = Chef::RunList::RunListItem.new("recipe[rage@0.1.0]")
- item.should be_a_recipe
- item.should_not be_a_role
- item.to_s.should == 'recipe[rage@0.1.0]'
- item.name.should == 'rage'
- item.version.should == '0.1.0'
+ expect(item).to be_a_recipe
+ expect(item).not_to be_a_role
+ expect(item.to_s).to eq('recipe[rage@0.1.0]')
+ expect(item.name).to eq('rage')
+ expect(item.version).to eq('0.1.0')
end
it "parses a qualified role" do
item = Chef::RunList::RunListItem.new("role[fist]")
- item.should be_a_role
- item.should_not be_a_recipe
- item.to_s.should == 'role[fist]'
- item.name.should == 'fist'
+ expect(item).to be_a_role
+ expect(item).not_to be_a_recipe
+ expect(item.to_s).to eq('role[fist]')
+ expect(item.name).to eq('fist')
end
it "parses an unqualified recipe" do
item = Chef::RunList::RunListItem.new("lobster")
- item.should be_a_recipe
- item.should_not be_a_role
- item.to_s.should == 'recipe[lobster]'
- item.name.should == 'lobster'
+ expect(item).to be_a_recipe
+ expect(item).not_to be_a_role
+ expect(item.to_s).to eq('recipe[lobster]')
+ expect(item.name).to eq('lobster')
end
it "raises an exception when the string has typo on the type part" do
- lambda {Chef::RunList::RunListItem.new("Recipe[lobster]") }.should raise_error(ArgumentError)
+ expect {Chef::RunList::RunListItem.new("Recipe[lobster]") }.to raise_error(ArgumentError)
end
it "raises an exception when the string has extra space between the type and the name" do
- lambda {Chef::RunList::RunListItem.new("recipe [lobster]") }.should raise_error(ArgumentError)
+ expect {Chef::RunList::RunListItem.new("recipe [lobster]") }.to raise_error(ArgumentError)
end
it "raises an exception when the string does not close the bracket" do
- lambda {Chef::RunList::RunListItem.new("recipe[lobster") }.should raise_error(ArgumentError)
+ expect {Chef::RunList::RunListItem.new("recipe[lobster") }.to raise_error(ArgumentError)
end
end
@@ -87,31 +87,31 @@ describe Chef::RunList::RunListItem do
it "is equal to another run list item that has the same name and type" do
item1 = Chef::RunList::RunListItem.new('recipe[lrf]')
item2 = Chef::RunList::RunListItem.new('recipe[lrf]')
- item1.should == item2
+ expect(item1).to eq(item2)
end
it "is not equal to another run list item with the same name and different type" do
item1 = Chef::RunList::RunListItem.new('recipe[lrf]')
item2 = Chef::RunList::RunListItem.new('role[lrf]')
- item1.should_not == item2
+ expect(item1).not_to eq(item2)
end
it "is not equal to another run list item with the same type and different name" do
item1 = Chef::RunList::RunListItem.new('recipe[lrf]')
item2 = Chef::RunList::RunListItem.new('recipe[lobsterragefist]')
- item1.should_not == item2
+ expect(item1).not_to eq(item2)
end
it "is not equal to another run list item with the same name and type but different version" do
item1 = Chef::RunList::RunListItem.new('recipe[lrf,0.1.0]')
item2 = Chef::RunList::RunListItem.new('recipe[lrf,0.2.0]')
- item1.should_not == item2
+ expect(item1).not_to eq(item2)
end
end
describe "comparing to strings" do
it "is equal to a string if that string matches its to_s representation" do
- Chef::RunList::RunListItem.new('recipe[lrf]').should == 'recipe[lrf]'
+ expect(Chef::RunList::RunListItem.new('recipe[lrf]')).to eq('recipe[lrf]')
end
end
end
diff --git a/spec/unit/run_list/versioned_recipe_list_spec.rb b/spec/unit/run_list/versioned_recipe_list_spec.rb
index 5cef32c32b..209ac37fc1 100644
--- a/spec/unit/run_list/versioned_recipe_list_spec.rb
+++ b/spec/unit/run_list/versioned_recipe_list_spec.rb
@@ -22,7 +22,7 @@ describe Chef::RunList::VersionedRecipeList do
describe "initialize" do
it "should create an empty array" do
l = Chef::RunList::VersionedRecipeList.new
- l.should == []
+ expect(l).to eq([])
end
end
@@ -36,41 +36,41 @@ describe Chef::RunList::VersionedRecipeList do
it "should append the recipe to the end of the list" do
@list.add_recipe "rails"
- @list.should == ["apt", "god", "apache2", "rails"]
+ expect(@list).to eq(["apt", "god", "apache2", "rails"])
end
it "should not duplicate entries" do
@list.add_recipe "apt"
- @list.should == ["apt", "god", "apache2"]
+ expect(@list).to eq(["apt", "god", "apache2"])
end
it "should allow you to specify a version" do
@list.add_recipe "rails", "1.0.0"
- @list.should == ["apt", "god", "apache2", "rails"]
- @list.with_versions.should include({:name => "rails", :version => "1.0.0"})
+ expect(@list).to eq(["apt", "god", "apache2", "rails"])
+ expect(@list.with_versions).to include({:name => "rails", :version => "1.0.0"})
end
it "should allow you to specify a version for a recipe that already exists" do
@list.add_recipe "apt", "1.2.3"
- @list.should == ["apt", "god", "apache2"]
- @list.with_versions.should include({:name => "apt", :version => "1.2.3"})
+ expect(@list).to eq(["apt", "god", "apache2"])
+ expect(@list.with_versions).to include({:name => "apt", :version => "1.2.3"})
end
it "should allow you to specify the same version of a recipe twice" do
@list.add_recipe "rails", "1.0.0"
@list.add_recipe "rails", "1.0.0"
- @list.with_versions.should include({:name => "rails", :version => "1.0.0"})
+ expect(@list.with_versions).to include({:name => "rails", :version => "1.0.0"})
end
it "should allow you to spcify no version, even when a version already exists" do
@list.add_recipe "rails", "1.0.0"
@list.add_recipe "rails"
- @list.with_versions.should include({:name => "rails", :version => "1.0.0"})
+ expect(@list.with_versions).to include({:name => "rails", :version => "1.0.0"})
end
it "should not allow multiple versions of the same recipe" do
@list.add_recipe "rails", "1.0.0"
- lambda {@list.add_recipe "rails", "0.1.0"}.should raise_error Chef::Exceptions::CookbookVersionConflict
+ expect {@list.add_recipe "rails", "0.1.0"}.to raise_error Chef::Exceptions::CookbookVersionConflict
end
end
@@ -86,13 +86,13 @@ describe Chef::RunList::VersionedRecipeList do
end
it "should return an array of hashes with :name and :version" do
- @list.with_versions.should == @recipes
+ expect(@list.with_versions).to eq(@recipes)
end
it "should retain the same order as the version-less list" do
with_versions = @list.with_versions
@list.each_with_index do |item, index|
- with_versions[index][:name].should == item
+ expect(with_versions[index][:name]).to eq(item)
end
end
end
@@ -115,8 +115,8 @@ describe Chef::RunList::VersionedRecipeList do
it "should return an array of hashes with :name and :version_constraint" do
@list.with_version_constraints.each do |x|
- x.should have_key :name
- x[:version_constraint].should_not be nil
+ expect(x).to have_key :name
+ expect(x[:version_constraint]).not_to be nil
end
end
end
diff --git a/spec/unit/run_list_spec.rb b/spec/unit/run_list_spec.rb
index cc7e29af0f..bf996de8c1 100644
--- a/spec/unit/run_list_spec.rb
+++ b/spec/unit/run_list_spec.rb
@@ -31,42 +31,42 @@ describe Chef::RunList do
describe "<<" do
it "should add a recipe to the run list and recipe list with the fully qualified name" do
@run_list << 'recipe[needy]'
- @run_list.should include('recipe[needy]')
- @run_list.recipes.should include("needy")
+ expect(@run_list).to include('recipe[needy]')
+ expect(@run_list.recipes).to include("needy")
end
it "should add a role to the run list and role list with the fully qualified name" do
@run_list << "role[woot]"
- @run_list.should include('role[woot]')
- @run_list.roles.should include('woot')
+ expect(@run_list).to include('role[woot]')
+ expect(@run_list.roles).to include('woot')
end
it "should accept recipes that are unqualified" do
@run_list << "needy"
- @run_list.should include('recipe[needy]')
- @run_list.recipes.include?('needy').should == true
+ expect(@run_list).to include('recipe[needy]')
+ expect(@run_list.recipes.include?('needy')).to eq(true)
end
it "should not allow duplicates" do
@run_list << "needy"
@run_list << "needy"
- @run_list.run_list.length.should == 1
- @run_list.recipes.length.should == 1
+ expect(@run_list.run_list.length).to eq(1)
+ expect(@run_list.recipes.length).to eq(1)
end
it "should allow two versions of a recipe" do
@run_list << "recipe[needy@0.2.0]"
@run_list << "recipe[needy@0.1.0]"
- @run_list.run_list.length.should == 2
- @run_list.recipes.length.should == 2
- @run_list.recipes.include?('needy').should == true
+ expect(@run_list.run_list.length).to eq(2)
+ expect(@run_list.recipes.length).to eq(2)
+ expect(@run_list.recipes.include?('needy')).to eq(true)
end
it "should not allow duplicate versions of a recipe" do
@run_list << "recipe[needy@0.2.0]"
@run_list << "recipe[needy@0.2.0]"
- @run_list.run_list.length.should == 1
- @run_list.recipes.length.should == 1
+ expect(@run_list.run_list.length).to eq(1)
+ expect(@run_list.recipes.length).to eq(1)
end
end
@@ -75,12 +75,12 @@ describe Chef::RunList do
# since full behavior is tested above.
it "should add a recipe to the run_list" do
@run_list.add 'recipe[needy]'
- @run_list.should include('recipe[needy]')
+ expect(@run_list).to include('recipe[needy]')
end
it "should add a role to the run_list" do
@run_list.add 'role[needy]'
- @run_list.should include('role[needy]')
+ expect(@run_list).to include('role[needy]')
end
end
@@ -89,43 +89,43 @@ describe Chef::RunList do
@run_list << "foo"
r = Chef::RunList.new
r << "foo"
- @run_list.should == r
+ expect(@run_list).to eq(r)
end
it "should believe a RunList is equal to an array named after it's members" do
@run_list << "foo"
@run_list << "baz"
- @run_list.should == [ "foo", "baz" ]
+ expect(@run_list).to eq([ "foo", "baz" ])
end
end
describe "empty?" do
it "should be emtpy if the run list has no members" do
- @run_list.empty?.should == true
+ expect(@run_list.empty?).to eq(true)
end
it "should not be empty if the run list has members" do
@run_list << "chromeo"
- @run_list.empty?.should == false
+ expect(@run_list.empty?).to eq(false)
end
end
describe "[]" do
it "should let you look up a member in the run list by position" do
@run_list << 'recipe[loulou]'
- @run_list[0].should == 'recipe[loulou]'
+ expect(@run_list[0]).to eq('recipe[loulou]')
end
end
describe "[]=" do
it "should let you set a member of the run list by position" do
@run_list[0] = 'recipe[loulou]'
- @run_list[0].should == 'recipe[loulou]'
+ expect(@run_list[0]).to eq('recipe[loulou]')
end
it "should properly expand a member of the run list given by position" do
@run_list[0] = 'loulou'
- @run_list[0].should == 'recipe[loulou]'
+ expect(@run_list[0]).to eq('recipe[loulou]')
end
end
@@ -135,8 +135,8 @@ describe Chef::RunList do
@run_list << "bar"
seen = Array.new
@run_list.each { |r| seen << r }
- seen.should be_include("recipe[foo]")
- seen.should be_include("recipe[bar]")
+ expect(seen).to be_include("recipe[foo]")
+ expect(seen).to be_include("recipe[bar]")
end
end
@@ -144,7 +144,7 @@ describe Chef::RunList do
it "should yield each members index to your block" do
to_add = [ "recipe[foo]", "recipe[bar]", "recipe[baz]" ]
to_add.each { |i| @run_list << i }
- @run_list.each_index { |i| @run_list[i].should == to_add[i] }
+ @run_list.each_index { |i| expect(@run_list[i]).to eq(to_add[i]) }
end
end
@@ -160,8 +160,8 @@ describe Chef::RunList do
@run_list << "chromeo"
list = %w{camp chairs snakes clowns}
@run_list.reset!(list)
- list.each { |i| @run_list.should be_include(i) }
- @run_list.include?("chromeo").should == false
+ list.each { |i| expect(@run_list).to be_include(i) }
+ expect(@run_list.include?("chromeo")).to eq(false)
end
end
@@ -173,9 +173,9 @@ describe Chef::RunList do
@role.default_attributes :one => :two
@role.override_attributes :three => :four
- Chef::Role.stub(:load).and_return(@role)
+ allow(Chef::Role).to receive(:load).and_return(@role)
@rest = double("Chef::REST", { :get_rest => @role, :url => "/" })
- Chef::REST.stub(:new).and_return(@rest)
+ allow(Chef::REST).to receive(:new).and_return(@rest)
@run_list << "role[stubby]"
@run_list << "kitty"
@@ -183,13 +183,13 @@ describe Chef::RunList do
describe "from disk" do
it "should load the role from disk" do
- Chef::Role.should_receive(:from_disk).with("stubby")
+ expect(Chef::Role).to receive(:from_disk).with("stubby")
@run_list.expand("_default", "disk")
end
it "should log a helpful error if the role is not available" do
- Chef::Role.stub(:from_disk).and_raise(Chef::Exceptions::RoleNotFound)
- Chef::Log.should_receive(:error).with("Role stubby (included by 'top level') is in the runlist but does not exist. Skipping expand.")
+ allow(Chef::Role).to receive(:from_disk).and_raise(Chef::Exceptions::RoleNotFound)
+ expect(Chef::Log).to receive(:error).with("Role stubby (included by 'top level') is in the runlist but does not exist. Skipping expand.")
@run_list.expand("_default", "disk")
end
end
@@ -198,11 +198,11 @@ describe Chef::RunList do
it "should load the role from the chef server" do
#@rest.should_receive(:get_rest).with("roles/stubby")
expansion = @run_list.expand("_default", "server")
- expansion.recipes.should == ['one', 'two', 'kitty']
+ expect(expansion.recipes).to eq(['one', 'two', 'kitty'])
end
it "should default to expanding from the server" do
- @rest.should_receive(:get_rest).with("roles/stubby")
+ expect(@rest).to receive(:get_rest).with("roles/stubby")
@run_list.expand("_default")
end
@@ -213,7 +213,7 @@ describe Chef::RunList do
it "expands the run list using the environment specific run list" do
expansion = @run_list.expand("production", "server")
- expansion.recipes.should == %w{one two five kitty}
+ expect(expansion.recipes).to eq(%w{one two five kitty})
end
describe "and multiply nested roles" do
@@ -233,13 +233,13 @@ describe Chef::RunList do
end
it "expands the run list using the specified environment for all nested roles" do
- Chef::REST.stub(:new).and_return(@multiple_rest_requests)
- @multiple_rest_requests.should_receive(:get_rest).with("roles/stubby").and_return(@role)
- @multiple_rest_requests.should_receive(:get_rest).with("roles/prod-base").and_return(@role_prod_base)
- @multiple_rest_requests.should_receive(:get_rest).with("roles/nested-deeper").and_return(@role_nested_deeper)
+ allow(Chef::REST).to receive(:new).and_return(@multiple_rest_requests)
+ expect(@multiple_rest_requests).to receive(:get_rest).with("roles/stubby").and_return(@role)
+ expect(@multiple_rest_requests).to receive(:get_rest).with("roles/prod-base").and_return(@role_prod_base)
+ expect(@multiple_rest_requests).to receive(:get_rest).with("roles/nested-deeper").and_return(@role_nested_deeper)
expansion = @run_list.expand("production", "server")
- expansion.recipes.should == %w{one two five prod-secret-sauce kitty}
+ expect(expansion.recipes).to eq(%w{one two five prod-secret-sauce kitty})
end
end
@@ -250,18 +250,18 @@ describe Chef::RunList do
it "should return the list of expanded recipes" do
expansion = @run_list.expand("_default")
- expansion.recipes[0].should == "one"
- expansion.recipes[1].should == "two"
+ expect(expansion.recipes[0]).to eq("one")
+ expect(expansion.recipes[1]).to eq("two")
end
it "should return the list of default attributes" do
expansion = @run_list.expand("_default")
- expansion.default_attrs[:one].should == :two
+ expect(expansion.default_attrs[:one]).to eq(:two)
end
it "should return the list of override attributes" do
expansion = @run_list.expand("_default")
- expansion.override_attrs[:three].should == :four
+ expect(expansion.override_attrs[:three]).to eq(:four)
end
it "should recurse into a child role" do
@@ -270,12 +270,12 @@ describe Chef::RunList do
dog.default_attributes :seven => :nine
dog.run_list "three"
@role.run_list << "role[dog]"
- Chef::Role.stub(:from_disk).with("stubby").and_return(@role)
- Chef::Role.stub(:from_disk).with("dog").and_return(dog)
+ allow(Chef::Role).to receive(:from_disk).with("stubby").and_return(@role)
+ allow(Chef::Role).to receive(:from_disk).with("dog").and_return(dog)
expansion = @run_list.expand("_default", 'disk')
- expansion.recipes[2].should == "three"
- expansion.default_attrs[:seven].should == :nine
+ expect(expansion.recipes[2]).to eq("three")
+ expect(expansion.default_attrs[:seven]).to eq(:nine)
end
it "should not recurse infinitely" do
@@ -284,13 +284,13 @@ describe Chef::RunList do
dog.default_attributes :seven => :nine
dog.run_list "role[dog]", "three"
@role.run_list << "role[dog]"
- Chef::Role.stub(:from_disk).with("stubby").and_return(@role)
- Chef::Role.should_receive(:from_disk).with("dog").once.and_return(dog)
+ allow(Chef::Role).to receive(:from_disk).with("stubby").and_return(@role)
+ expect(Chef::Role).to receive(:from_disk).with("dog").once.and_return(dog)
expansion = @run_list.expand("_default", 'disk')
- expansion.recipes[2].should == "three"
- expansion.recipes[3].should == "kitty"
- expansion.default_attrs[:seven].should == :nine
+ expect(expansion.recipes[2]).to eq("three")
+ expect(expansion.recipes[3]).to eq("kitty")
+ expect(expansion.default_attrs[:seven]).to eq(:nine)
end
end
@@ -300,11 +300,11 @@ describe Chef::RunList do
end
it "converts to an array of the string forms of its items" do
- @run_list.to_a.should == ["recipe[nagios::client]", "role[production]", "recipe[apache2]"]
+ expect(@run_list.to_a).to eq(["recipe[nagios::client]", "role[production]", "recipe[apache2]"])
end
it "converts to json by converting its array form" do
- Chef::JSONCompat.to_json(@run_list).should == Chef::JSONCompat.to_json(["recipe[nagios::client]", "role[production]", "recipe[apache2]"])
+ expect(Chef::JSONCompat.to_json(@run_list)).to eq(Chef::JSONCompat.to_json(["recipe[nagios::client]", "role[production]", "recipe[apache2]"]))
end
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
diff --git a/spec/unit/run_lock_spec.rb b/spec/unit/run_lock_spec.rb
index 80140dfcce..51e6ba1b84 100644
--- a/spec/unit/run_lock_spec.rb
+++ b/spec/unit/run_lock_spec.rb
@@ -25,15 +25,15 @@ describe Chef::RunLock do
describe "when first created" do
it "locates the lockfile in the file cache path by default" do
- Chef::Config.stub(:cache_path).and_return(default_cache_path)
+ allow(Chef::Config).to receive(:cache_path).and_return(default_cache_path)
run_lock = Chef::RunLock.new(Chef::Config.lockfile)
- run_lock.runlock_file.should == default_pid_location
+ expect(run_lock.runlock_file).to eq(default_pid_location)
end
it "locates the lockfile in the user-configured path when set" do
Chef::Config.lockfile = "/tmp/chef-client-running.pid"
run_lock = Chef::RunLock.new(Chef::Config.lockfile)
- run_lock.runlock_file.should == "/tmp/chef-client-running.pid"
+ expect(run_lock.runlock_file).to eq("/tmp/chef-client-running.pid")
end
end
@@ -42,20 +42,20 @@ describe Chef::RunLock do
subject(:runlock) { Chef::RunLock.new(lockfile) }
def stub_unblocked_run
- runlock.stub(:test).and_return(true)
+ allow(runlock).to receive(:test).and_return(true)
end
def stub_blocked_run(duration)
- runlock.stub(:test).and_return(false)
- runlock.stub(:wait) { sleep(duration) }
- runlock.stub(:runpid).and_return(666) # errors read blocking pid
+ allow(runlock).to receive(:test).and_return(false)
+ allow(runlock).to receive(:wait) { sleep(duration) }
+ allow(runlock).to receive(:runpid).and_return(666) # errors read blocking pid
end
describe "when Chef::Config[:run_lock_timeout] is not set (set to default)" do
describe "and the lockfile is not locked by another client run" do
it "should not wait" do
stub_unblocked_run
- Chef::RunLock.any_instance.should_not_receive(:wait)
+ expect_any_instance_of(Chef::RunLock).not_to receive(:wait)
runlock.acquire
end
end
@@ -63,7 +63,7 @@ describe Chef::RunLock do
describe "and the lockfile is locked by another client run" do
it "should wait for the lock to be released" do
stub_blocked_run(0.001)
- runlock.should_receive(:wait)
+ expect(runlock).to receive(:wait)
runlock.acquire
end
end
@@ -82,7 +82,7 @@ describe Chef::RunLock do
describe "and the lockfile is not locked by another client run" do
it "should acquire the lock" do
stub_unblocked_run
- runlock.should_not_receive(:wait)
+ expect(runlock).not_to receive(:wait)
runlock.acquire
end
end
@@ -90,7 +90,7 @@ describe Chef::RunLock do
describe "and the lockfile is locked by another client run" do
it "should raise Chef::Exceptions::RunLockTimeout" do
stub_blocked_run(0.001)
- runlock.should_not_receive(:wait)
+ expect(runlock).not_to receive(:wait)
expect{ runlock.acquire }.to raise_error(Chef::Exceptions::RunLockTimeout)
end
end
@@ -110,7 +110,7 @@ describe Chef::RunLock do
describe "and the lockfile is not locked by another client run" do
it "should acquire the lock" do
stub_unblocked_run
- runlock.should_not_receive(:wait)
+ expect(runlock).not_to receive(:wait)
runlock.acquire
end
end
@@ -119,7 +119,7 @@ describe Chef::RunLock do
describe "and the lock is released before the timeout expires" do
it "should acquire the lock" do
stub_blocked_run(@timeout/2.0)
- runlock.should_receive(:wait)
+ expect(runlock).to receive(:wait)
expect{ runlock.acquire }.not_to raise_error
end
end
@@ -127,7 +127,7 @@ describe Chef::RunLock do
describe "and the lock is not released before the timeout expires" do
it "should raise a RunLockTimeout exception" do
stub_blocked_run(2.0)
- runlock.should_receive(:wait)
+ expect(runlock).to receive(:wait)
expect{ runlock.acquire }.to raise_error(Chef::Exceptions::RunLockTimeout)
end
end
diff --git a/spec/unit/run_status_spec.rb b/spec/unit/run_status_spec.rb
index 6c85364871..d658cb5a5a 100644
--- a/spec/unit/run_status_spec.rb
+++ b/spec/unit/run_status_spec.rb
@@ -39,43 +39,43 @@ describe Chef::RunStatus do
end
it "has a run context" do
- @run_status.run_context.should equal(@run_context)
+ expect(@run_status.run_context).to equal(@run_context)
end
it "provides access to the run context's node" do
- @run_status.node.should equal(@node)
+ expect(@run_status.node).to equal(@node)
end
it "converts to a hash" do
- @run_status.to_hash[:node].should equal(@node)
- @run_status.to_hash[:success].should be_true
+ expect(@run_status.to_hash[:node]).to equal(@node)
+ expect(@run_status.to_hash[:success]).to be_truthy
end
describe "after it has recorded timing information" do
before do
@start_time = Time.new
@end_time = @start_time + 23
- Time.stub(:now).and_return(@start_time, @end_time)
+ allow(Time).to receive(:now).and_return(@start_time, @end_time)
@run_status.start_clock
@run_status.stop_clock
end
it "records the start time of the run" do
- @run_status.start_time.should == @start_time
+ expect(@run_status.start_time).to eq(@start_time)
end
it "records the end time of the run" do
- @run_status.end_time.should == @end_time
+ expect(@run_status.end_time).to eq(@end_time)
end
it "gives the elapsed time of the chef run" do
- @run_status.elapsed_time.should == 23
+ expect(@run_status.elapsed_time).to eq(23)
end
it "includes timing information in its hash form" do
- @run_status.to_hash[:start_time].should == @start_time
- @run_status.to_hash[:end_time].should == @end_time
- @run_status.to_hash[:elapsed_time].should == 23
+ expect(@run_status.to_hash[:start_time]).to eq(@start_time)
+ expect(@run_status.to_hash[:end_time]).to eq(@end_time)
+ expect(@run_status.to_hash[:elapsed_time]).to eq(23)
end
end
@@ -87,16 +87,16 @@ describe Chef::RunStatus do
end
it "lists all resources" do
- @run_status.all_resources.should == @all_resources
+ expect(@run_status.all_resources).to eq(@all_resources)
end
it "has no updated resources" do
- @run_status.updated_resources.should be_empty
+ expect(@run_status.updated_resources).to be_empty
end
it "includes the list of all resources in its hash form" do
- @run_status.to_hash[:all_resources].should == @all_resources
- @run_status.to_hash[:updated_resources].should be_empty
+ expect(@run_status.to_hash[:all_resources]).to eq(@all_resources)
+ expect(@run_status.to_hash[:updated_resources]).to be_empty
end
describe "and some have been updated" do
@@ -105,11 +105,11 @@ describe Chef::RunStatus do
end
it "lists the updated resources" do
- @run_status.updated_resources.should == [@all_resources.first]
+ expect(@run_status.updated_resources).to eq([@all_resources.first])
end
it "includes the list of updated resources in its hash form" do
- @run_status.to_hash[:updated_resources].should == [@all_resources.first]
+ expect(@run_status.to_hash[:updated_resources]).to eq([@all_resources.first])
end
end
end
@@ -123,22 +123,22 @@ describe Chef::RunStatus do
end
it "stores the exception" do
- @run_status.exception.should equal(@exception)
+ expect(@run_status.exception).to equal(@exception)
end
it "stores the backtrace" do
- @run_status.backtrace.should == @backtrace
+ expect(@run_status.backtrace).to eq(@backtrace)
end
it "says the run was not successful" do
- @run_status.success?.should be_false
- @run_status.failed?.should be_true
+ expect(@run_status.success?).to be_falsey
+ expect(@run_status.failed?).to be_truthy
end
it "converts to a hash including the exception information" do
- @run_status.to_hash[:success].should be_false
- @run_status.to_hash[:exception].should == "Exception: just testing"
- @run_status.to_hash[:backtrace].should == @backtrace
+ expect(@run_status.to_hash[:success]).to be_falsey
+ expect(@run_status.to_hash[:exception]).to eq("Exception: just testing")
+ expect(@run_status.to_hash[:backtrace]).to eq(@backtrace)
end
end
end
diff --git a/spec/unit/scan_access_control_spec.rb b/spec/unit/scan_access_control_spec.rb
index 48f820ff85..8cf681e994 100644
--- a/spec/unit/scan_access_control_spec.rb
+++ b/spec/unit/scan_access_control_spec.rb
@@ -39,9 +39,9 @@ describe Chef::ScanAccessControl do
end
it "does not set any fields on the current resource" do
- @current_resource.owner.should be_nil
- @current_resource.group.should be_nil
- @current_resource.mode.should be_nil
+ expect(@current_resource.owner).to be_nil
+ expect(@current_resource.group).to be_nil
+ expect(@current_resource.mode).to be_nil
end
end
@@ -50,9 +50,9 @@ describe Chef::ScanAccessControl do
before do
@stat = double("File::Stat for #{@new_resource.path}", :uid => 0, :gid => 0, :mode => 00100644)
- File.should_receive(:realpath).with(@new_resource.path).and_return(@real_file)
- File.should_receive(:stat).with(@real_file).and_return(@stat)
- File.should_receive(:exist?).with(@new_resource.path).and_return(true)
+ expect(File).to receive(:realpath).with(@new_resource.path).and_return(@real_file)
+ expect(File).to receive(:stat).with(@real_file).and_return(@stat)
+ expect(File).to receive(:exist?).with(@new_resource.path).and_return(true)
end
describe "when new_resource does not specify mode, user or group" do
@@ -62,26 +62,26 @@ describe Chef::ScanAccessControl do
end
it "sets the mode of the current resource to the current mode as a String" do
- @current_resource.mode.should == "0644"
+ expect(@current_resource.mode).to eq("0644")
end
context "on unix", :unix_only do
it "sets the group of the current resource to the current group as a String" do
- @current_resource.group.should == Etc.getgrgid(0).name
+ expect(@current_resource.group).to eq(Etc.getgrgid(0).name)
end
it "sets the owner of the current resource to the current owner as a String" do
- @current_resource.user.should == "root"
+ expect(@current_resource.user).to eq("root")
end
end
context "on windows", :windows_only do
it "sets the group of the current resource to the current group as a String" do
- @current_resource.group.should == 0
+ expect(@current_resource.group).to eq(0)
end
it "sets the owner of the current resource to the current owner as a String" do
- @current_resource.user.should == 0
+ expect(@current_resource.user).to eq(0)
end
end
end
@@ -93,7 +93,7 @@ describe Chef::ScanAccessControl do
end
it "sets the mode of the current resource to the file's current mode as a string" do
- @current_resource.mode.should == "0644"
+ expect(@current_resource.mode).to eq("0644")
end
end
@@ -104,7 +104,7 @@ describe Chef::ScanAccessControl do
end
it "sets the mode of the current resource to the current mode as a String" do
- @current_resource.mode.should == "0644"
+ expect(@current_resource.mode).to eq("0644")
end
end
@@ -117,7 +117,7 @@ describe Chef::ScanAccessControl do
end
it "sets the owner of current_resource to the UID of the current owner" do
- @current_resource.user.should == 0
+ expect(@current_resource.user).to eq(0)
end
end
@@ -129,17 +129,17 @@ describe Chef::ScanAccessControl do
it "sets the owner of current_resource to the username of the current owner" do
@root_passwd = double("Struct::Passwd for uid 0", :name => "root")
- Etc.should_receive(:getpwuid).with(0).and_return(@root_passwd)
+ expect(Etc).to receive(:getpwuid).with(0).and_return(@root_passwd)
@scanner.set_all!
- @current_resource.user.should == "root"
+ expect(@current_resource.user).to eq("root")
end
describe "and there is no passwd entry for the user" do
it "sets the owner of the current_resource to the UID" do
- Etc.should_receive(:getpwuid).with(0).and_raise(ArgumentError)
+ expect(Etc).to receive(:getpwuid).with(0).and_raise(ArgumentError)
@scanner.set_all!
- @current_resource.user.should == 0
+ expect(@current_resource.user).to eq(0)
end
end
end
@@ -152,7 +152,7 @@ describe Chef::ScanAccessControl do
end
it "sets the group of the current_resource to the gid of the current owner" do
- @current_resource.group.should == 0
+ expect(@current_resource.group).to eq(0)
end
end
@@ -164,17 +164,17 @@ describe Chef::ScanAccessControl do
it "sets the group of the current resource to the group name" do
@group_entry = double("Struct::Group for wheel", :name => "wheel")
- Etc.should_receive(:getgrgid).with(0).and_return(@group_entry)
+ expect(Etc).to receive(:getgrgid).with(0).and_return(@group_entry)
@scanner.set_all!
- @current_resource.group.should == "wheel"
+ expect(@current_resource.group).to eq("wheel")
end
describe "and there is no group entry for the group" do
it "sets the current_resource's group to the GID" do
- Etc.should_receive(:getgrgid).with(0).and_raise(ArgumentError)
+ expect(Etc).to receive(:getgrgid).with(0).and_raise(ArgumentError)
@scanner.set_all!
- @current_resource.group.should == 0
+ expect(@current_resource.group).to eq(0)
end
end
diff --git a/spec/unit/search/query_spec.rb b/spec/unit/search/query_spec.rb
index c7388a6234..2fb197b183 100644
--- a/spec/unit/search/query_spec.rb
+++ b/spec/unit/search/query_spec.rb
@@ -24,7 +24,7 @@ describe Chef::Search::Query do
let(:query) { Chef::Search::Query.new }
shared_context "filtered search" do
- let(:query_string) { "search/node?q=platform:rhel&sort=X_CHEF_id_CHEF_X%20asc&start=0&rows=1000" }
+ 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) {
@@ -65,11 +65,19 @@ describe Chef::Search::Query do
"total" => 4
}
}
+ let(:response_rows) {
+ [
+ { "env" => "elysium", "ruby_plat" => "nudibranch" },
+ { "env" => "hades", "ruby_plat" => "i386-mingw32"},
+ { "env" => "elysium", "ruby_plat" => "centos"},
+ { "env" => "moon", "ruby_plat" => "solaris2"}
+ ]
+ }
end
before(:each) do
- Chef::REST.stub(:new).and_return(rest)
- rest.stub(:get_rest).and_return(response)
+ allow(Chef::REST).to receive(:new).and_return(rest)
+ allow(rest).to receive(:get_rest).and_return(response)
end
describe "search" do
@@ -132,59 +140,59 @@ describe Chef::Search::Query do
"total" => 4
} }
- it "should accept a type as the first argument" do
- lambda { query.search("node") }.should_not raise_error
- lambda { query.search(:node) }.should_not raise_error
- lambda { query.search(Hash.new) }.should raise_error(Chef::Exceptions::InvalidSearchQuery, /(Hash)/)
+ it "accepts a type as the first argument" do
+ expect { query.search("node") }.not_to raise_error
+ expect { query.search(:node) }.not_to raise_error
+ expect { query.search(Hash.new) }.to raise_error(Chef::Exceptions::InvalidSearchQuery, /(Hash)/)
end
- it "should query for every object of a type by default" do
- rest.should_receive(:get_rest).with("search/node?q=*:*&sort=X_CHEF_id_CHEF_X%20asc&start=0&rows=1000").and_return(response)
+ it "queries for every object of a type by default" do
+ expect(rest).to receive(:get_rest).with("search/node?q=*:*&sort=X_CHEF_id_CHEF_X%20asc&start=0").and_return(response)
query.search(:node)
end
- it "should allow a custom query" do
- rest.should_receive(:get_rest).with("search/node?q=platform:rhel&sort=X_CHEF_id_CHEF_X%20asc&start=0&rows=1000").and_return(response)
+ it "allows a custom query" do
+ expect(rest).to receive(:get_rest).with("search/node?q=platform:rhel&sort=X_CHEF_id_CHEF_X%20asc&start=0").and_return(response)
query.search(:node, "platform:rhel")
end
- it "should let you set a sort order" do
- rest.should_receive(:get_rest).with("search/node?q=platform:rhel&sort=id%20desc&start=0&rows=1000").and_return(response)
- query.search(:node, "platform:rhel", "id desc")
+ it "lets you set a sort order" do
+ expect(rest).to receive(:get_rest).with("search/node?q=platform:rhel&sort=id%20desc&start=0").and_return(response)
+ query.search(:node, "platform:rhel", sort: "id desc")
end
- it "should let you set a starting object" do
- rest.should_receive(:get_rest).with("search/node?q=platform:rhel&sort=id%20desc&start=2&rows=1000").and_return(response)
- query.search(:node, "platform:rhel", "id desc", 2)
+ it "lets you set a starting object" do
+ expect(rest).to receive(:get_rest).with("search/node?q=platform:rhel&sort=X_CHEF_id_CHEF_X%20asc&start=2").and_return(response)
+ query.search(:node, "platform:rhel", start: 2)
end
- it "should let you set how many rows to return" do
- rest.should_receive(:get_rest).with("search/node?q=platform:rhel&sort=id%20desc&start=2&rows=40").and_return(response)
- query.search(:node, "platform:rhel", "id desc", 2, 40)
+ it "lets you set how many rows to return" do
+ expect(rest).to receive(:get_rest).with("search/node?q=platform:rhel&sort=X_CHEF_id_CHEF_X%20asc&start=0&rows=40").and_return(response)
+ query.search(:node, "platform:rhel", rows: 40)
end
- it "should throw an exception if you pass to many options" do
- lambda { query.search(:node, "platform:rhel", "id desc", 2, 40, "wrong") }
- .should raise_error(Chef::Exceptions::InvalidSearchQuery, "Too many arguments! (4 for <= 3)")
+ it "throws an exception if you pass an incorrect option" do
+ expect { query.search(:node, "platform:rhel", total: 10) }
+ .to raise_error(ArgumentError, /unknown keyword: total/)
end
- it "should return the raw rows, start, and total if no block is passed" do
+ it "returns the raw rows, start, and total if no block is passed" do
rows, start, total = query.search(:node)
- rows.should equal(response["rows"])
- start.should equal(response["start"])
- total.should equal(response["total"])
+ expect(rows).to equal(response["rows"])
+ expect(start).to equal(response["start"])
+ expect(total).to equal(response["total"])
end
- it "should call a block for each object in the response" do
+ it "calls a block for each object in the response" do
@call_me = double("blocky")
- response["rows"].each { |r| @call_me.should_receive(:do).with(r) }
+ response["rows"].each { |r| expect(@call_me).to receive(:do).with(r) }
query.search(:node) { |r| @call_me.do(r) }
end
- it "should page through the responses" do
+ it "pages through the responses" do
@call_me = double("blocky")
- response["rows"].each { |r| @call_me.should_receive(:do).with(r) }
- query.search(:node, "*:*", nil, 0, 1) { |r| @call_me.do(r) }
+ response["rows"].each { |r| expect(@call_me).to receive(:do).with(r) }
+ query.search(:node, "*:*", sort: nil, start: 0, rows: 1) { |r| @call_me.do(r) }
end
context "when :filter_result is provided as a result" do
@@ -192,34 +200,22 @@ describe Chef::Search::Query do
let(:filter_key) { :filter_result }
before(:each) do
- rest.should_receive(:post_rest).with(query_string, args[filter_key]).and_return(response)
+ expect(rest).to receive(:post_rest).with(query_string, args[filter_key]).and_return(response)
end
- it "should return start" do
+ it "returns start" do
start = query.search(:node, "platform:rhel", args)[1]
- start.should == response['start']
+ expect(start).to eq(response['start'])
end
- it "should return total" do
+ it "returns total" do
total = query.search(:node, "platform:rhel", args)[2]
- total.should == response['total']
+ expect(total).to eq(response['total'])
end
- it "should return rows with the filter applied" do
- results = query.search(:node, "platform:rhel", args)[0]
-
- results.each_with_index do |result, idx|
- expected = response["rows"][idx]
-
- result.should have_key("url")
- result["url"].should == expected["url"]
-
- result.should have_key("data")
- filter_hash.keys.each do |filter_key|
- result["data"].should have_key(filter_key)
- result["data"][filter_key].should == expected["data"][filter_key]
- end
- end
+ it "returns rows with the filter applied" do
+ filtered_rows = query.search(:node, "platform:rhel", args)[0]
+ expect(filtered_rows).to match_array(response_rows)
end
end
@@ -230,25 +226,17 @@ describe Chef::Search::Query do
include_context "filtered search" do
let(:filter_key) { :keys }
- it "should emit a deprecation warning" do
+ it "emits a deprecation warning" do
# partial_search calls search, so we'll stub search to return empty
- query.stub(:search).and_return( [ [], 0, 0 ] )
- Chef::Log.should_receive(:warn).with("DEPRECATED: The 'partial_search' api is deprecated, please use the search api with 'filter_result'")
+ allow(query).to receive(:search).and_return( [ [], 0, 0 ] )
+ expect(Chef::Log).to receive(:warn).with(/DEPRECATED: The 'partial_search' API is deprecated/)
query.partial_search(:node, "platform:rhel", args)
end
- it "should return an array of filtered hashes" do
- rest.should_receive(:post_rest).with(query_string, args[filter_key]).and_return(response)
+ it "returns an array of filtered hashes" do
+ expect(rest).to receive(:post_rest).with(query_string, args[filter_key]).and_return(response)
results = query.partial_search(:node, "platform:rhel", args)
-
- results.each_with_index do |result, idx|
- expected = response["rows"][idx]
-
- filter_hash.keys.each do |filter_key|
- result.should have_key(filter_key)
- result[filter_key].should == expected["data"][filter_key]
- end
- end
+ expect(results[0]).to match_array(response_rows)
end
end
end
diff --git a/spec/unit/shell/model_wrapper_spec.rb b/spec/unit/shell/model_wrapper_spec.rb
index eae3b2b581..d6da2dcffc 100644
--- a/spec/unit/shell/model_wrapper_spec.rb
+++ b/spec/unit/shell/model_wrapper_spec.rb
@@ -32,12 +32,12 @@ describe Shell::ModelWrapper do
end
it "uses the explicit model symbol" do
- @wrapper.model_symbol.should == :client
+ expect(@wrapper.model_symbol).to eq(:client)
end
end
it "determines the model symbol from the class name" do
- @wrapper.model_symbol.should == :node
+ expect(@wrapper.model_symbol).to eq(:node)
end
describe "when listing objects" do
@@ -48,16 +48,16 @@ describe Shell::ModelWrapper do
@node_2.name("yummy")
@server_response = {:node_1 => @node_1, :node_2 => @node_2}
@wrapper = Shell::ModelWrapper.new(Chef::Node)
- Chef::Node.stub(:list).and_return(@server_response)
+ allow(Chef::Node).to receive(:list).and_return(@server_response)
end
it "lists fully inflated objects without the resource IDs" do
- @wrapper.all.should have(2).nodes
- @wrapper.all.should include(@node_1, @node_2)
+ expect(@wrapper.all.size).to eq(2)
+ expect(@wrapper.all).to include(@node_1, @node_2)
end
it "maps the listed nodes when given a block" do
- @wrapper.all {|n| n.name }.sort.reverse.should == %w{yummy sammich}
+ expect(@wrapper.all {|n| n.name }.sort.reverse).to eq(%w{yummy sammich})
end
end
@@ -72,23 +72,23 @@ describe Shell::ModelWrapper do
# Creating a Chef::Search::Query object tries to read the private key...
@searcher = double("Chef::Search::Query #{__FILE__}:#{__LINE__}")
- Chef::Search::Query.stub(:new).and_return(@searcher)
+ allow(Chef::Search::Query).to receive(:new).and_return(@searcher)
end
it "falls back to listing the objects when the 'query' is :all" do
- Chef::Node.stub(:list).and_return(@server_response)
- @wrapper.find(:all).should include(@node_1, @node_2)
+ allow(Chef::Node).to receive(:list).and_return(@server_response)
+ expect(@wrapper.find(:all)).to include(@node_1, @node_2)
end
it "searches for objects using the given query string" do
- @searcher.should_receive(:search).with(:node, 'name:app*').and_yield(@node_1).and_yield(@node_2)
- @wrapper.find("name:app*").should include(@node_1, @node_2)
+ expect(@searcher).to receive(:search).with(:node, 'name:app*').and_yield(@node_1).and_yield(@node_2)
+ expect(@wrapper.find("name:app*")).to include(@node_1, @node_2)
end
it "creates a 'AND'-joined query string from a HASH" do
# Hash order woes
- @searcher.should_receive(:search).with(:node, 'name:app* AND name:app*').and_yield(@node_1).and_yield(@node_2)
- @wrapper.find(:name=>"app*",'name'=>"app*").should include(@node_1, @node_2)
+ expect(@searcher).to receive(:search).with(:node, 'name:app* AND name:app*').and_yield(@node_1).and_yield(@node_2)
+ expect(@wrapper.find(:name=>"app*",'name'=>"app*")).to include(@node_1, @node_2)
end
end
diff --git a/spec/unit/shell/shell_ext_spec.rb b/spec/unit/shell/shell_ext_spec.rb
index 8485b66d23..9521ae646b 100644
--- a/spec/unit/shell/shell_ext_spec.rb
+++ b/spec/unit/shell/shell_ext_spec.rb
@@ -23,7 +23,7 @@ describe Shell::Extensions do
before do
@shell_client = TestableShellSession.instance
- Shell.stub(:session).and_return(@shell_client)
+ allow(Shell).to receive(:session).and_return(@shell_client)
@job_manager = TestJobManager.new
@root_context = Object.new
@root_context.instance_eval(&ObjectTestHarness)
@@ -37,98 +37,98 @@ describe Shell::Extensions do
irb_context = double("context", :main => target_context_obj)
irb_session = double("irb session", :context => irb_context)
@job_manager.jobs = [[:thread, irb_session]]
- @root_context.stub(:jobs).and_return(@job_manager)
+ allow(@root_context).to receive(:jobs).and_return(@job_manager)
@root_context.ensure_session_select_defined
- @root_context.jobs.select_shell_session(target_context_obj).should == irb_session
- @root_context.jobs.select_shell_session(:idontexist).should be_nil
+ expect(@root_context.jobs.select_shell_session(target_context_obj)).to eq(irb_session)
+ expect(@root_context.jobs.select_shell_session(:idontexist)).to be_nil
end
it "finds, then switches to a session" do
@job_manager.jobs = []
- @root_context.stub(:ensure_session_select_defined)
- @root_context.stub(:jobs).and_return(@job_manager)
- @job_manager.should_receive(:select_shell_session).and_return(:the_shell_session)
- @job_manager.should_receive(:switch).with(:the_shell_session)
+ allow(@root_context).to receive(:ensure_session_select_defined)
+ allow(@root_context).to receive(:jobs).and_return(@job_manager)
+ expect(@job_manager).to receive(:select_shell_session).and_return(:the_shell_session)
+ expect(@job_manager).to receive(:switch).with(:the_shell_session)
@root_context.find_or_create_session_for(:foo)
end
it "creates a new session if an existing one isn't found" do
@job_manager.jobs = []
- @root_context.stub(:jobs).and_return(@job_manager)
- @job_manager.stub(:select_shell_session).and_return(nil)
- @root_context.should_receive(:irb).with(:foo)
+ allow(@root_context).to receive(:jobs).and_return(@job_manager)
+ allow(@job_manager).to receive(:select_shell_session).and_return(nil)
+ expect(@root_context).to receive(:irb).with(:foo)
@root_context.find_or_create_session_for(:foo)
end
it "switches to recipe context" do
- @root_context.should respond_to(:recipe_mode)
+ expect(@root_context).to respond_to(:recipe_mode)
@shell_client.recipe = :monkeyTime
- @root_context.should_receive(:find_or_create_session_for).with(:monkeyTime)
+ expect(@root_context).to receive(:find_or_create_session_for).with(:monkeyTime)
@root_context.recipe_mode
end
it "switches to attribute context" do
- @root_context.should respond_to(:attributes_mode)
+ expect(@root_context).to respond_to(:attributes_mode)
@shell_client.node = "monkeyNodeTime"
- @root_context.should_receive(:find_or_create_session_for).with("monkeyNodeTime")
+ expect(@root_context).to receive(:find_or_create_session_for).with("monkeyNodeTime")
@root_context.attributes_mode
end
it "has a help command" do
- @root_context.should respond_to(:help)
+ expect(@root_context).to respond_to(:help)
end
it "turns irb tracing on and off" do
- @root_context.should respond_to(:trace)
- @root_context.conf.should_receive(:use_tracer=).with(true)
- @root_context.stub(:tracing?)
+ expect(@root_context).to respond_to(:trace)
+ expect(@root_context.conf).to receive(:use_tracer=).with(true)
+ allow(@root_context).to receive(:tracing?)
@root_context.tracing :on
end
it "says if tracing is on or off" do
- @root_context.conf.stub(:use_tracer).and_return(true)
- @root_context.should_receive(:puts).with("tracing is on")
+ allow(@root_context.conf).to receive(:use_tracer).and_return(true)
+ expect(@root_context).to receive(:puts).with("tracing is on")
@root_context.tracing?
end
it "prints node attributes" do
node = double("node", :attribute => {:foo => :bar})
@shell_client.node = node
- @root_context.should_receive(:pp).with({:foo => :bar})
+ expect(@root_context).to receive(:pp).with({:foo => :bar})
@root_context.ohai
- @root_context.should_receive(:pp).with(:bar)
+ expect(@root_context).to receive(:pp).with(:bar)
@root_context.ohai(:foo)
end
it "resets the recipe and reloads ohai data" do
- @shell_client.should_receive(:reset!)
+ expect(@shell_client).to receive(:reset!)
@root_context.reset
end
it "turns irb echo on and off" do
- @root_context.conf.should_receive(:echo=).with(true)
+ expect(@root_context.conf).to receive(:echo=).with(true)
@root_context.echo :on
end
it "says if echo is on or off" do
- @root_context.conf.stub(:echo).and_return(true)
- @root_context.should_receive(:puts).with("echo is on")
+ allow(@root_context.conf).to receive(:echo).and_return(true)
+ expect(@root_context).to receive(:puts).with("echo is on")
@root_context.echo?
end
it "gives access to the stepable iterator" do
- Shell::StandAloneSession.instance.stub(:reset!)
- Shell.session.stub(:rebuild_context)
+ allow(Shell::StandAloneSession.instance).to receive(:reset!)
+ allow(Shell.session).to receive(:rebuild_context)
events = Chef::EventDispatch::Dispatcher.new
run_context = Chef::RunContext.new(Chef::Node.new, {}, events)
run_context.resource_collection.instance_variable_get(:@resource_list).instance_variable_set(:@iterator, :the_iterator)
Shell.session.run_context = run_context
- @root_context.chef_run.should == :the_iterator
+ expect(@root_context.chef_run).to eq(:the_iterator)
end
it "lists directory contents" do
entries = %w{. .. someFile}
- Dir.should_receive(:entries).with("/tmp").and_return(entries)
+ expect(Dir).to receive(:entries).with("/tmp").and_return(entries)
@root_context.ls "/tmp"
end
@@ -145,7 +145,7 @@ describe Shell::Extensions do
it "gives a list of the resources" do
resource = @recipe_object.file("foo")
- @recipe_object.should_receive(:pp).with(["file[foo]"])
+ expect(@recipe_object).to receive(:pp).with(["file[foo]"])
@recipe_object.resources
end
diff --git a/spec/unit/shell/shell_session_spec.rb b/spec/unit/shell/shell_session_spec.rb
index f49c9fc805..d72e3fa1bb 100644
--- a/spec/unit/shell/shell_session_spec.rb
+++ b/spec/unit/shell/shell_session_spec.rb
@@ -42,7 +42,7 @@ end
describe Shell::ShellSession do
it "is a singleton object" do
- Shell::ShellSession.should include(Singleton)
+ expect(Shell::ShellSession).to include(Singleton)
end
end
@@ -66,13 +66,13 @@ describe Shell::ClientSession do
@session.instance_variable_set(:@client, @client)
@expansion = Chef::RunList::RunListExpansion.new(@node.chef_environment, [])
- @node.run_list.should_receive(:expand).with(@node.chef_environment).and_return(@expansion)
- Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(@chef_rest)
+ expect(@node.run_list).to receive(:expand).with(@node.chef_environment).and_return(@expansion)
+ expect(Chef::REST).to receive(:new).with(Chef::Config[:chef_server_url]).and_return(@chef_rest)
@session.rebuild_context
end
it "passes the shell CLI args to the client" do
- Chef::Client.should_receive(:new).with(nil, Chef::Config[:shell_config]).and_return(@client)
+ expect(Chef::Client).to receive(:new).with(nil, Chef::Config[:shell_config]).and_return(@client)
@session.send(:rebuild_node)
end
@@ -90,30 +90,30 @@ describe Shell::StandAloneSession do
end
it "has a run_context" do
- @session.run_context.should equal(@run_context)
+ expect(@session.run_context).to equal(@run_context)
end
it "returns a collection based on it's standalone recipe file" do
- @session.resource_collection.should == @recipe.run_context.resource_collection
+ expect(@session.resource_collection).to eq(@recipe.run_context.resource_collection)
end
it "gives nil for the definitions (for now)" do
- @session.definitions.should be_nil
+ expect(@session.definitions).to be_nil
end
it "gives nil for the cookbook_loader" do
- @session.cookbook_loader.should be_nil
+ expect(@session.cookbook_loader).to be_nil
end
it "runs chef with the standalone recipe" do
- @session.stub(:node_built?).and_return(true)
- Chef::Log.stub(:level)
+ allow(@session).to receive(:node_built?).and_return(true)
+ allow(Chef::Log).to receive(:level)
chef_runner = double("Chef::Runner.new", :converge => :converged)
# pre-heat resource collection cache
@session.resource_collection
- Chef::Runner.should_receive(:new).with(@session.recipe.run_context).and_return(chef_runner)
- @recipe.run_chef.should == :converged
+ expect(Chef::Runner).to receive(:new).with(@session.recipe.run_context).and_return(chef_runner)
+ expect(@recipe.run_chef).to eq(:converged)
end
it "passes the shell CLI args to the client" do
@@ -123,7 +123,7 @@ describe Shell::StandAloneSession do
:build_node => true,
:register => true,
:sync_cookbooks => {})
- Chef::Client.should_receive(:new).with(nil, Chef::Config[:shell_config]).and_return(@client)
+ expect(Chef::Client).to receive(:new).with(nil, Chef::Config[:shell_config]).and_return(@client)
@session.send(:rebuild_node)
end
@@ -147,39 +147,39 @@ describe Shell::SoloSession do
end
it "returns a collection based on it's compilation object and the extra recipe provided by chef-shell" do
- @session.stub(:node_built?).and_return(true)
+ allow(@session).to receive(:node_built?).and_return(true)
kitteh = Chef::Resource::Cat.new("keyboard")
@recipe.run_context.resource_collection << kitteh
- @session.resource_collection.should include(kitteh)
+ expect(@session.resource_collection).to include(kitteh)
end
it "returns definitions from its compilation object" do
- @session.definitions.should == @run_context.definitions
+ expect(@session.definitions).to eq(@run_context.definitions)
end
it "keeps json attribs and passes them to the node for consumption" do
@session.node_attributes = {"besnard_lakes" => "are_the_dark_horse"}
- @session.node.besnard_lakes.should == "are_the_dark_horse"
+ expect(@session.node.besnard_lakes).to eq("are_the_dark_horse")
#pending "1) keep attribs in an ivar 2) pass them to the node 3) feed them to the node on reset"
end
it "generates its resource collection from the compiled cookbooks and the ad hoc recipe" do
- @session.stub(:node_built?).and_return(true)
+ allow(@session).to receive(:node_built?).and_return(true)
kitteh_cat = Chef::Resource::Cat.new("kitteh")
@run_context.resource_collection << kitteh_cat
keyboard_cat = Chef::Resource::Cat.new("keyboard_cat")
@recipe.run_context.resource_collection << keyboard_cat
#@session.rebuild_collection
- @session.resource_collection.should include(kitteh_cat, keyboard_cat)
+ expect(@session.resource_collection).to include(kitteh_cat, keyboard_cat)
end
it "runs chef with a resource collection from the compiled cookbooks" do
- @session.stub(:node_built?).and_return(true)
- Chef::Log.stub(:level)
+ allow(@session).to receive(:node_built?).and_return(true)
+ allow(Chef::Log).to receive(:level)
chef_runner = double("Chef::Runner.new", :converge => :converged)
- Chef::Runner.should_receive(:new).with(an_instance_of(Chef::RunContext)).and_return(chef_runner)
+ expect(Chef::Runner).to receive(:new).with(an_instance_of(Chef::RunContext)).and_return(chef_runner)
- @recipe.run_chef.should == :converged
+ expect(@recipe.run_chef).to eq(:converged)
end
it "passes the shell CLI args to the client" do
@@ -189,7 +189,7 @@ describe Shell::SoloSession do
:build_node => true,
:register => true,
:sync_cookbooks => {})
- Chef::Client.should_receive(:new).with(nil, Chef::Config[:shell_config]).and_return(@client)
+ expect(Chef::Client).to receive(:new).with(nil, Chef::Config[:shell_config]).and_return(@client)
@session.send(:rebuild_node)
end
diff --git a/spec/unit/shell_out_spec.rb b/spec/unit/shell_out_spec.rb
index 1330dd16de..50b0b61cb7 100644
--- a/spec/unit/shell_out_spec.rb
+++ b/spec/unit/shell_out_spec.rb
@@ -2,8 +2,8 @@ require File.expand_path('../../spec_helper', __FILE__)
describe "Chef::ShellOut deprecation notices" do
it "logs a warning when initializing a new Chef::ShellOut object" do
- Chef::Log.should_receive(:warn).with("Chef::ShellOut is deprecated, please use Mixlib::ShellOut")
- Chef::Log.should_receive(:warn).with(/Called from\:/)
+ expect(Chef::Log).to receive(:warn).with("Chef::ShellOut is deprecated, please use Mixlib::ShellOut")
+ expect(Chef::Log).to receive(:warn).with(/Called from\:/)
Chef::ShellOut.new("pwd")
end
end
@@ -11,8 +11,8 @@ end
describe "Chef::Exceptions::ShellCommandFailed deprecation notices" do
it "logs a warning when referencing the constant Chef::Exceptions::ShellCommandFailed" do
- Chef::Log.should_receive(:warn).with("Chef::Exceptions::ShellCommandFailed is deprecated, use Mixlib::ShellOut::ShellCommandFailed")
- Chef::Log.should_receive(:warn).with(/Called from\:/)
+ expect(Chef::Log).to receive(:warn).with("Chef::Exceptions::ShellCommandFailed is deprecated, use Mixlib::ShellOut::ShellCommandFailed")
+ expect(Chef::Log).to receive(:warn).with(/Called from\:/)
Chef::Exceptions::ShellCommandFailed
end
end
diff --git a/spec/unit/shell_spec.rb b/spec/unit/shell_spec.rb
index bf638e1c3a..0e028f4359 100644
--- a/spec/unit/shell_spec.rb
+++ b/spec/unit/shell_spec.rb
@@ -42,13 +42,13 @@ describe Shell do
before do
Shell.irb_conf = {}
- Shell::ShellSession.instance.stub(:reset!)
+ allow(Shell::ShellSession.instance).to receive(:reset!)
end
describe "reporting its status" do
- it "alway says it is running" do
- Shell.should be_running
+ it "always says it is running" do
+ expect(Shell).to be_running
end
end
@@ -56,8 +56,8 @@ describe Shell do
describe "configuring IRB" do
it "configures irb history" do
Shell.configure_irb
- Shell.irb_conf[:HISTORY_FILE].should == "~/.chef/chef_shell_history"
- Shell.irb_conf[:SAVE_HISTORY].should == 1000
+ expect(Shell.irb_conf[:HISTORY_FILE]).to eq("~/.chef/chef_shell_history")
+ expect(Shell.irb_conf[:SAVE_HISTORY]).to eq(1000)
end
it "has a prompt like ``chef > '' in the default context" do
@@ -67,12 +67,12 @@ describe Shell do
conf.main = Object.new
conf.main.instance_eval(&ObjectTestHarness)
Shell.irb_conf[:IRB_RC].call(conf)
- conf.prompt_c.should == "chef > "
- conf.return_format.should == " => %s \n"
- conf.prompt_i.should == "chef > "
- conf.prompt_n.should == "chef ?> "
- conf.prompt_s.should == "chef%l> "
- conf.use_tracer.should == false
+ expect(conf.prompt_c).to eq("chef > ")
+ expect(conf.return_format).to eq(" => %s \n")
+ expect(conf.prompt_i).to eq("chef > ")
+ expect(conf.prompt_n).to eq("chef ?> ")
+ expect(conf.prompt_s).to eq("chef%l> ")
+ expect(conf.use_tracer).to eq(false)
end
it "has a prompt like ``chef:recipe > '' in recipe context" do
@@ -82,10 +82,10 @@ describe Shell do
events = Chef::EventDispatch::Dispatcher.new
conf.main = Chef::Recipe.new(nil,nil,Chef::RunContext.new(Chef::Node.new, {}, events))
Shell.irb_conf[:IRB_RC].call(conf)
- conf.prompt_c.should == "chef:recipe > "
- conf.prompt_i.should == "chef:recipe > "
- conf.prompt_n.should == "chef:recipe ?> "
- conf.prompt_s.should == "chef:recipe%l> "
+ expect(conf.prompt_c).to eq("chef:recipe > ")
+ expect(conf.prompt_i).to eq("chef:recipe > ")
+ expect(conf.prompt_n).to eq("chef:recipe ?> ")
+ expect(conf.prompt_s).to eq("chef:recipe%l> ")
end
it "has a prompt like ``chef:attributes > '' in attributes/node context" do
@@ -94,10 +94,10 @@ describe Shell do
conf = OpenStruct.new
conf.main = Chef::Node.new
Shell.irb_conf[:IRB_RC].call(conf)
- conf.prompt_c.should == "chef:attributes > "
- conf.prompt_i.should == "chef:attributes > "
- conf.prompt_n.should == "chef:attributes ?> "
- conf.prompt_s.should == "chef:attributes%l> "
+ expect(conf.prompt_c).to eq("chef:attributes > ")
+ expect(conf.prompt_i).to eq("chef:attributes > ")
+ expect(conf.prompt_n).to eq("chef:attributes ?> ")
+ expect(conf.prompt_s).to eq("chef:attributes%l> ")
end
end
@@ -110,7 +110,7 @@ describe Shell do
end
it "creates help text for methods with descriptions" do
- @chef_object.help_descriptions.should == [Shell::Extensions::Help.new("rspec_method", "rspecin'", nil)]
+ expect(@chef_object.help_descriptions).to eq([Shell::Extensions::Help.new("rspec_method", "rspecin'", nil)])
end
it "adds help text when a new method is described then defined" do
@@ -120,8 +120,8 @@ describe Shell do
end
EVAL
@chef_object.instance_eval describe_define
- @chef_object.help_descriptions.should == [Shell::Extensions::Help.new("rspec_method", "rspecin'"),
- Shell::Extensions::Help.new("baz", "foo2the Bar")]
+ expect(@chef_object.help_descriptions).to eq([Shell::Extensions::Help.new("rspec_method", "rspecin'"),
+ Shell::Extensions::Help.new("baz", "foo2the Bar")])
end
it "adds help text for subcommands" do
@@ -133,7 +133,7 @@ describe Shell do
@chef_object.instance_eval describe_define
expected_help_text_fragments = [Shell::Extensions::Help.new("rspec_method", "rspecin'")]
expected_help_text_fragments << Shell::Extensions::Help.new("baz.baz_obj_command", "something you can do with baz.baz_obj_command")
- @chef_object.help_descriptions.should == expected_help_text_fragments
+ expect(@chef_object.help_descriptions).to eq(expected_help_text_fragments)
end
it "doesn't add previous subcommand help to commands defined afterward" do
@@ -147,13 +147,13 @@ describe Shell do
EVAL
@chef_object.instance_eval describe_define
- @chef_object.help_descriptions.should have(2).descriptions
- @chef_object.help_descriptions.select {|h| h.cmd == "super_monkey_time" }.should be_empty
+ expect(@chef_object.help_descriptions.size).to eq(2)
+ expect(@chef_object.help_descriptions.select {|h| h.cmd == "super_monkey_time" }).to be_empty
end
it "creates a help banner with the command descriptions" do
- @chef_object.help_banner.should match(/^\|\ Command[\s]+\|\ Description[\s]*$/)
- @chef_object.help_banner.should match(/^\|\ rspec_method[\s]+\|\ rspecin\'[\s]*$/)
+ expect(@chef_object.help_banner).to match(/^\|\ Command[\s]+\|\ Description[\s]*$/)
+ expect(@chef_object.help_banner).to match(/^\|\ rspec_method[\s]+\|\ rspecin\'[\s]*$/)
end
end
diff --git a/spec/unit/user_spec.rb b/spec/unit/user_spec.rb
index 2f2299c5bd..d451531b16 100644
--- a/spec/unit/user_spec.rb
+++ b/spec/unit/user_spec.rb
@@ -28,89 +28,89 @@ describe Chef::User do
describe "initialize" do
it "should be a Chef::User" do
- @user.should be_a_kind_of(Chef::User)
+ expect(@user).to be_a_kind_of(Chef::User)
end
end
describe "name" do
it "should let you set the name to a string" do
- @user.name("ops_master").should == "ops_master"
+ expect(@user.name("ops_master")).to eq("ops_master")
end
it "should return the current name" do
@user.name "ops_master"
- @user.name.should == "ops_master"
+ expect(@user.name).to eq("ops_master")
end
# It is not feasible to check all invalid characters. Here are a few
# that we probably care about.
it "should not accept invalid characters" do
# capital letters
- lambda { @user.name "Bar" }.should raise_error(ArgumentError)
+ expect { @user.name "Bar" }.to raise_error(ArgumentError)
# slashes
- lambda { @user.name "foo/bar" }.should raise_error(ArgumentError)
+ expect { @user.name "foo/bar" }.to raise_error(ArgumentError)
# ?
- lambda { @user.name "foo?" }.should raise_error(ArgumentError)
+ expect { @user.name "foo?" }.to raise_error(ArgumentError)
# &
- lambda { @user.name "foo&" }.should raise_error(ArgumentError)
+ expect { @user.name "foo&" }.to raise_error(ArgumentError)
end
it "should not accept spaces" do
- lambda { @user.name "ops master" }.should raise_error(ArgumentError)
+ expect { @user.name "ops master" }.to raise_error(ArgumentError)
end
it "should throw an ArgumentError if you feed it anything but a string" do
- lambda { @user.name Hash.new }.should raise_error(ArgumentError)
+ expect { @user.name Hash.new }.to raise_error(ArgumentError)
end
end
describe "admin" do
it "should let you set the admin bit" do
- @user.admin(true).should == true
+ expect(@user.admin(true)).to eq(true)
end
it "should return the current admin value" do
@user.admin true
- @user.admin.should == true
+ expect(@user.admin).to eq(true)
end
it "should default to false" do
- @user.admin.should == false
+ expect(@user.admin).to eq(false)
end
it "should throw an ArgumentError if you feed it anything but true or false" do
- lambda { @user.name Hash.new }.should raise_error(ArgumentError)
+ expect { @user.name Hash.new }.to raise_error(ArgumentError)
end
end
describe "public_key" do
it "should let you set the public key" do
- @user.public_key("super public").should == "super public"
+ expect(@user.public_key("super public")).to eq("super public")
end
it "should return the current public key" do
@user.public_key("super public")
- @user.public_key.should == "super public"
+ expect(@user.public_key).to eq("super public")
end
it "should throw an ArgumentError if you feed it something lame" do
- lambda { @user.public_key Hash.new }.should raise_error(ArgumentError)
+ expect { @user.public_key Hash.new }.to raise_error(ArgumentError)
end
end
describe "private_key" do
it "should let you set the private key" do
- @user.private_key("super private").should == "super private"
+ expect(@user.private_key("super private")).to eq("super private")
end
it "should return the private key" do
@user.private_key("super private")
- @user.private_key.should == "super private"
+ expect(@user.private_key).to eq("super private")
end
it "should throw an ArgumentError if you feed it something lame" do
- lambda { @user.private_key Hash.new }.should raise_error(ArgumentError)
+ expect { @user.private_key Hash.new }.to raise_error(ArgumentError)
end
end
@@ -122,37 +122,37 @@ describe Chef::User do
end
it "serializes as a JSON object" do
- @json.should match(/^\{.+\}$/)
+ expect(@json).to match(/^\{.+\}$/)
end
it "includes the name value" do
- @json.should include(%q{"name":"black"})
+ expect(@json).to include(%q{"name":"black"})
end
it "includes the public key value" do
- @json.should include(%{"public_key":"crowes"})
+ expect(@json).to include(%{"public_key":"crowes"})
end
it "includes the 'admin' flag" do
- @json.should include(%q{"admin":false})
+ expect(@json).to include(%q{"admin":false})
end
it "includes the private key when present" do
@user.private_key("monkeypants")
- @user.to_json.should include(%q{"private_key":"monkeypants"})
+ expect(@user.to_json).to include(%q{"private_key":"monkeypants"})
end
it "does not include the private key if not present" do
- @json.should_not include("private_key")
+ expect(@json).not_to include("private_key")
end
it "includes the password if present" do
@user.password "password"
- @user.to_json.should include(%q{"password":"password"})
+ expect(@user.to_json).to include(%q{"password":"password"})
end
it "does not include the password if not present" do
- @json.should_not include("password")
+ expect(@json).not_to include("password")
end
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
@@ -171,27 +171,27 @@ describe Chef::User do
end
it "should deserialize to a Chef::User object" do
- @user.should be_a_kind_of(Chef::User)
+ expect(@user).to be_a_kind_of(Chef::User)
end
it "preserves the name" do
- @user.name.should == "mr_spinks"
+ expect(@user.name).to eq("mr_spinks")
end
it "preserves the public key" do
- @user.public_key.should == "turtles"
+ expect(@user.public_key).to eq("turtles")
end
it "preserves the admin status" do
- @user.admin.should be_true
+ expect(@user.admin).to be_truthy
end
it "includes the private key if present" do
- @user.private_key.should == "pandas"
+ expect(@user.private_key).to eq("pandas")
end
it "includes the password if present" do
- @user.password.should == "password"
+ expect(@user.password).to eq("password")
end
end
@@ -201,7 +201,7 @@ describe Chef::User do
@user = Chef::User.new
@user.name "foobar"
@http_client = double("Chef::REST mock")
- Chef::REST.stub(:new).and_return(@http_client)
+ allow(Chef::REST).to receive(:new).and_return(@http_client)
end
describe "list" do
@@ -209,61 +209,61 @@ describe Chef::User do
Chef::Config[:chef_server_url] = "http://www.example.com"
@osc_response = { "admin" => "http://www.example.com/users/admin"}
@ohc_response = [ { "user" => { "username" => "admin" }} ]
- Chef::User.stub(:load).with("admin").and_return(@user)
+ allow(Chef::User).to receive(:load).with("admin").and_return(@user)
@osc_inflated_response = { "admin" => @user }
end
it "lists all clients on an OSC server" do
- @http_client.stub(:get_rest).with("users").and_return(@osc_response)
- Chef::User.list.should == @osc_response
+ allow(@http_client).to receive(:get_rest).with("users").and_return(@osc_response)
+ expect(Chef::User.list).to eq(@osc_response)
end
it "inflate all clients on an OSC server" do
- @http_client.stub(:get_rest).with("users").and_return(@osc_response)
- Chef::User.list(true).should == @osc_inflated_response
+ allow(@http_client).to receive(:get_rest).with("users").and_return(@osc_response)
+ expect(Chef::User.list(true)).to eq(@osc_inflated_response)
end
it "lists all clients on an OHC/OPC server" do
- @http_client.stub(:get_rest).with("users").and_return(@ohc_response)
+ allow(@http_client).to receive(:get_rest).with("users").and_return(@ohc_response)
# We expect that Chef::User.list will give a consistent response
# so OHC API responses should be transformed to OSC-style output.
- Chef::User.list.should == @osc_response
+ expect(Chef::User.list).to eq(@osc_response)
end
it "inflate all clients on an OHC/OPC server" do
- @http_client.stub(:get_rest).with("users").and_return(@ohc_response)
- Chef::User.list(true).should == @osc_inflated_response
+ allow(@http_client).to receive(:get_rest).with("users").and_return(@ohc_response)
+ expect(Chef::User.list(true)).to eq(@osc_inflated_response)
end
end
describe "create" do
it "creates a new user via the API" do
@user.password "password"
- @http_client.should_receive(:post_rest).with("users", {:name => "foobar", :admin => false, :password => "password"}).and_return({})
+ expect(@http_client).to receive(:post_rest).with("users", {:name => "foobar", :admin => false, :password => "password"}).and_return({})
@user.create
end
end
describe "read" do
it "loads a named user from the API" do
- @http_client.should_receive(:get_rest).with("users/foobar").and_return({"name" => "foobar", "admin" => true, "public_key" => "pubkey"})
+ expect(@http_client).to receive(:get_rest).with("users/foobar").and_return({"name" => "foobar", "admin" => true, "public_key" => "pubkey"})
user = Chef::User.load("foobar")
- user.name.should == "foobar"
- user.admin.should == true
- user.public_key.should == "pubkey"
+ expect(user.name).to eq("foobar")
+ expect(user.admin).to eq(true)
+ expect(user.public_key).to eq("pubkey")
end
end
describe "update" do
it "updates an existing user on via the API" do
- @http_client.should_receive(:put_rest).with("users/foobar", {:name => "foobar", :admin => false}).and_return({})
+ expect(@http_client).to receive(:put_rest).with("users/foobar", {:name => "foobar", :admin => false}).and_return({})
@user.update
end
end
describe "destroy" do
it "deletes the specified user via the API" do
- @http_client.should_receive(:delete_rest).with("users/foobar")
+ expect(@http_client).to receive(:delete_rest).with("users/foobar")
@user.destroy
end
end
diff --git a/spec/unit/util/backup_spec.rb b/spec/unit/util/backup_spec.rb
index 617886cede..f548e8241d 100644
--- a/spec/unit/util/backup_spec.rb
+++ b/spec/unit/util/backup_spec.rb
@@ -28,33 +28,33 @@ describe Chef::Util::Backup do
before(:each) do
@new_resource = double("new_resource")
- @new_resource.should_receive(:path).at_least(:once).and_return(tempfile.path)
+ expect(@new_resource).to receive(:path).at_least(:once).and_return(tempfile.path)
@backup = Chef::Util::Backup.new(@new_resource)
end
it "should store the resource passed to new as new_resource" do
- @backup.new_resource.should eql(@new_resource)
+ expect(@backup.new_resource).to eql(@new_resource)
end
describe "for cases when we don't want to back anything up" do
before(:each) do
- @backup.should_not_receive(:do_backup)
+ expect(@backup).not_to receive(:do_backup)
end
it "should not attempt to backup a file if :backup is false" do
- @new_resource.should_receive(:backup).at_least(:once).and_return(false)
+ expect(@new_resource).to receive(:backup).at_least(:once).and_return(false)
@backup.backup!
end
it "should not attempt to backup a file if :backup == 0" do
- @new_resource.should_receive(:backup).at_least(:once).and_return(0)
+ expect(@new_resource).to receive(:backup).at_least(:once).and_return(0)
@backup.backup!
end
it "should not attempt to backup a file if it does not exist" do
- @new_resource.should_receive(:backup).at_least(:once).and_return(1)
- File.should_receive(:exist?).with(tempfile.path).at_least(:once).and_return(false)
+ expect(@new_resource).to receive(:backup).at_least(:once).and_return(1)
+ expect(File).to receive(:exist?).with(tempfile.path).at_least(:once).and_return(false)
@backup.backup!
end
@@ -62,43 +62,43 @@ describe Chef::Util::Backup do
describe "for cases when we want to back things up" do
before(:each) do
- @backup.should_receive(:do_backup)
+ expect(@backup).to receive(:do_backup)
end
describe "when the number of backups is specified as 1" do
before(:each) do
- @new_resource.should_receive(:backup).at_least(:once).and_return(1)
+ expect(@new_resource).to receive(:backup).at_least(:once).and_return(1)
end
it "should not delete anything if this is the only backup" do
- @backup.should_receive(:sorted_backup_files).and_return(['a'])
- @backup.should_not_receive(:delete_backup)
+ expect(@backup).to receive(:sorted_backup_files).and_return(['a'])
+ expect(@backup).not_to receive(:delete_backup)
@backup.backup!
end
it "should keep only 1 backup copy" do
- @backup.should_receive(:sorted_backup_files).and_return(['a', 'b', 'c'])
- @backup.should_receive(:delete_backup).with('b')
- @backup.should_receive(:delete_backup).with('c')
+ expect(@backup).to receive(:sorted_backup_files).and_return(['a', 'b', 'c'])
+ expect(@backup).to receive(:delete_backup).with('b')
+ expect(@backup).to receive(:delete_backup).with('c')
@backup.backup!
end
end
describe "when the number of backups is specified as 2" do
before(:each) do
- @new_resource.should_receive(:backup).at_least(:once).and_return(2)
+ expect(@new_resource).to receive(:backup).at_least(:once).and_return(2)
end
it "should not delete anything if we only have one other backup" do
- @backup.should_receive(:sorted_backup_files).and_return(['a', 'b'])
- @backup.should_not_receive(:delete_backup)
+ expect(@backup).to receive(:sorted_backup_files).and_return(['a', 'b'])
+ expect(@backup).not_to receive(:delete_backup)
@backup.backup!
end
it "should keep only 2 backup copies" do
- @backup.should_receive(:sorted_backup_files).and_return(['a', 'b', 'c', 'd'])
- @backup.should_receive(:delete_backup).with('c')
- @backup.should_receive(:delete_backup).with('d')
+ expect(@backup).to receive(:sorted_backup_files).and_return(['a', 'b', 'c', 'd'])
+ expect(@backup).to receive(:delete_backup).with('c')
+ expect(@backup).to receive(:delete_backup).with('d')
@backup.backup!
end
end
@@ -106,36 +106,36 @@ describe Chef::Util::Backup do
describe "backup_filename" do
it "should return a timestamped path" do
- @backup.should_receive(:path).and_return('/a/b/c.txt')
- @backup.send(:backup_filename).should =~ %r|^/a/b/c.txt.chef-\d{14}.\d{6}$|
+ expect(@backup).to receive(:path).and_return('/a/b/c.txt')
+ expect(@backup.send(:backup_filename)).to match(%r|^/a/b/c.txt.chef-\d{14}.\d{6}$|)
end
it "should strip the drive letter off for windows" do
- @backup.should_receive(:path).and_return('c:\a\b\c.txt')
- @backup.send(:backup_filename).should =~ %r|^\\a\\b\\c.txt.chef-\d{14}.\d{6}$|
+ expect(@backup).to receive(:path).and_return('c:\a\b\c.txt')
+ expect(@backup.send(:backup_filename)).to match(%r|^\\a\\b\\c.txt.chef-\d{14}.\d{6}$|)
end
it "should strip the drive letter off for windows (with forwardslashes)" do
- @backup.should_receive(:path).and_return('c:/a/b/c.txt')
- @backup.send(:backup_filename).should =~ %r|^/a/b/c.txt.chef-\d{14}.\d{6}$|
+ expect(@backup).to receive(:path).and_return('c:/a/b/c.txt')
+ expect(@backup.send(:backup_filename)).to match(%r|^/a/b/c.txt.chef-\d{14}.\d{6}$|)
end
end
describe "backup_path" do
it "uses the file's directory when Chef::Config[:file_backup_path] is nil" do
- @backup.should_receive(:path).and_return('/a/b/c.txt')
+ expect(@backup).to receive(:path).and_return('/a/b/c.txt')
Chef::Config[:file_backup_path] = nil
- @backup.send(:backup_path).should =~ %r|^/a/b/c.txt.chef-\d{14}.\d{6}$|
+ expect(@backup.send(:backup_path)).to match(%r|^/a/b/c.txt.chef-\d{14}.\d{6}$|)
end
it "uses the configured Chef::Config[:file_backup_path]" do
- @backup.should_receive(:path).and_return('/a/b/c.txt')
+ expect(@backup).to receive(:path).and_return('/a/b/c.txt')
Chef::Config[:file_backup_path] = '/backupdir'
- @backup.send(:backup_path).should =~ %r|^/backupdir[\\/]+a/b/c.txt.chef-\d{14}.\d{6}$|
+ expect(@backup.send(:backup_path)).to match(%r|^/backupdir[\\/]+a/b/c.txt.chef-\d{14}.\d{6}$|)
end
it "uses the configured Chef::Config[:file_backup_path] and strips the drive on windows" do
- @backup.should_receive(:path).and_return('c:\\a\\b\\c.txt')
+ expect(@backup).to receive(:path).and_return('c:\\a\\b\\c.txt')
Chef::Config[:file_backup_path] = 'c:\backupdir'
- @backup.send(:backup_path).should =~ %r|^c:\\backupdir[\\/]+a\\b\\c.txt.chef-\d{14}.\d{6}$|
+ expect(@backup.send(:backup_path)).to match(%r|^c:\\backupdir[\\/]+a\\b\\c.txt.chef-\d{14}.\d{6}$|)
end
end
diff --git a/spec/unit/util/diff_spec.rb b/spec/unit/util/diff_spec.rb
index 947ce1d5aa..b0a57a32c0 100644
--- a/spec/unit/util/diff_spec.rb
+++ b/spec/unit/util/diff_spec.rb
@@ -105,7 +105,7 @@ shared_examples_for "a diff util" do
end
end
- describe "when the default external encoding is UTF-8", :ruby_gte_19_only do
+ describe "when the default external encoding is UTF-8" do
before do
@saved_default_external = Encoding.default_external
@@ -122,7 +122,7 @@ shared_examples_for "a diff util" do
new_tempfile.close
end
it "calling for_output should return a valid diff" do
- differ.for_output.join("\\n").should match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
+ expect(differ.for_output.join("\\n")).to match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
end
it "calling for_reporting should return a utf-8 string" do
expect(differ.for_reporting.encoding).to equal(Encoding::UTF_8)
@@ -135,7 +135,7 @@ shared_examples_for "a diff util" do
new_tempfile.close
end
it "calling for_output should return a valid diff" do
- differ.for_output.join("\\n").should match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
+ expect(differ.for_output.join("\\n")).to match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
end
it "calling for_reporting should return a utf-8 string" do
expect(differ.for_reporting.encoding).to equal(Encoding::UTF_8)
@@ -170,7 +170,7 @@ shared_examples_for "a diff util" do
end
- describe "when the default external encoding is Latin-1", :ruby_gte_19_only do
+ describe "when the default external encoding is Latin-1" do
before do
@saved_default_external = Encoding.default_external
@@ -187,7 +187,7 @@ shared_examples_for "a diff util" do
new_tempfile.close
end
it "calling for_output should return a valid diff" do
- differ.for_output.join("\\n").should match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
+ expect(differ.for_output.join("\\n")).to match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
end
it "calling for_reporting should return a utf-8 string" do
expect(differ.for_reporting.encoding).to equal(Encoding::UTF_8)
@@ -213,7 +213,7 @@ shared_examples_for "a diff util" do
new_tempfile.close
end
it "calling for_output should return a valid diff" do
- differ.for_output.join("\\n").should match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
+ expect(differ.for_output.join("\\n")).to match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
end
it "calling for_reporting should return a utf-8 string" do
expect(differ.for_reporting.encoding).to equal(Encoding::UTF_8)
@@ -234,7 +234,7 @@ shared_examples_for "a diff util" do
end
end
- describe "when the default external encoding is Shift_JIS", :ruby_gte_19_only do
+ describe "when the default external encoding is Shift_JIS" do
before do
@saved_default_external = Encoding.default_external
@@ -251,7 +251,7 @@ shared_examples_for "a diff util" do
new_tempfile.close
end
it "calling for_output should return a valid diff" do
- differ.for_output.join("\\n").should match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
+ expect(differ.for_output.join("\\n")).to match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
end
it "calling for_reporting should return a utf-8 string" do
expect(differ.for_reporting.encoding).to equal(Encoding::UTF_8)
@@ -290,7 +290,7 @@ shared_examples_for "a diff util" do
new_tempfile.close
end
it "calling for_output should return a valid diff" do
- differ.for_output.join("\\n").should match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
+ expect(differ.for_output.join("\\n")).to match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
end
it "calling for_reporting should return a utf-8 string" do
expect(differ.for_reporting.encoding).to equal(Encoding::UTF_8)
@@ -349,12 +349,12 @@ shared_examples_for "a diff util" do
end
it "calling for_output should return a unified diff" do
- differ.for_output.size.should eql(5)
- differ.for_output.join("\\n").should match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
+ expect(differ.for_output.size).to eql(5)
+ expect(differ.for_output.join("\\n")).to match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
end
it "calling for_reporting should return a unified diff" do
- differ.for_reporting.should match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
+ expect(differ.for_reporting).to match(/\A--- .*\\n\+\+\+ .*\\n@@/m)
end
describe "when the diff output is too long" do
@@ -383,7 +383,7 @@ shared_examples_for "a diff util" do
it "should identify zero-length files as text" do
Tempfile.open("chef-util-diff-spec") do |file|
file.close
- differ.send(:is_binary?, file.path).should be_false
+ expect(differ.send(:is_binary?, file.path)).to be_falsey
end
end
@@ -391,7 +391,7 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(plain_ascii)
file.close
- differ.send(:is_binary?, file.path).should be_false
+ expect(differ.send(:is_binary?, file.path)).to be_falsey
end
end
@@ -399,7 +399,7 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write("This is a binary file.\0")
file.close
- differ.send(:is_binary?, file.path).should be_true
+ expect(differ.send(:is_binary?, file.path)).to be_truthy
end
end
@@ -407,11 +407,11 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write("This is a binary file.\nNo Really\nit is\0")
file.close
- differ.send(:is_binary?, file.path).should be_true
+ expect(differ.send(:is_binary?, file.path)).to be_truthy
end
end
- describe "when the default external encoding is UTF-8", :ruby_gte_19_only do
+ describe "when the default external encoding is UTF-8" do
before do
@saved_default_external = Encoding.default_external
@@ -426,7 +426,7 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(plain_ascii)
file.close
- differ.send(:is_binary?, file.path).should be_false
+ expect(differ.send(:is_binary?, file.path)).to be_falsey
end
end
@@ -434,7 +434,7 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(utf_8)
file.close
- differ.send(:is_binary?, file.path).should be_false
+ expect(differ.send(:is_binary?, file.path)).to be_falsey
end
end
@@ -442,7 +442,7 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(latin_1)
file.close
- differ.send(:is_binary?, file.path).should be_true
+ expect(differ.send(:is_binary?, file.path)).to be_truthy
end
end
@@ -450,13 +450,13 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(shift_jis)
file.close
- differ.send(:is_binary?, file.path).should be_true
+ expect(differ.send(:is_binary?, file.path)).to be_truthy
end
end
end
- describe "when the default external encoding is Latin-1", :ruby_gte_19_only do
+ describe "when the default external encoding is Latin-1" do
before do
@saved_default_external = Encoding.default_external
@@ -471,7 +471,7 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(plain_ascii)
file.close
- differ.send(:is_binary?, file.path).should be_false
+ expect(differ.send(:is_binary?, file.path)).to be_falsey
end
end
@@ -479,7 +479,7 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(utf_8)
file.close
- differ.send(:is_binary?, file.path).should be_true
+ expect(differ.send(:is_binary?, file.path)).to be_truthy
end
end
@@ -487,7 +487,7 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(latin_1)
file.close
- differ.send(:is_binary?, file.path).should be_false
+ expect(differ.send(:is_binary?, file.path)).to be_falsey
end
end
@@ -495,12 +495,12 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(shift_jis)
file.close
- differ.send(:is_binary?, file.path).should be_true
+ expect(differ.send(:is_binary?, file.path)).to be_truthy
end
end
end
- describe "when the default external encoding is Shift-JIS", :ruby_gte_19_only do
+ describe "when the default external encoding is Shift-JIS" do
before do
@saved_default_external = Encoding.default_external
@@ -515,14 +515,14 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(plain_ascii)
file.close
- differ.send(:is_binary?, file.path).should be_false
+ expect(differ.send(:is_binary?, file.path)).to be_falsey
end
end
it "should identify UTF-8 that is invalid Shift-JIS as binary" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(utf_8)
file.close
- differ.send(:is_binary?, file.path).should be_true
+ expect(differ.send(:is_binary?, file.path)).to be_truthy
end
end
@@ -530,7 +530,7 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(latin_1)
file.close
- differ.send(:is_binary?, file.path).should be_true
+ expect(differ.send(:is_binary?, file.path)).to be_truthy
end
end
@@ -538,7 +538,7 @@ shared_examples_for "a diff util" do
Tempfile.open("chef-util-diff-spec") do |file|
file.write(shift_jis)
file.close
- differ.send(:is_binary?, file.path).should be_false
+ expect(differ.send(:is_binary?, file.path)).to be_falsey
end
end
diff --git a/spec/unit/util/dsc/configuration_generator_spec.rb b/spec/unit/util/dsc/configuration_generator_spec.rb
index 03f3ffe25c..9fbd3aaa51 100644
--- a/spec/unit/util/dsc/configuration_generator_spec.rb
+++ b/spec/unit/util/dsc/configuration_generator_spec.rb
@@ -51,9 +51,9 @@ describe Chef::Util::DSC::ConfigurationGenerator do
context 'when strings are used as switches' do
it 'should merge the hash if there are no restricted switches' do
merged = conf_man.send(:get_merged_configuration_flags!, {'flag' => 'a'}, 'hello')
- merged.should include(:flag)
- merged[:flag].should eql('a')
- merged.should include(:outputpath)
+ expect(merged).to include(:flag)
+ expect(merged[:flag]).to eql('a')
+ expect(merged).to include(:outputpath)
end
it 'should raise an ArgumentError if you try to override outputpath' do
@@ -70,16 +70,16 @@ describe Chef::Util::DSC::ConfigurationGenerator do
it 'should be case insensitive to switches that are allowed' do
merged = conf_man.send(:get_merged_configuration_flags!, {'FLAG' => 'a'}, 'hello')
- merged.should include(:flag)
+ expect(merged).to include(:flag)
end
end
context 'when symbols are used as switches' do
it 'should merge the hash if there are no restricted switches' do
merged = conf_man.send(:get_merged_configuration_flags!, {:flag => 'a'}, 'hello')
- merged.should include(:flag)
- merged[:flag].should eql('a')
- merged.should include(:outputpath)
+ expect(merged).to include(:flag)
+ expect(merged[:flag]).to eql('a')
+ expect(merged).to include(:outputpath)
end
it 'should raise an ArgumentError if you try to override outputpath' do
@@ -96,21 +96,21 @@ describe Chef::Util::DSC::ConfigurationGenerator do
it 'should be case insensitive to switches that are allowed' do
merged = conf_man.send(:get_merged_configuration_flags!, {:FLAG => 'a'}, 'hello')
- merged.should include(:flag)
+ expect(merged).to include(:flag)
end
end
context 'when there are no flags' do
it 'should supply an output path if configuration_flags is an empty hash' do
merged = conf_man.send(:get_merged_configuration_flags!, {}, 'hello')
- merged.should include(:outputpath)
- merged.length.should eql(1)
+ expect(merged).to include(:outputpath)
+ expect(merged.length).to eql(1)
end
it 'should supply an output path if configuration_flags is an empty hash' do
merged = conf_man.send(:get_merged_configuration_flags!, nil, 'hello')
- merged.should include(:outputpath)
- merged.length.should eql(1)
+ expect(merged).to include(:outputpath)
+ expect(merged.length).to eql(1)
end
end
@@ -130,14 +130,14 @@ describe Chef::Util::DSC::ConfigurationGenerator do
[a,b].join("++")
end
allow(file_like_object).to receive(:write)
- conf_man.send(:write_document_generation_script, 'file', 'hello')
+ conf_man.send(:write_document_generation_script, 'file', 'hello', {})
expect(file_like_object).to have_received(:write)
end
end
describe "#find_configuration_document" do
it "should find the mof file" do
- # These tests seem way too implementation specific. Unfortunatly, File and Dir
+ # These tests seem way too implementation specific. Unfortunately, File and Dir
# need to be mocked because they are OS specific
allow(File).to receive(:join) do |a, b|
[a,b].join("++")
@@ -158,14 +158,36 @@ describe Chef::Util::DSC::ConfigurationGenerator do
describe "#configuration_code" do
it "should build dsc" do
- dsc = conf_man.send(:configuration_code, 'archive{}', 'hello')
+ dsc = conf_man.send(:configuration_code, 'archive{}', 'hello', {})
found_configuration = false
dsc.split(';').each do |command|
if command.downcase =~ /\s*configuration\s+'hello'\s*\{\s*node\s+'localhost'\s*\{\s*archive\s*\{\s*\}\s*\}\s*\}\s*/
found_configuration = true
end
end
- expect(found_configuration).to be_true
+ expect(found_configuration).to be_truthy
+ end
+ context "with imports" do
+ it "should import all resources when a module has an empty list" do
+ dsc = conf_man.send(:configuration_code, 'archive{}', 'hello', {'FooModule' => []})
+ expect(dsc).to match(/Import-DscResource -ModuleName FooModule\s*\n/)
+ end
+
+ it "should import all resources when a module has a list with *" do
+ dsc = conf_man.send(:configuration_code, 'archive{}', 'hello', {'FooModule' => ['FooResource', '*', 'BarResource']})
+ expect(dsc).to match(/Import-DscResource -ModuleName FooModule\s*\n/)
+ end
+
+ it "should import specific resources when a module has list without * that is not empty" do
+ dsc = conf_man.send(:configuration_code, 'archive{}', 'hello', {'FooModule' => ['FooResource', 'BarResource']})
+ expect(dsc).to match(/Import-DscResource -ModuleName FooModule -Name FooResource,BarResource/)
+ end
+
+ it "should import multiple modules with multiple import statements" do
+ dsc = conf_man.send(:configuration_code, 'archive{}', 'hello', {'FooModule' => ['FooResource', 'BarResource'], 'BazModule' => []})
+ expect(dsc).to match(/Import-DscResource -ModuleName FooModule -Name FooResource,BarResource/)
+ expect(dsc).to match(/Import-DscResource -ModuleName BazModule\s*\n/)
+ end
end
end
end
diff --git a/spec/unit/util/dsc/lcm_output_parser_spec.rb b/spec/unit/util/dsc/lcm_output_parser_spec.rb
index 23a3dbd3ec..3d44e07885 100644
--- a/spec/unit/util/dsc/lcm_output_parser_spec.rb
+++ b/spec/unit/util/dsc/lcm_output_parser_spec.rb
@@ -20,24 +20,19 @@ require 'chef/util/dsc/lcm_output_parser'
describe Chef::Util::DSC::LocalConfigurationManager::Parser do
context 'empty input parameter' do
- it 'returns an empty array for a 0 length string' do
- Chef::Util::DSC::LocalConfigurationManager::Parser::parse('').should be_empty
+ it 'raises an exception when there are no valid lines' do
+ str = <<-EOF
+
+ EOF
+ expect {Chef::Util::DSC::LocalConfigurationManager::Parser::parse(str)}.to raise_error(Chef::Exceptions::LCMParser)
end
- it 'returns an empty array for a nil input' do
- Chef::Util::DSC::LocalConfigurationManager::Parser::parse('').should be_empty
+ it 'raises an exception for a nil input' do
+ expect {Chef::Util::DSC::LocalConfigurationManager::Parser::parse(nil)}.to raise_error(Chef::Exceptions::LCMParser)
end
end
context 'correctly formatted output from lcm' do
- it 'returns an empty array for a log with no resources' do
- str = <<EOF
-logtype: [machinename]: LCM: [ Start Set ]
-logtype: [machinename]: LCM: [ End Set ]
-EOF
- Chef::Util::DSC::LocalConfigurationManager::Parser::parse(str).should be_empty
- end
-
it 'returns a single resource when only 1 logged with the correct name' do
str = <<EOF
logtype: [machinename]: LCM: [ Start Set ]
@@ -46,8 +41,8 @@ logtype: [machinename]: LCM: [ End Resource ] [name]
logtype: [machinename]: LCM: [ End Set ]
EOF
resources = Chef::Util::DSC::LocalConfigurationManager::Parser::parse(str)
- resources.length.should eq(1)
- resources[0].name.should eq('[name]')
+ expect(resources.length).to eq(1)
+ expect(resources[0].name).to eq('[name]')
end
it 'identifies when a resource changes the state of the system' do
@@ -60,7 +55,7 @@ logtype: [machinename]: LCM: [ End Resource ] [name]
logtype: [machinename]: LCM: [ End Set ]
EOF
resources = Chef::Util::DSC::LocalConfigurationManager::Parser::parse(str)
- resources[0].changes_state?.should be_true
+ expect(resources[0].changes_state?).to be_truthy
end
it 'preserves the log provided for how the system changed the state' do
@@ -74,7 +69,7 @@ logtype: [machinename]: LCM: [ End Resource ] [name]
logtype: [machinename]: LCM: [ End Set ]
EOF
resources = Chef::Util::DSC::LocalConfigurationManager::Parser::parse(str)
- resources[0].change_log.should match_array(["[name]","[message]","[name]"])
+ expect(resources[0].change_log).to match_array(["[name]","[message]","[name]"])
end
it 'should return false for changes_state?' do
@@ -86,7 +81,7 @@ logtype: [machinename]: LCM: [ End Resource ] [name]
logtype: [machinename]: LCM: [ End Set ]
EOF
resources = Chef::Util::DSC::LocalConfigurationManager::Parser::parse(str)
- resources[0].changes_state?.should be_false
+ expect(resources[0].changes_state?).to be_falsey
end
it 'should return an empty array for change_log if changes_state? is false' do
@@ -98,7 +93,7 @@ logtype: [machinename]: LCM: [ End Resource ] [name]
logtype: [machinename]: LCM: [ End Set ]
EOF
resources = Chef::Util::DSC::LocalConfigurationManager::Parser::parse(str)
- resources[0].change_log.should be_empty
+ expect(resources[0].change_log).to be_empty
end
end
@@ -120,8 +115,8 @@ logtype: [machinename]: LCM: [ End Set ]
EOF
resources = Chef::Util::DSC::LocalConfigurationManager::Parser::parse(str)
- resources[0].changes_state?.should be_false
- resources[1].changes_state?.should be_true
+ expect(resources[0].changes_state?).to be_falsey
+ expect(resources[1].changes_state?).to be_truthy
end
it 'should allow missing a [End Resource] when its the first one and still find all the resource' do
@@ -141,8 +136,8 @@ logtype: [machinename]: LCM: [ End Set ]
EOF
resources = Chef::Util::DSC::LocalConfigurationManager::Parser::parse(str)
- resources[0].changes_state?.should be_false
- resources[1].changes_state?.should be_true
+ expect(resources[0].changes_state?).to be_falsey
+ expect(resources[1].changes_state?).to be_truthy
end
it 'should allow missing set and end resource and assume an unconverged resource in this case' do
@@ -160,10 +155,10 @@ logtype: [machinename]: LCM: [ End Resource ]
logtype: [machinename]: LCM: [ End Set ]
EOF
resources = Chef::Util::DSC::LocalConfigurationManager::Parser::parse(str)
- resources[0].changes_state?.should be_true
- resources[0].name.should eql('[name]')
- resources[1].changes_state?.should be_true
- resources[1].name.should eql('[name2]')
+ expect(resources[0].changes_state?).to be_truthy
+ expect(resources[0].name).to eql('[name]')
+ expect(resources[1].changes_state?).to be_truthy
+ expect(resources[1].name).to eql('[name2]')
end
end
end
diff --git a/spec/unit/util/dsc/local_configuration_manager_spec.rb b/spec/unit/util/dsc/local_configuration_manager_spec.rb
index eb27e9e94e..1cff9e445b 100644
--- a/spec/unit/util/dsc/local_configuration_manager_spec.rb
+++ b/spec/unit/util/dsc/local_configuration_manager_spec.rb
@@ -65,7 +65,7 @@ EOH
let(:lcm_cmdlet_success) { true }
it 'should successfully return resource information for normally formatted output when cmdlet the cmdlet succeeds' do
- test_configuration_result = lcm.test_configuration('config')
+ test_configuration_result = lcm.test_configuration('config', {})
expect(test_configuration_result.class).to be(Array)
expect(test_configuration_result.length).to be > 0
expect(Chef::Log).not_to receive(:warn)
@@ -78,14 +78,14 @@ EOH
let(:lcm_cmdlet_success) { false }
it 'returns true when passed to #whatif_not_supported?' do
- expect(lcm.send(:whatif_not_supported?, no_whatif_lcm_output)).to be_true
+ expect(lcm.send(:whatif_not_supported?, no_whatif_lcm_output)).to be_truthy
end
it 'should should return a (possibly empty) array of ResourceInfo instances' do
- expect(Chef::Log).to receive(:warn)
+ expect(Chef::Log).to receive(:warn).at_least(:once)
expect(lcm).to receive(:whatif_not_supported?).and_call_original
test_configuration_result = nil
- expect {test_configuration_result = lcm.test_configuration('config')}.not_to raise_error
+ expect {test_configuration_result = lcm.test_configuration('config', {})}.not_to raise_error
expect(test_configuration_result.class).to be(Array)
end
end
@@ -96,16 +96,16 @@ EOH
let(:lcm_cmdlet_success) { false }
it 'should log a warning if the message is formatted as expected when a resource import failure occurs' do
- expect(Chef::Log).to receive(:warn)
+ expect(Chef::Log).to receive(:warn).at_least(:once)
expect(lcm).to receive(:dsc_module_import_failure?).and_call_original
test_configuration_result = nil
- expect {test_configuration_result = lcm.test_configuration('config')}.not_to raise_error
+ expect {test_configuration_result = lcm.test_configuration('config', {})}.not_to raise_error
end
it 'should return a (possibly empty) array of ResourceInfo instances' do
- expect(Chef::Log).to receive(:warn)
+ expect(Chef::Log).to receive(:warn).at_least(:once)
test_configuration_result = nil
- expect {test_configuration_result = lcm.test_configuration('config')}.not_to raise_error
+ expect {test_configuration_result = lcm.test_configuration('config', {})}.not_to raise_error
expect(test_configuration_result.class).to be(Array)
end
end
@@ -116,9 +116,9 @@ EOH
let(:lcm_cmdlet_success) { false }
it 'should log a warning' do
- expect(Chef::Log).to receive(:warn)
+ expect(Chef::Log).to receive(:warn).at_least(:once)
expect(lcm).to receive(:dsc_module_import_failure?).and_call_original
- expect {lcm.test_configuration('config')}.not_to raise_error
+ expect {lcm.test_configuration('config', {})}.not_to raise_error
end
end
end
diff --git a/spec/unit/util/editor_spec.rb b/spec/unit/util/editor_spec.rb
index 06370f7de0..968302df17 100644
--- a/spec/unit/util/editor_spec.rb
+++ b/spec/unit/util/editor_spec.rb
@@ -22,7 +22,7 @@ describe Chef::Util::Editor do
context 'when there is no match' do
subject(:execute) { editor.append_line_after('missing', 'new') }
- it('returns the number of added lines') { should be == 0 }
+ it('returns the number of added lines') { is_expected.to eq(0) }
it 'does not add any lines' do
expect { execute }.to_not change { editor.lines }
end
@@ -31,7 +31,7 @@ describe Chef::Util::Editor do
context 'when there is a match' do
subject(:execute) { editor.append_line_after('two', 'new') }
- it('returns the number of added lines') { should be == 2 }
+ it('returns the number of added lines') { is_expected.to eq(2) }
it 'adds a line after each match' do
execute
expect(editor.lines).to be == ['one', 'two', 'new', 'two', 'new', 'three']
@@ -48,7 +48,7 @@ describe Chef::Util::Editor do
context 'when there is no match' do
subject(:execute) { editor.append_line_if_missing('missing', 'new') }
- it('returns the number of added lines') { should be == 1 }
+ it('returns the number of added lines') { is_expected.to eq(1) }
it 'adds a line to the end' do
execute
expect(editor.lines).to be == ['one', 'two', 'two', 'three', 'new']
@@ -58,7 +58,7 @@ describe Chef::Util::Editor do
context 'when there is a match' do
subject(:execute) { editor.append_line_if_missing('one', 'new') }
- it('returns the number of added lines') { should be == 0 }
+ it('returns the number of added lines') { is_expected.to eq(0) }
it 'does not add any lines' do
expect { execute }.to_not change { editor.lines }
end
@@ -74,7 +74,7 @@ describe Chef::Util::Editor do
context 'when there is no match' do
subject(:execute) { editor.remove_lines('missing') }
- it('returns the number of removed lines') { should be == 0 }
+ it('returns the number of removed lines') { is_expected.to eq(0) }
it 'does not remove any lines' do
expect { execute }.to_not change { editor.lines }
end
@@ -83,7 +83,7 @@ describe Chef::Util::Editor do
context 'when there is a match' do
subject(:execute) { editor.remove_lines('two') }
- it('returns the number of removed lines') { should be == 2 }
+ it('returns the number of removed lines') { is_expected.to eq(2) }
it 'removes the matching lines' do
execute
expect(editor.lines).to be == ['one', 'three']
@@ -100,7 +100,7 @@ describe Chef::Util::Editor do
context 'when there is no match' do
subject(:execute) { editor.replace('missing', 'new') }
- it('returns the number of changed lines') { should be == 0 }
+ it('returns the number of changed lines') { is_expected.to eq(0) }
it 'does not change any lines' do
expect { execute }.to_not change { editor.lines }
end
@@ -109,7 +109,7 @@ describe Chef::Util::Editor do
context 'when there is a match' do
subject(:execute) { editor.replace('two', 'new') }
- it('returns the number of changed lines') { should be == 2 }
+ it('returns the number of changed lines') { is_expected.to eq(2) }
it 'replaces the matching portions' do
execute
expect(editor.lines).to be == ['one', 'new', 'new', 'three']
@@ -127,7 +127,7 @@ describe Chef::Util::Editor do
context 'when there is no match' do
subject(:execute) { editor.replace_lines('missing', 'new') }
- it('returns the number of changed lines') { should be == 0 }
+ it('returns the number of changed lines') { is_expected.to eq(0) }
it 'does not change any lines' do
expect { execute }.to_not change { editor.lines }
end
@@ -136,7 +136,7 @@ describe Chef::Util::Editor do
context 'when there is a match' do
subject(:execute) { editor.replace_lines('two', 'new') }
- it('returns the number of replaced lines') { should be == 2 }
+ it('returns the number of replaced lines') { is_expected.to eq(2) }
it 'replaces the matching line' do
execute
expect(editor.lines).to be == ['one', 'new', 'new', 'three']
diff --git a/spec/unit/util/file_edit_spec.rb b/spec/unit/util/file_edit_spec.rb
index 139b29d9ce..b99cf2f426 100644
--- a/spec/unit/util/file_edit_spec.rb
+++ b/spec/unit/util/file_edit_spec.rb
@@ -135,21 +135,21 @@ twice
describe "search_file_replace" do
it "should accept regex passed in as a string (not Regexp object) and replace the match if there is one" do
fedit.search_file_replace("localhost", "replacement")
- fedit.unwritten_changes?.should be_true
+ expect(fedit.unwritten_changes?).to be_truthy
fedit.write_file
expect(edited_file_contents).to eq(localhost_replaced)
end
it "should accept regex passed in as a Regexp object and replace the match if there is one" do
fedit.search_file_replace(/localhost/, "replacement")
- fedit.unwritten_changes?.should be_true
+ expect(fedit.unwritten_changes?).to be_truthy
fedit.write_file
expect(edited_file_contents).to eq(localhost_replaced)
end
it "should do nothing if there isn't a match" do
fedit.search_file_replace(/pattern/, "replacement")
- fedit.unwritten_changes?.should be_false
+ expect(fedit.unwritten_changes?).to be_falsey
fedit.write_file
expect(edited_file_contents).to eq(starting_content)
end
@@ -158,7 +158,7 @@ twice
describe "search_file_replace_line" do
it "should search for match and replace the whole line" do
fedit.search_file_replace_line(/localhost/, "replacement line")
- fedit.unwritten_changes?.should be_true
+ expect(fedit.unwritten_changes?).to be_truthy
fedit.write_file
expect(edited_file_contents).to eq(localhost_line_replaced)
end
@@ -167,7 +167,7 @@ twice
describe "search_file_delete" do
it "should search for match and delete the match" do
fedit.search_file_delete(/localhost/)
- fedit.unwritten_changes?.should be_true
+ expect(fedit.unwritten_changes?).to be_truthy
fedit.write_file
expect(edited_file_contents).to eq(localhost_deleted)
end
@@ -176,7 +176,7 @@ twice
describe "search_file_delete_line" do
it "should search for match and delete the matching line" do
fedit.search_file_delete_line(/localhost/)
- fedit.unwritten_changes?.should be_true
+ expect(fedit.unwritten_changes?).to be_truthy
fedit.write_file
expect(edited_file_contents).to eq(localhost_line_deleted)
end
@@ -185,7 +185,7 @@ twice
describe "insert_line_after_match" do
it "should search for match and insert the given line after the matching line" do
fedit.insert_line_after_match(/localhost/, "new line inserted")
- fedit.unwritten_changes?.should be_true
+ expect(fedit.unwritten_changes?).to be_truthy
fedit.write_file
expect(edited_file_contents).to eq(append_after_all_localhost)
end
@@ -194,14 +194,14 @@ twice
describe "insert_line_if_no_match" do
it "should search for match and insert the given line if no line match" do
fedit.insert_line_if_no_match(/pattern/, "new line inserted")
- fedit.unwritten_changes?.should be_true
+ expect(fedit.unwritten_changes?).to be_truthy
fedit.write_file
expect(edited_file_contents).to eq(append_after_content)
end
it "should do nothing if there is a match" do
fedit.insert_line_if_no_match(/localhost/, "replacement")
- fedit.unwritten_changes?.should be_false
+ expect(fedit.unwritten_changes?).to be_falsey
fedit.write_file
expect(edited_file_contents).to eq(starting_content)
end
@@ -218,7 +218,7 @@ twice
it "should return true if a file got edited" do
fedit.insert_line_if_no_match(/pattern/, "new line inserted")
fedit.write_file
- expect(fedit.file_edited?).to be_true
+ expect(fedit.file_edited?).to be_truthy
end
end
end
diff --git a/spec/unit/util/path_helper_spec.rb b/spec/unit/util/path_helper_spec.rb
index 1d97efc607..5756c29b90 100644
--- a/spec/unit/util/path_helper_spec.rb
+++ b/spec/unit/util/path_helper_spec.rb
@@ -25,81 +25,81 @@ describe Chef::Util::PathHelper do
[ false, true ].each do |is_windows|
context "on #{is_windows ? "windows" : "unix"}" do
before(:each) do
- Chef::Platform.stub(:windows?).and_return(is_windows)
+ allow(Chef::Platform).to receive(:windows?).and_return(is_windows)
end
describe "join" do
it "joins components when some end with separators" do
expected = PathHelper.cleanpath("/foo/bar/baz")
expected = "C:#{expected}" if is_windows
- PathHelper.join(is_windows ? 'C:\\foo\\' : "/foo/", "bar", "baz").should == expected
+ expect(PathHelper.join(is_windows ? 'C:\\foo\\' : "/foo/", "bar", "baz")).to eq(expected)
end
it "joins components when some end and start with separators" do
expected = PathHelper.cleanpath("/foo/bar/baz")
expected = "C:#{expected}" if is_windows
- PathHelper.join(is_windows ? 'C:\\foo\\' : "/foo/", "bar/", "/baz").should == expected
+ expect(PathHelper.join(is_windows ? 'C:\\foo\\' : "/foo/", "bar/", "/baz")).to eq(expected)
end
it "joins components that don't end in separators" do
expected = PathHelper.cleanpath("/foo/bar/baz")
expected = "C:#{expected}" if is_windows
- PathHelper.join(is_windows ? 'C:\\foo' : "/foo", "bar", "baz").should == expected
+ expect(PathHelper.join(is_windows ? 'C:\\foo' : "/foo", "bar", "baz")).to eq(expected)
end
it "joins starting with '' resolve to absolute paths" do
- PathHelper.join('', 'a', 'b').should == "#{PathHelper.path_separator}a#{PathHelper.path_separator}b"
+ expect(PathHelper.join('', 'a', 'b')).to eq("#{PathHelper.path_separator}a#{PathHelper.path_separator}b")
end
it "joins ending with '' add a / to the end" do
- PathHelper.join('a', 'b', '').should == "a#{PathHelper.path_separator}b#{PathHelper.path_separator}"
+ expect(PathHelper.join('a', 'b', '')).to eq("a#{PathHelper.path_separator}b#{PathHelper.path_separator}")
end
if is_windows
it "joins components on Windows when some end with unix separators" do
- PathHelper.join('C:\\foo/', "bar", "baz").should == 'C:\\foo\\bar\\baz'
+ expect(PathHelper.join('C:\\foo/', "bar", "baz")).to eq('C:\\foo\\bar\\baz')
end
end
end
if is_windows
it "path_separator is \\" do
- PathHelper.path_separator.should == '\\'
+ expect(PathHelper.path_separator).to eq('\\')
end
else
it "path_separator is /" do
- PathHelper.path_separator.should == '/'
+ expect(PathHelper.path_separator).to eq('/')
end
end
if is_windows
it "cleanpath changes slashes into backslashes and leaves backslashes alone" do
- PathHelper.cleanpath('/a/b\\c/d/').should == '\\a\\b\\c\\d'
+ expect(PathHelper.cleanpath('/a/b\\c/d/')).to eq('\\a\\b\\c\\d')
end
it "cleanpath does not remove leading double backslash" do
- PathHelper.cleanpath('\\\\a/b\\c/d/').should == '\\\\a\\b\\c\\d'
+ expect(PathHelper.cleanpath('\\\\a/b\\c/d/')).to eq('\\\\a\\b\\c\\d')
end
else
it "cleanpath removes extra slashes alone" do
- PathHelper.cleanpath('/a///b/c/d/').should == '/a/b/c/d'
+ expect(PathHelper.cleanpath('/a///b/c/d/')).to eq('/a/b/c/d')
end
end
describe "dirname" do
it "dirname('abc') is '.'" do
- PathHelper.dirname('abc').should == '.'
+ expect(PathHelper.dirname('abc')).to eq('.')
end
it "dirname('/') is '/'" do
- PathHelper.dirname(PathHelper.path_separator).should == PathHelper.path_separator
+ expect(PathHelper.dirname(PathHelper.path_separator)).to eq(PathHelper.path_separator)
end
it "dirname('a/b/c') is 'a/b'" do
- PathHelper.dirname(PathHelper.join('a', 'b', 'c')).should == PathHelper.join('a', 'b')
+ expect(PathHelper.dirname(PathHelper.join('a', 'b', 'c'))).to eq(PathHelper.join('a', 'b'))
end
it "dirname('a/b/c/') is 'a/b'" do
- PathHelper.dirname(PathHelper.join('a', 'b', 'c', '')).should == PathHelper.join('a', 'b')
+ expect(PathHelper.dirname(PathHelper.join('a', 'b', 'c', ''))).to eq(PathHelper.join('a', 'b'))
end
it "dirname('/a/b/c') is '/a/b'" do
- PathHelper.dirname(PathHelper.join('', 'a', 'b', 'c')).should == PathHelper.join('', 'a', 'b')
+ expect(PathHelper.dirname(PathHelper.join('', 'a', 'b', 'c'))).to eq(PathHelper.join('', 'a', 'b'))
end
end
end
@@ -109,9 +109,9 @@ describe Chef::Util::PathHelper do
context "on windows" do
before(:each) do
# pass by default
- Chef::Platform.stub(:windows?).and_return(true)
- PathHelper.stub(:printable?).and_return(true)
- PathHelper.stub(:windows_max_length_exceeded?).and_return(false)
+ allow(Chef::Platform).to receive(:windows?).and_return(true)
+ allow(PathHelper).to receive(:printable?).and_return(true)
+ allow(PathHelper).to receive(:windows_max_length_exceeded?).and_return(false)
end
it "returns the path if the path passes the tests" do
@@ -123,14 +123,14 @@ describe Chef::Util::PathHelper do
end
it "raises an error if the path has invalid characters" do
- PathHelper.stub(:printable?).and_return(false)
+ allow(PathHelper).to receive(:printable?).and_return(false)
expect { PathHelper.validate_path("Newline!\n") }.to raise_error(Chef::Exceptions::ValidationFailed)
end
it "Adds the \\\\?\\ prefix if the path exceeds MAX_LENGTH and does not have it" do
long_path = "C:\\" + "a" * 250 + "\\" + "b" * 250
prefixed_long_path = "\\\\?\\" + long_path
- PathHelper.stub(:windows_max_length_exceeded?).and_return(true)
+ allow(PathHelper).to receive(:windows_max_length_exceeded?).and_return(true)
expect(PathHelper.validate_path(long_path)).to eql(prefixed_long_path)
end
end
@@ -138,38 +138,38 @@ describe Chef::Util::PathHelper do
describe "windows_max_length_exceeded?" do
it "returns true if the path is too long (259 + NUL) for the API" do
- expect(PathHelper.windows_max_length_exceeded?("C:\\" + "a" * 250 + "\\" + "b" * 6)).to be_true
+ expect(PathHelper.windows_max_length_exceeded?("C:\\" + "a" * 250 + "\\" + "b" * 6)).to be_truthy
end
it "returns false if the path is not too long (259 + NUL) for the standard API" do
- expect(PathHelper.windows_max_length_exceeded?("C:\\" + "a" * 250 + "\\" + "b" * 5)).to be_false
+ expect(PathHelper.windows_max_length_exceeded?("C:\\" + "a" * 250 + "\\" + "b" * 5)).to be_falsey
end
it "returns false if the path is over 259 characters but uses the \\\\?\\ prefix" do
- expect(PathHelper.windows_max_length_exceeded?("\\\\?\\C:\\" + "a" * 250 + "\\" + "b" * 250)).to be_false
+ expect(PathHelper.windows_max_length_exceeded?("\\\\?\\C:\\" + "a" * 250 + "\\" + "b" * 250)).to be_falsey
end
end
describe "printable?" do
it "returns true if the string contains no non-printable characters" do
- expect(PathHelper.printable?("C:\\Program Files (x86)\\Microsoft Office\\Files.lst")).to be_true
+ expect(PathHelper.printable?("C:\\Program Files (x86)\\Microsoft Office\\Files.lst")).to be_truthy
end
it "returns true when given 'abc' in unicode" do
- expect(PathHelper.printable?("\u0061\u0062\u0063")).to be_true
+ expect(PathHelper.printable?("\u0061\u0062\u0063")).to be_truthy
end
it "returns true when given japanese unicode" do
- expect(PathHelper.printable?("\uff86\uff87\uff88")).to be_true
+ expect(PathHelper.printable?("\uff86\uff87\uff88")).to be_truthy
end
it "returns false if the string contains a non-printable character" do
- expect(PathHelper.printable?("\my files\work\notes.txt")).to be_false
+ expect(PathHelper.printable?("\my files\work\notes.txt")).to be_falsey
end
# This isn't necessarily a requirement, but here to be explicit about functionality.
it "returns false if the string contains a newline or tab" do
- expect(PathHelper.printable?("\tThere's no way,\n\t *no* way,\n\t that you came from my loins.\n")).to be_false
+ expect(PathHelper.printable?("\tThere's no way,\n\t *no* way,\n\t that you came from my loins.\n")).to be_falsey
end
end
@@ -189,31 +189,23 @@ describe Chef::Util::PathHelper do
end
context "not on windows", :unix_only do
- context "ruby is at least 1.9", :ruby_gte_19_only do
- it "returns a canonical path" do
- expect(PathHelper.canonical_path("/etc//apache.d/sites-enabled/../sites-available/default")).to eq("/etc/apache.d/sites-available/default")
- end
- end
-
- context "ruby is less than 1.9", :ruby_18_only do
- it "returns a canonical path" do
- expect { PathHelper.canonical_path("/etc//apache.d/sites-enabled/../sites-available/default") }.to raise_error(NotImplementedError)
- end
+ it "returns a canonical path" do
+ expect(PathHelper.canonical_path("/etc//apache.d/sites-enabled/../sites-available/default")).to eq("/etc/apache.d/sites-available/default")
end
end
end
describe "paths_eql?" do
it "returns true if the paths are the same" do
- PathHelper.stub(:canonical_path).with("bandit").and_return("c:/bandit/bandit")
- PathHelper.stub(:canonical_path).with("../bandit/bandit").and_return("c:/bandit/bandit")
- expect(PathHelper.paths_eql?("bandit", "../bandit/bandit")).to be_true
+ allow(PathHelper).to receive(:canonical_path).with("bandit").and_return("c:/bandit/bandit")
+ allow(PathHelper).to receive(:canonical_path).with("../bandit/bandit").and_return("c:/bandit/bandit")
+ expect(PathHelper.paths_eql?("bandit", "../bandit/bandit")).to be_truthy
end
it "returns false if the paths are different" do
- PathHelper.stub(:canonical_path).with("bandit").and_return("c:/Bo/Bandit")
- PathHelper.stub(:canonical_path).with("../bandit/bandit").and_return("c:/bandit/bandit")
- expect(PathHelper.paths_eql?("bandit", "../bandit/bandit")).to be_false
+ allow(PathHelper).to receive(:canonical_path).with("bandit").and_return("c:/Bo/Bandit")
+ allow(PathHelper).to receive(:canonical_path).with("../bandit/bandit").and_return("c:/bandit/bandit")
+ expect(PathHelper.paths_eql?("bandit", "../bandit/bandit")).to be_falsey
end
end
diff --git a/spec/unit/util/powershell/cmdlet_spec.rb b/spec/unit/util/powershell/cmdlet_spec.rb
index a964f607c8..5ddf9282c4 100644
--- a/spec/unit/util/powershell/cmdlet_spec.rb
+++ b/spec/unit/util/powershell/cmdlet_spec.rb
@@ -51,18 +51,18 @@ describe Chef::Util::Powershell::Cmdlet do
# Is this list really complete?
%w{` " # '}.each do |c|
it "escapse #{c}" do
- @cmdlet.send(:escape_parameter_value, "stuff #{c}").should eql("stuff `#{c}")
+ expect(@cmdlet.send(:escape_parameter_value, "stuff #{c}")).to eql("stuff `#{c}")
end
end
it 'does not do anything to a string without special characters' do
- @cmdlet.send(:escape_parameter_value, 'stuff').should eql('stuff')
+ expect(@cmdlet.send(:escape_parameter_value, 'stuff')).to eql('stuff')
end
end
describe '#escape_string_parameter_value' do
it "surrounds a string with ''" do
- @cmdlet.send(:escape_string_parameter_value, 'stuff').should eql("'stuff'")
+ expect(@cmdlet.send(:escape_string_parameter_value, 'stuff')).to eql("'stuff'")
end
end
@@ -80,27 +80,27 @@ describe Chef::Util::Powershell::Cmdlet do
end
it 'ignores switches with a false value' do
- @cmdlet.send(:command_switches_string, {foo: false}).should eql('')
+ expect(@cmdlet.send(:command_switches_string, {foo: false})).to eql('')
end
it 'should correctly handle a value type of string' do
- @cmdlet.send(:command_switches_string, {foo: 'bar'}).should eql("-foo 'bar'")
+ expect(@cmdlet.send(:command_switches_string, {foo: 'bar'})).to eql("-foo 'bar'")
end
it 'should correctly handle a value type of string even when it is 0 length' do
- @cmdlet.send(:command_switches_string, {foo: ''}).should eql("-foo ''")
+ expect(@cmdlet.send(:command_switches_string, {foo: ''})).to eql("-foo ''")
end
it 'should not quote integers' do
- @cmdlet.send(:command_switches_string, {foo: 1}).should eql("-foo 1")
+ expect(@cmdlet.send(:command_switches_string, {foo: 1})).to eql("-foo 1")
end
it 'should not quote floats' do
- @cmdlet.send(:command_switches_string, {foo: 1.0}).should eql("-foo 1.0")
+ expect(@cmdlet.send(:command_switches_string, {foo: 1.0})).to eql("-foo 1.0")
end
it 'has just the switch when the value is true' do
- @cmdlet.send(:command_switches_string, {foo: true}).should eql("-foo")
+ expect(@cmdlet.send(:command_switches_string, {foo: true})).to eql("-foo")
end
end
end
diff --git a/spec/unit/util/selinux_spec.rb b/spec/unit/util/selinux_spec.rb
index 53faba3db3..0ed138c7bc 100644
--- a/spec/unit/util/selinux_spec.rb
+++ b/spec/unit/util/selinux_spec.rb
@@ -44,17 +44,17 @@ describe Chef::Util::Selinux do
expected_paths.each do |bin_path|
selinux_path = File.join(bin_path, "selinuxenabled")
- File.should_receive(:executable?).with(selinux_path).and_return(false)
+ expect(File).to receive(:executable?).with(selinux_path).and_return(false)
end
- @test_instance.selinux_enabled?.should be_false
+ expect(@test_instance.selinux_enabled?).to be_falsey
end
describe "when selinuxenabled binary exists" do
before do
@selinux_enabled_path = File.join("/sbin", "selinuxenabled")
- File.stub(:executable?) do |file_path|
- file_path.end_with?("selinuxenabled").should be_true
+ allow(File).to receive(:executable?) do |file_path|
+ expect(file_path.end_with?("selinuxenabled")).to be_truthy
file_path == @selinux_enabled_path
end
end
@@ -62,54 +62,54 @@ describe Chef::Util::Selinux do
describe "when selinux is enabled" do
before do
cmd_result = double("Cmd Result", :exitstatus => 0)
- @test_instance.should_receive(:shell_out!).once.with(@selinux_enabled_path, {:returns=>[0, 1]}).and_return(cmd_result)
+ expect(@test_instance).to receive(:shell_out!).once.with(@selinux_enabled_path, {:returns=>[0, 1]}).and_return(cmd_result)
end
it "should report selinux is enabled" do
- @test_instance.selinux_enabled?.should be_true
+ expect(@test_instance.selinux_enabled?).to be_truthy
# should check the file system only once for multiple calls
- @test_instance.selinux_enabled?.should be_true
+ expect(@test_instance.selinux_enabled?).to be_truthy
end
end
describe "when selinux is disabled" do
before do
cmd_result = double("Cmd Result", :exitstatus => 1)
- @test_instance.should_receive(:shell_out!).once.with(@selinux_enabled_path, {:returns=>[0, 1]}).and_return(cmd_result)
+ expect(@test_instance).to receive(:shell_out!).once.with(@selinux_enabled_path, {:returns=>[0, 1]}).and_return(cmd_result)
end
it "should report selinux is disabled" do
- @test_instance.selinux_enabled?.should be_false
+ expect(@test_instance.selinux_enabled?).to be_falsey
# should check the file system only once for multiple calls
- @test_instance.selinux_enabled?.should be_false
+ expect(@test_instance.selinux_enabled?).to be_falsey
end
end
describe "when selinux gives an unexpected status" do
before do
cmd_result = double("Cmd Result", :exitstatus => 101)
- @test_instance.should_receive(:shell_out!).once.with(@selinux_enabled_path, {:returns=>[0, 1]}).and_return(cmd_result)
+ expect(@test_instance).to receive(:shell_out!).once.with(@selinux_enabled_path, {:returns=>[0, 1]}).and_return(cmd_result)
end
it "should throw an error" do
- lambda {@test_instance.selinux_enabled?}.should raise_error(RuntimeError)
+ expect {@test_instance.selinux_enabled?}.to raise_error(RuntimeError)
end
end
end
describe "when selinuxenabled binary doesn't exist" do
before do
- File.stub(:executable?) do |file_path|
- file_path.end_with?("selinuxenabled").should be_true
+ allow(File).to receive(:executable?) do |file_path|
+ expect(file_path.end_with?("selinuxenabled")).to be_truthy
false
end
end
it "should report selinux is disabled" do
- @test_instance.selinux_enabled?.should be_false
+ expect(@test_instance.selinux_enabled?).to be_falsey
# should check the file system only once for multiple calls
- File.should_not_receive(:executable?)
- @test_instance.selinux_enabled?.should be_false
+ expect(File).not_to receive(:executable?)
+ expect(@test_instance.selinux_enabled?).to be_falsey
end
end
@@ -118,53 +118,53 @@ describe Chef::Util::Selinux do
before do
@restorecon_enabled_path = File.join("/sbin", "restorecon")
- File.stub(:executable?) do |file_path|
- file_path.end_with?("restorecon").should be_true
+ allow(File).to receive(:executable?) do |file_path|
+ expect(file_path.end_with?("restorecon")).to be_truthy
file_path == @restorecon_enabled_path
end
end
it "should call restorecon non-recursive by default" do
restorecon_command = "#{@restorecon_enabled_path} -R \"#{path}\""
- @test_instance.should_receive(:shell_out!).twice.with(restorecon_command)
+ expect(@test_instance).to receive(:shell_out!).twice.with(restorecon_command)
@test_instance.restore_security_context(path)
- File.should_not_receive(:executable?)
+ expect(File).not_to receive(:executable?)
@test_instance.restore_security_context(path)
end
it "should call restorecon recursive when recursive is set" do
restorecon_command = "#{@restorecon_enabled_path} -R -r \"#{path}\""
- @test_instance.should_receive(:shell_out!).twice.with(restorecon_command)
+ expect(@test_instance).to receive(:shell_out!).twice.with(restorecon_command)
@test_instance.restore_security_context(path, true)
- File.should_not_receive(:executable?)
+ expect(File).not_to receive(:executable?)
@test_instance.restore_security_context(path, true)
end
it "should call restorecon non-recursive when recursive is not set" do
restorecon_command = "#{@restorecon_enabled_path} -R \"#{path}\""
- @test_instance.should_receive(:shell_out!).twice.with(restorecon_command)
+ expect(@test_instance).to receive(:shell_out!).twice.with(restorecon_command)
@test_instance.restore_security_context(path)
- File.should_not_receive(:executable?)
+ expect(File).not_to receive(:executable?)
@test_instance.restore_security_context(path)
end
describe "when restorecon doesn't exist on the system" do
before do
- File.stub(:executable?) do |file_path|
- file_path.end_with?("restorecon").should be_true
+ allow(File).to receive(:executable?) do |file_path|
+ expect(file_path.end_with?("restorecon")).to be_truthy
false
end
end
it "should log a warning message" do
log = [ ]
- Chef::Log.stub(:warn) do |message|
+ allow(Chef::Log).to receive(:warn) do |message|
log << message
end
@test_instance.restore_security_context(path)
- log.should_not be_empty
- File.should_not_receive(:executable?)
+ expect(log).not_to be_empty
+ expect(File).not_to receive(:executable?)
@test_instance.restore_security_context(path)
end
end
diff --git a/spec/unit/util/threaded_job_queue_spec.rb b/spec/unit/util/threaded_job_queue_spec.rb
index a199937639..22626328be 100644
--- a/spec/unit/util/threaded_job_queue_spec.rb
+++ b/spec/unit/util/threaded_job_queue_spec.rb
@@ -23,8 +23,8 @@ describe Chef::Util::ThreadedJobQueue do
it "should pass mutex to jobs with an arity of 1" do
job = double()
- job.should_receive(:arity).at_least(:once).and_return(1)
- job.should_receive(:call).exactly(5).times.with(an_instance_of(Mutex))
+ expect(job).to receive(:arity).at_least(:once).and_return(1)
+ expect(job).to receive(:call).exactly(5).times.with(an_instance_of(Mutex))
5.times { queue << job }
queue.process
@@ -32,20 +32,20 @@ describe Chef::Util::ThreadedJobQueue do
it "should pass nothing to jobs with an arity of 0" do
job = double()
- job.should_receive(:arity).at_least(:once).and_return(0)
- job.should_receive(:call).exactly(5).times.with(no_args)
+ expect(job).to receive(:arity).at_least(:once).and_return(0)
+ expect(job).to receive(:call).exactly(5).times.with(no_args)
5.times { queue << job }
queue.process
end
it "should use specified number of threads" do
- Thread.should_receive(:new).exactly(7).times.and_call_original
+ expect(Thread).to receive(:new).exactly(7).times.and_call_original
queue.process(7)
end
it "should propagate exceptions to the main thread" do
queue << lambda { raise WorkerThreadError }
- lambda { queue.process }.should raise_error(WorkerThreadError)
+ expect { queue.process }.to raise_error(WorkerThreadError)
end
end
diff --git a/spec/unit/version/platform_spec.rb b/spec/unit/version/platform_spec.rb
index 69f42e58b2..dd425b32a5 100644
--- a/spec/unit/version/platform_spec.rb
+++ b/spec/unit/version/platform_spec.rb
@@ -21,12 +21,12 @@ describe Chef::Version::Platform do
it "is a subclass of Chef::Version" do
v = Chef::Version::Platform.new('1.1')
- v.should be_an_instance_of(Chef::Version::Platform)
- v.should be_a_kind_of(Chef::Version)
+ expect(v).to be_an_instance_of(Chef::Version::Platform)
+ expect(v).to be_a_kind_of(Chef::Version)
end
it "should transform 1 to 1.0.0" do
- Chef::Version::Platform.new("1").to_s.should == "1.0.0"
+ expect(Chef::Version::Platform.new("1").to_s).to eq("1.0.0")
end
describe "when creating valid Versions" do
@@ -44,7 +44,7 @@ describe Chef::Version::Platform do
the_error = Chef::Exceptions::InvalidPlatformVersion
bad_versions.each do |v|
it "should raise #{the_error} when given '#{v}'" do
- lambda { Chef::Version::Platform.new v }.should raise_error(the_error)
+ expect { Chef::Version::Platform.new v }.to raise_error(the_error)
end
end
end
@@ -52,7 +52,7 @@ describe Chef::Version::Platform do
describe "<=>" do
it "should equate versions 1 and 1.0.0" do
- Chef::Version::Platform.new("1").should == Chef::Version::Platform.new("1.0.0")
+ expect(Chef::Version::Platform.new("1")).to eq(Chef::Version::Platform.new("1.0.0"))
end
end
diff --git a/spec/unit/version_class_spec.rb b/spec/unit/version_class_spec.rb
index b0fcfbb3fb..fe1488550b 100644
--- a/spec/unit/version_class_spec.rb
+++ b/spec/unit/version_class_spec.rb
@@ -25,22 +25,22 @@ describe Chef::Version do
end
it "should turn itself into a string" do
- @v0.to_s.should == "0.0.0"
- @v123.to_s.should == "1.2.3"
+ expect(@v0.to_s).to eq("0.0.0")
+ expect(@v123.to_s).to eq("1.2.3")
end
it "should make a round trip with its string representation" do
a = Chef::Version.new(@v123.to_s)
- a.should == @v123
+ expect(a).to eq(@v123)
end
it "should transform 1.2 to 1.2.0" do
- Chef::Version.new("1.2").to_s.should == "1.2.0"
+ expect(Chef::Version.new("1.2").to_s).to eq("1.2.0")
end
it "should transform 01.002.0003 to 1.2.3" do
a = Chef::Version.new "01.002.0003"
- a.should == @v123
+ expect(a).to eq(@v123)
end
describe "when creating valid Versions" do
@@ -58,7 +58,7 @@ describe Chef::Version do
the_error = Chef::Exceptions::InvalidCookbookVersion
bad_versions.each do |v|
it "should raise #{the_error} when given '#{v}'" do
- lambda { Chef::Version.new v }.should raise_error(the_error)
+ expect { Chef::Version.new v }.to raise_error(the_error)
end
end
end
@@ -66,15 +66,15 @@ describe Chef::Version do
describe "<=>" do
it "should equate versions 1.2 and 1.2.0" do
- Chef::Version.new("1.2").should == Chef::Version.new("1.2.0")
+ expect(Chef::Version.new("1.2")).to eq(Chef::Version.new("1.2.0"))
end
it "should equate version 1.04 and 1.4" do
- Chef::Version.new("1.04").should == Chef::Version.new("1.4")
+ expect(Chef::Version.new("1.04")).to eq(Chef::Version.new("1.4"))
end
it "should treat versions as numbers in the right way" do
- Chef::Version.new("2.0").should be < Chef::Version.new("11.0")
+ expect(Chef::Version.new("2.0")).to be < Chef::Version.new("11.0")
end
it "should sort based on the version number" do
@@ -95,9 +95,9 @@ describe Chef::Version do
examples.each do |smaller, larger|
sm = Chef::Version.new(smaller)
lg = Chef::Version.new(larger)
- sm.should be < lg
- lg.should be > sm
- sm.should_not == lg
+ expect(sm).to be < lg
+ expect(lg).to be > sm
+ expect(sm).not_to eq(lg)
end
end
@@ -106,7 +106,7 @@ describe Chef::Version do
Chef::Version.new(s)
end
got = a.sort.map {|v| v.to_s }
- got.should == %w{0.0.0 0.0.1 0.1.0 0.1.1 1.0.0 1.1.0 1.1.1}
+ expect(got).to eq(%w{0.0.0 0.0.1 0.1.0 0.1.1 1.0.0 1.1.0 1.1.1})
end
it "should sort an array of versions, part 2" do
@@ -114,7 +114,7 @@ describe Chef::Version do
Chef::Version.new(s)
end
got = a.sort.map { |v| v.to_s }
- got.should == %w{0.8.6 1.0.0 1.2.3 3.5.7 4.4.6 4.5.5 4.5.6 5.9.8 9.8.7}
+ expect(got).to eq(%w{0.8.6 1.0.0 1.2.3 3.5.7 4.4.6 4.5.5 4.5.6 5.9.8 9.8.7})
end
describe "comparison examples" do
@@ -163,7 +163,7 @@ describe Chef::Version do
it "(#{spec.first(3).join(' ')}) should be #{spec[3]}" do
got = Chef::Version.new(spec[0]).send(spec[1],
Chef::Version.new(spec[2]))
- got.should == spec[3]
+ expect(got).to eq(spec[3])
end
end
end
diff --git a/spec/unit/version_constraint/platform_spec.rb b/spec/unit/version_constraint/platform_spec.rb
index a3599aeb96..f38eb49689 100644
--- a/spec/unit/version_constraint/platform_spec.rb
+++ b/spec/unit/version_constraint/platform_spec.rb
@@ -21,24 +21,24 @@ describe Chef::VersionConstraint::Platform do
it "is a subclass of Chef::VersionConstraint" do
v = Chef::VersionConstraint::Platform.new
- v.should be_an_instance_of(Chef::VersionConstraint::Platform)
- v.should be_a_kind_of(Chef::VersionConstraint)
+ expect(v).to be_an_instance_of(Chef::VersionConstraint::Platform)
+ expect(v).to be_a_kind_of(Chef::VersionConstraint)
end
it "should work with Chef::Version::Platform classes" do
vc = Chef::VersionConstraint::Platform.new("1.0")
- vc.version.should be_an_instance_of(Chef::Version::Platform)
+ expect(vc.version).to be_an_instance_of(Chef::Version::Platform)
end
describe "include?" do
it "pessimistic ~> x" do
vc = Chef::VersionConstraint::Platform.new "~> 1"
- vc.should include "1.3.3"
- vc.should include "1.4"
+ expect(vc).to include "1.3.3"
+ expect(vc).to include "1.4"
- vc.should_not include "2.2"
- vc.should_not include "0.3.0"
+ expect(vc).not_to include "2.2"
+ expect(vc).not_to include "0.3.0"
end
end
diff --git a/spec/unit/version_constraint_spec.rb b/spec/unit/version_constraint_spec.rb
index dfa4740d51..0ae502f66d 100644
--- a/spec/unit/version_constraint_spec.rb
+++ b/spec/unit/version_constraint_spec.rb
@@ -26,18 +26,18 @@ describe Chef::VersionConstraint do
v_error = Chef::Exceptions::InvalidCookbookVersion
bad_version.each do |s|
it "should raise #{v_error} when given #{s}" do
- lambda { Chef::VersionConstraint.new s }.should raise_error(v_error)
+ expect { Chef::VersionConstraint.new s }.to raise_error(v_error)
end
end
bad_op.each do |s|
it "should raise #{o_error} when given #{s}" do
- lambda { Chef::VersionConstraint.new s }.should raise_error(o_error)
+ expect { Chef::VersionConstraint.new s }.to raise_error(o_error)
end
end
it "should interpret a lone version number as implicit = OP" do
vc = Chef::VersionConstraint.new("1.2.3")
- vc.to_s.should == "= 1.2.3"
+ expect(vc.to_s).to eq("= 1.2.3")
end
it "should allow initialization with [] for back compatibility" do
@@ -52,28 +52,28 @@ describe Chef::VersionConstraint do
it "should default to >= 0.0.0" do
vc = Chef::VersionConstraint.new
- vc.to_s.should == ">= 0.0.0"
+ expect(vc.to_s).to eq(">= 0.0.0")
end
it "should default to >= 0.0.0 when initialized with nil" do
- Chef::VersionConstraint.new(nil).to_s.should == ">= 0.0.0"
+ expect(Chef::VersionConstraint.new(nil).to_s).to eq(">= 0.0.0")
end
it "should work with Chef::Version classes" do
vc = Chef::VersionConstraint.new("1.0")
- vc.version.should be_an_instance_of(Chef::Version)
+ expect(vc.version).to be_an_instance_of(Chef::Version)
end
it "should allow ops without space separator" do
- Chef::VersionConstraint.new("=1.2.3").should eql(Chef::VersionConstraint.new("= 1.2.3"))
- Chef::VersionConstraint.new(">1.2.3").should eql(Chef::VersionConstraint.new("> 1.2.3"))
- Chef::VersionConstraint.new("<1.2.3").should eql(Chef::VersionConstraint.new("< 1.2.3"))
- Chef::VersionConstraint.new(">=1.2.3").should eql(Chef::VersionConstraint.new(">= 1.2.3"))
- Chef::VersionConstraint.new("<=1.2.3").should eql(Chef::VersionConstraint.new("<= 1.2.3"))
+ expect(Chef::VersionConstraint.new("=1.2.3")).to eql(Chef::VersionConstraint.new("= 1.2.3"))
+ expect(Chef::VersionConstraint.new(">1.2.3")).to eql(Chef::VersionConstraint.new("> 1.2.3"))
+ expect(Chef::VersionConstraint.new("<1.2.3")).to eql(Chef::VersionConstraint.new("< 1.2.3"))
+ expect(Chef::VersionConstraint.new(">=1.2.3")).to eql(Chef::VersionConstraint.new(">= 1.2.3"))
+ expect(Chef::VersionConstraint.new("<=1.2.3")).to eql(Chef::VersionConstraint.new("<= 1.2.3"))
end
it "should allow ops with multiple spaces" do
- Chef::VersionConstraint.new("= 1.2.3").should eql(Chef::VersionConstraint.new("= 1.2.3"))
+ expect(Chef::VersionConstraint.new("= 1.2.3")).to eql(Chef::VersionConstraint.new("= 1.2.3"))
end
describe "include?" do
@@ -82,70 +82,70 @@ describe Chef::VersionConstraint do
@vc = Chef::VersionConstraint.new "> 1.2.3"
end
it "String" do
- @vc.should include "1.4"
+ expect(@vc).to include "1.4"
end
it "Chef::Version" do
- @vc.should include Chef::Version.new("1.4")
+ expect(@vc).to include Chef::Version.new("1.4")
end
it "Chef::CookbookVersion" do
cv = Chef::CookbookVersion.new("alice", '/tmp/blah.txt')
cv.version = "1.4"
- @vc.should include cv
+ expect(@vc).to include cv
end
end
it "strictly less than" do
vc = Chef::VersionConstraint.new "< 1.2.3"
- vc.should_not include "1.3.0"
- vc.should_not include "1.2.3"
- vc.should include "1.2.2"
+ expect(vc).not_to include "1.3.0"
+ expect(vc).not_to include "1.2.3"
+ expect(vc).to include "1.2.2"
end
it "strictly greater than" do
vc = Chef::VersionConstraint.new "> 1.2.3"
- vc.should include "1.3.0"
- vc.should_not include "1.2.3"
- vc.should_not include "1.2.2"
+ expect(vc).to include "1.3.0"
+ expect(vc).not_to include "1.2.3"
+ expect(vc).not_to include "1.2.2"
end
it "less than or equal to" do
vc = Chef::VersionConstraint.new "<= 1.2.3"
- vc.should_not include "1.3.0"
- vc.should include "1.2.3"
- vc.should include "1.2.2"
+ expect(vc).not_to include "1.3.0"
+ expect(vc).to include "1.2.3"
+ expect(vc).to include "1.2.2"
end
it "greater than or equal to" do
vc = Chef::VersionConstraint.new ">= 1.2.3"
- vc.should include "1.3.0"
- vc.should include "1.2.3"
- vc.should_not include "1.2.2"
+ expect(vc).to include "1.3.0"
+ expect(vc).to include "1.2.3"
+ expect(vc).not_to include "1.2.2"
end
it "equal to" do
vc = Chef::VersionConstraint.new "= 1.2.3"
- vc.should_not include "1.3.0"
- vc.should include "1.2.3"
- vc.should_not include "0.3.0"
+ expect(vc).not_to include "1.3.0"
+ expect(vc).to include "1.2.3"
+ expect(vc).not_to include "0.3.0"
end
it "pessimistic ~> x.y.z" do
vc = Chef::VersionConstraint.new "~> 1.2.3"
- vc.should include "1.2.3"
- vc.should include "1.2.4"
+ expect(vc).to include "1.2.3"
+ expect(vc).to include "1.2.4"
- vc.should_not include "1.2.2"
- vc.should_not include "1.3.0"
- vc.should_not include "2.0.0"
+ expect(vc).not_to include "1.2.2"
+ expect(vc).not_to include "1.3.0"
+ expect(vc).not_to include "2.0.0"
end
it "pessimistic ~> x.y" do
vc = Chef::VersionConstraint.new "~> 1.2"
- vc.should include "1.3.3"
- vc.should include "1.4"
+ expect(vc).to include "1.3.3"
+ expect(vc).to include "1.4"
- vc.should_not include "2.2"
- vc.should_not include "0.3.0"
+ expect(vc).not_to include "2.2"
+ expect(vc).not_to include "0.3.0"
end
end
@@ -153,13 +153,13 @@ describe Chef::VersionConstraint do
it 'shows a patch-level if one is given' do
vc = Chef::VersionConstraint.new '~> 1.2.0'
- vc.to_s.should == '~> 1.2.0'
+ expect(vc.to_s).to eq('~> 1.2.0')
end
it 'shows no patch-level if one is not given' do
vc = Chef::VersionConstraint.new '~> 1.2'
- vc.to_s.should == '~> 1.2'
+ expect(vc.to_s).to eq('~> 1.2')
end
end
@@ -167,13 +167,13 @@ describe Chef::VersionConstraint do
it 'shows a patch-level if one is given' do
vc = Chef::VersionConstraint.new '~> 1.2.0'
- vc.inspect.should == '(~> 1.2.0)'
+ expect(vc.inspect).to eq('(~> 1.2.0)')
end
it 'shows no patch-level if one is not given' do
vc = Chef::VersionConstraint.new '~> 1.2'
- vc.inspect.should == '(~> 1.2)'
+ expect(vc.inspect).to eq('(~> 1.2)')
end
end
end
diff --git a/spec/unit/windows_service_spec.rb b/spec/unit/windows_service_spec.rb
index ba3d2980df..cf933a9ab2 100644
--- a/spec/unit/windows_service_spec.rb
+++ b/spec/unit/windows_service_spec.rb
@@ -25,29 +25,29 @@ describe "Chef::Application::WindowsService", :windows_only do
let (:shell_out_result) {Object.new}
let (:tempfile) {Tempfile.new "log_file"}
before do
- instance.stub(:parse_options)
- shell_out_result.stub(:stdout)
- shell_out_result.stub(:stderr)
+ allow(instance).to receive(:parse_options)
+ allow(shell_out_result).to receive(:stdout)
+ allow(shell_out_result).to receive(:stderr)
end
it "runs chef-client in new process" do
- instance.should_receive(:configure_chef).twice
+ expect(instance).to receive(:configure_chef).twice
instance.service_init
- instance.should_receive(:run_chef_client).and_call_original
- instance.should_receive(:shell_out).and_return(shell_out_result)
- instance.stub(:running?).and_return(true, false)
- instance.instance_variable_get(:@service_signal).stub(:wait)
- instance.stub(:state).and_return(4)
+ expect(instance).to receive(:run_chef_client).and_call_original
+ expect(instance).to receive(:shell_out).and_return(shell_out_result)
+ allow(instance).to receive(:running?).and_return(true, false)
+ allow(instance.instance_variable_get(:@service_signal)).to receive(:wait)
+ allow(instance).to receive(:state).and_return(4)
instance.service_main
end
it "passes config params to new process" do
Chef::Config.merge!({:log_location => tempfile.path, :config_file => "test_config_file", :log_level => :info})
- instance.should_receive(:configure_chef).twice
+ expect(instance).to receive(:configure_chef).twice
instance.service_init
- instance.stub(:running?).and_return(true, false)
- instance.instance_variable_get(:@service_signal).stub(:wait)
- instance.stub(:state).and_return(4)
- instance.should_receive(:run_chef_client).and_call_original
- instance.should_receive(:shell_out).with("chef-client --no-fork -c test_config_file -L #{tempfile.path}").and_return(shell_out_result)
+ allow(instance).to receive(:running?).and_return(true, false)
+ allow(instance.instance_variable_get(:@service_signal)).to receive(:wait)
+ allow(instance).to receive(:state).and_return(4)
+ expect(instance).to receive(:run_chef_client).and_call_original
+ expect(instance).to receive(:shell_out).with("chef-client --no-fork -c test_config_file -L #{tempfile.path}").and_return(shell_out_result)
instance.service_main
tempfile.unlink
end
diff --git a/spec/unit/workstation_config_loader_spec.rb b/spec/unit/workstation_config_loader_spec.rb
index de108ff6d7..a865103188 100644
--- a/spec/unit/workstation_config_loader_spec.rb
+++ b/spec/unit/workstation_config_loader_spec.rb
@@ -177,7 +177,7 @@ describe Chef::WorkstationConfigLoader do
env["CD"] = "/home/someuser/prod/chef-repo" # windows
env["PWD"] = "/home/someuser/prod/chef-repo" # unix
- Dir.stub(:pwd).and_return("/home/someuser/codes/chef-repo")
+ allow(Dir).to receive(:pwd).and_return("/home/someuser/codes/chef-repo")
end
it "loads the config from the non-dereferenced directory path" do
@@ -219,7 +219,7 @@ describe Chef::WorkstationConfigLoader do
end
- context "when an explict config is given but it doesn't exist" do
+ context "when an explicit config is given but it doesn't exist" do
let(:explicit_config_location) { "/nope/nope/nope/frab/jab/nab" }
diff --git a/tasks/rspec.rb b/tasks/rspec.rb
index 95ae274955..a6fc5a9180 100644
--- a/tasks/rspec.rb
+++ b/tasks/rspec.rb
@@ -27,28 +27,16 @@ begin
task :default => :spec
- desc "Run all specs in spec directory"
+ desc "Run standard specs (minus long running specs)"
RSpec::Core::RakeTask.new(:spec) do |t|
- t.rspec_opts = ['--options', "\"#{CHEF_ROOT}/.rspec\""]
- t.pattern = FileList['spec/**/*_spec.rb']
- end
-
- desc "Run all functional specs (in functional/ directory)"
- RSpec::Core::RakeTask.new(:functional) do |t|
- t.rspec_opts = ['--options', "\"#{CHEF_ROOT}/spec/spec.opts\""]
- t.pattern = FileList['spec/functional/**/*_spec.rb']
- end
-
- desc "Run the rspec tests with activesupport loaded"
- RSpec::Core::RakeTask.new(:spec_activesupport) do |t|
- t.rspec_opts = ['--options', "\"#{CHEF_ROOT}/.rspec\"", "--require active_support/core_ext"]
- t.pattern = FileList['spec/unit/**/*_spec.rb']
+ # right now this just limits to functional + unit, but could also remove
+ # individual tests marked long-running
+ t.pattern = FileList['spec/{functional,unit}/**/*_spec.rb']
end
namespace :spec do
desc "Run all specs in spec directory with RCov"
RSpec::Core::RakeTask.new(:rcov) do |t|
- t.rspec_opts = ['--options', "\"#{CHEF_ROOT}/spec/spec.opts\""]
t.pattern = FileList['spec/**/*_spec.rb']
t.rcov = true
t.rcov_opts = lambda do
@@ -56,16 +44,26 @@ begin
end
end
+ desc "Run all specs in spec directory"
+ RSpec::Core::RakeTask.new(:all) do |t|
+ t.pattern = FileList['spec/**/*_spec.rb']
+ end
+
desc "Print Specdoc for all specs"
RSpec::Core::RakeTask.new(:doc) do |t|
t.rspec_opts = ["--format", "specdoc", "--dry-run"]
t.pattern = FileList['spec/**/*_spec.rb']
end
- [:unit].each do |sub|
+ desc "Run the specs under spec/unit with activesupport loaded"
+ RSpec::Core::RakeTask.new(:activesupport) do |t|
+ t.rspec_opts = ["--require active_support/core_ext"]
+ t.pattern = FileList['spec/unit/**/*_spec.rb']
+ end
+
+ [:unit, :functional, :integration, :stress].each do |sub|
desc "Run the specs under spec/#{sub}"
RSpec::Core::RakeTask.new(sub) do |t|
- t.rspec_opts = ['--options', "\"#{CHEF_ROOT}/spec/spec.opts\""]
t.pattern = FileList["spec/#{sub}/**/*_spec.rb"]
end
end