summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaire McQuin <claire@getchef.com>2014-10-31 16:40:02 -0700
committerClaire McQuin <claire@getchef.com>2014-10-31 16:40:02 -0700
commitd24a4a16a6e1d571c6f70e11340b0e1695ff92d9 (patch)
tree4bd7a0c2761db1e8b51de86ab9144676bb4526d2
parent4996f445cc66e3ac8c5602ff86aa0091e5ffe5bd (diff)
parent48c62d5a7c0348f2db607d80cb1b56e9fe62d693 (diff)
downloadchef-d24a4a16a6e1d571c6f70e11340b0e1695ff92d9.tar.gz
Merge branch 'audit-mode' into runner
-rw-r--r--.travis.yml5
-rw-r--r--CHANGELOG.md1
-rw-r--r--kitchen-tests/.kitchen.travis.yml14
-rw-r--r--kitchen-tests/.kitchen.yml24
-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/application.rb606
-rw-r--r--lib/chef/audit/chef_json_formatter.rb88
-rw-r--r--lib/chef/audit/control_group_data.rb84
-rw-r--r--lib/chef/chef_fs/file_system/base_fs_dir.rb5
-rw-r--r--lib/chef/provider/service/aix.rb2
-rw-r--r--lib/chef/resource/windows_package.rb2
-rw-r--r--spec/functional/resource/base.rb1
-rw-r--r--spec/functional/resource/cron_spec.rb4
-rw-r--r--spec/spec_helper.rb2
-rw-r--r--spec/support/shared/functional/windows_script.rb2
-rw-r--r--spec/unit/chef_fs/file_system_spec.rb23
-rw-r--r--spec/unit/resource/windows_package_spec.rb6
26 files changed, 652 insertions, 373 deletions
diff --git a/.travis.yml b/.travis.yml
index 65d28d0f68..dcc93fde32 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -40,9 +40,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 a388733423..c98c58d9c5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -398,3 +398,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/kitchen-tests/.kitchen.travis.yml b/kitchen-tests/.kitchen.travis.yml
index 4fd6a78900..66bbe23f64 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: true
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/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/application.rb b/lib/chef/application.rb
index abcc81c290..a2718e7556 100644
--- a/lib/chef/application.rb
+++ b/lib/chef/application.rb
@@ -28,370 +28,372 @@ require 'mixlib/cli'
require 'tmpdir'
require 'rbconfig'
-class Chef::Application
- include Mixlib::CLI
+class Chef
+ class Application
+ include Mixlib::CLI
- def initialize
- super
+ def initialize
+ super
- @chef_client = nil
- @chef_client_json = nil
-
- # Always switch to a readable directory. Keeps subsequent Dir.chdir() {}
- # from failing due to permissions when launched as a less privileged user.
- end
-
- # Reconfigure the application. You'll want to override and super this method.
- def reconfigure
- configure_chef
- configure_logging
- configure_proxy_environment_variables
- configure_encoding
- end
+ @chef_client = nil
+ @chef_client_json = nil
- # Get this party started
- def run
- setup_signal_handlers
- reconfigure
- setup_application
- run_application
- end
+ # Always switch to a readable directory. Keeps subsequent Dir.chdir() {}
+ # from failing due to permissions when launched as a less privileged user.
+ end
- def setup_signal_handlers
- trap("INT") do
- Chef::Application.fatal!("SIGINT received, stopping", 2)
+ # Reconfigure the application. You'll want to override and super this method.
+ def reconfigure
+ configure_chef
+ configure_logging
+ configure_proxy_environment_variables
+ configure_encoding
end
- trap("TERM") do
- Chef::Application.fatal!("SIGTERM received, stopping", 3)
+ # Get this party started
+ def run
+ setup_signal_handlers
+ reconfigure
+ setup_application
+ run_application
end
- unless Chef::Platform.windows?
- trap("QUIT") do
- Chef::Log.info("SIGQUIT received, call stack:\n " + caller.join("\n "))
+ def setup_signal_handlers
+ trap("INT") do
+ Chef::Application.fatal!("SIGINT received, stopping", 2)
end
- trap("HUP") do
- Chef::Log.info("SIGHUP received, reconfiguring")
- reconfigure
+ trap("TERM") do
+ Chef::Application.fatal!("SIGTERM received, stopping", 3)
+ end
+
+ unless Chef::Platform.windows?
+ trap("QUIT") do
+ Chef::Log.info("SIGQUIT received, call stack:\n " + caller.join("\n "))
+ end
+
+ trap("HUP") do
+ Chef::Log.info("SIGHUP received, reconfiguring")
+ reconfigure
+ end
end
end
- end
- # Parse configuration (options and config file)
- def configure_chef
- parse_options
- load_config_file
- end
+ # Parse configuration (options and config file)
+ def configure_chef
+ parse_options
+ load_config_file
+ end
- # Parse the config file
- def load_config_file
- config_fetcher = Chef::ConfigFetcher.new(config[:config_file])
- if config[:config_file].nil?
- Chef::Log.warn("No config file found or specified on command line, using command line options.")
- elsif config_fetcher.config_missing?
- pp config_missing: true
- Chef::Log.warn("*****************************************")
- Chef::Log.warn("Did not find config file: #{config[:config_file]}, using command line options.")
- Chef::Log.warn("*****************************************")
- else
- config_content = config_fetcher.read_config
- apply_config(config_content, config[:config_file])
+ # Parse the config file
+ def load_config_file
+ config_fetcher = Chef::ConfigFetcher.new(config[:config_file])
+ if config[:config_file].nil?
+ Chef::Log.warn("No config file found or specified on command line, using command line options.")
+ elsif config_fetcher.config_missing?
+ pp config_missing: true
+ Chef::Log.warn("*****************************************")
+ Chef::Log.warn("Did not find config file: #{config[:config_file]}, using command line options.")
+ Chef::Log.warn("*****************************************")
+ else
+ config_content = config_fetcher.read_config
+ apply_config(config_content, config[:config_file])
+ end
+ Chef::Config.merge!(config)
end
- Chef::Config.merge!(config)
- end
- # Initialize and configure the logger.
- # === Loggers and Formatters
- # In Chef 10.x and previous, the Logger was the primary/only way that Chef
- # communicated information to the user. In Chef 10.14, a new system, "output
- # formatters" was added, and in Chef 11.0+ it is the default when running
- # chef in a console (detected by `STDOUT.tty?`). Because output formatters
- # are more complex than the logger system and users have less experience with
- # them, the config option `force_logger` is provided to restore the Chef 10.x
- # behavior.
- #
- # Conversely, for users who want formatter output even when chef is running
- # unattended, the `force_formatter` option is provided.
- #
- # === Auto Log Level
- # When `log_level` is set to `:auto` (default), the log level will be `:warn`
- # when the primary output mode is an output formatter (see
- # +using_output_formatter?+) and `:info` otherwise.
- #
- # === Automatic STDOUT Logging
- # When `force_logger` is configured (e.g., Chef 10 mode), a second logger
- # with output on STDOUT is added when running in a console (STDOUT is a tty)
- # and the configured log_location isn't STDOUT. This accounts for the case
- # that a user has configured a log_location in client.rb, but is running
- # chef-client by hand to troubleshoot a problem.
- def configure_logging
- Chef::Log.init(MonoLogger.new(Chef::Config[:log_location]))
- if want_additional_logger?
- configure_stdout_logger
+ # Initialize and configure the logger.
+ # === Loggers and Formatters
+ # In Chef 10.x and previous, the Logger was the primary/only way that Chef
+ # communicated information to the user. In Chef 10.14, a new system, "output
+ # formatters" was added, and in Chef 11.0+ it is the default when running
+ # chef in a console (detected by `STDOUT.tty?`). Because output formatters
+ # are more complex than the logger system and users have less experience with
+ # them, the config option `force_logger` is provided to restore the Chef 10.x
+ # behavior.
+ #
+ # Conversely, for users who want formatter output even when chef is running
+ # unattended, the `force_formatter` option is provided.
+ #
+ # === Auto Log Level
+ # When `log_level` is set to `:auto` (default), the log level will be `:warn`
+ # when the primary output mode is an output formatter (see
+ # +using_output_formatter?+) and `:info` otherwise.
+ #
+ # === Automatic STDOUT Logging
+ # When `force_logger` is configured (e.g., Chef 10 mode), a second logger
+ # with output on STDOUT is added when running in a console (STDOUT is a tty)
+ # and the configured log_location isn't STDOUT. This accounts for the case
+ # that a user has configured a log_location in client.rb, but is running
+ # chef-client by hand to troubleshoot a problem.
+ def configure_logging
+ Chef::Log.init(MonoLogger.new(Chef::Config[:log_location]))
+ if want_additional_logger?
+ configure_stdout_logger
+ end
+ Chef::Log.level = resolve_log_level
+ rescue StandardError => error
+ Chef::Log.fatal("Failed to open or create log file at #{Chef::Config[:log_location]}: #{error.class} (#{error.message})")
+ Chef::Application.fatal!("Aborting due to invalid 'log_location' configuration", 2)
end
- Chef::Log.level = resolve_log_level
- rescue StandardError => error
- Chef::Log.fatal("Failed to open or create log file at #{Chef::Config[:log_location]}: #{error.class} (#{error.message})")
- Chef::Application.fatal!("Aborting due to invalid 'log_location' configuration", 2)
- end
- def configure_stdout_logger
- stdout_logger = MonoLogger.new(STDOUT)
- stdout_logger.formatter = Chef::Log.logger.formatter
- Chef::Log.loggers << stdout_logger
- end
+ def configure_stdout_logger
+ stdout_logger = MonoLogger.new(STDOUT)
+ stdout_logger.formatter = Chef::Log.logger.formatter
+ Chef::Log.loggers << stdout_logger
+ end
- # Based on config and whether or not STDOUT is a tty, should we setup a
- # secondary logger for stdout?
- def want_additional_logger?
- ( Chef::Config[:log_location] != STDOUT ) && STDOUT.tty? && (!Chef::Config[:daemonize]) && (Chef::Config[:force_logger])
- end
+ # Based on config and whether or not STDOUT is a tty, should we setup a
+ # secondary logger for stdout?
+ def want_additional_logger?
+ ( Chef::Config[:log_location] != STDOUT ) && STDOUT.tty? && (!Chef::Config[:daemonize]) && (Chef::Config[:force_logger])
+ end
- # Use of output formatters is assumed if `force_formatter` is set or if
- # `force_logger` is not set and STDOUT is to a console (tty)
- def using_output_formatter?
- Chef::Config[:force_formatter] || (!Chef::Config[:force_logger] && STDOUT.tty?)
- end
+ # Use of output formatters is assumed if `force_formatter` is set or if
+ # `force_logger` is not set and STDOUT is to a console (tty)
+ def using_output_formatter?
+ Chef::Config[:force_formatter] || (!Chef::Config[:force_logger] && STDOUT.tty?)
+ end
- def auto_log_level?
- Chef::Config[:log_level] == :auto
- end
+ def auto_log_level?
+ Chef::Config[:log_level] == :auto
+ end
- # if log_level is `:auto`, convert it to :warn (when using output formatter)
- # or :info (no output formatter). See also +using_output_formatter?+
- def resolve_log_level
- if auto_log_level?
- if using_output_formatter?
- :warn
+ # if log_level is `:auto`, convert it to :warn (when using output formatter)
+ # or :info (no output formatter). See also +using_output_formatter?+
+ def resolve_log_level
+ if auto_log_level?
+ if using_output_formatter?
+ :warn
+ else
+ :info
+ end
else
- :info
+ Chef::Config[:log_level]
end
- else
- Chef::Config[:log_level]
end
- end
- # Configure and set any proxy environment variables according to the config.
- def configure_proxy_environment_variables
- configure_http_proxy
- configure_https_proxy
- configure_ftp_proxy
- configure_no_proxy
- end
-
- # Sets the default external encoding to UTF-8 (users can change this, but they shouldn't)
- def configure_encoding
- Encoding.default_external = Chef::Config[:ruby_encoding]
- end
+ # Configure and set any proxy environment variables according to the config.
+ def configure_proxy_environment_variables
+ configure_http_proxy
+ configure_https_proxy
+ configure_ftp_proxy
+ configure_no_proxy
+ end
- # Called prior to starting the application, by the run method
- def setup_application
- raise Chef::Exceptions::Application, "#{self.to_s}: you must override setup_application"
- end
+ # Sets the default external encoding to UTF-8 (users can change this, but they shouldn't)
+ def configure_encoding
+ Encoding.default_external = Chef::Config[:ruby_encoding]
+ end
- # Actually run the application
- def run_application
- raise Chef::Exceptions::Application, "#{self.to_s}: you must override run_application"
- end
+ # Called prior to starting the application, by the run method
+ def setup_application
+ raise Chef::Exceptions::Application, "#{self.to_s}: you must override setup_application"
+ end
- # Initializes Chef::Client instance and runs it
- def run_chef_client(specific_recipes = [])
- Chef::LocalMode.with_server_connectivity do
- override_runlist = config[:override_runlist]
- if specific_recipes.size > 0
- override_runlist ||= []
- end
- @chef_client = Chef::Client.new(
- @chef_client_json,
- :override_runlist => config[:override_runlist],
- :specific_recipes => specific_recipes,
- :runlist => config[:runlist]
- )
- @chef_client_json = nil
+ # Actually run the application
+ def run_application
+ raise Chef::Exceptions::Application, "#{self.to_s}: you must override run_application"
+ end
- if can_fork?
- fork_chef_client # allowed to run client in forked process
- else
- # Unforked interval runs are disabled, so this runs chef-client
- # once and then exits. If TERM signal is received, will "ignore"
- # the signal to finish converge.
- run_with_graceful_exit_option
+ # Initializes Chef::Client instance and runs it
+ def run_chef_client(specific_recipes = [])
+ Chef::LocalMode.with_server_connectivity do
+ override_runlist = config[:override_runlist]
+ if specific_recipes.size > 0
+ override_runlist ||= []
+ end
+ @chef_client = Chef::Client.new(
+ @chef_client_json,
+ :override_runlist => config[:override_runlist],
+ :specific_recipes => specific_recipes,
+ :runlist => config[:runlist]
+ )
+ @chef_client_json = nil
+
+ if can_fork?
+ fork_chef_client # allowed to run client in forked process
+ else
+ # Unforked interval runs are disabled, so this runs chef-client
+ # once and then exits. If TERM signal is received, will "ignore"
+ # the signal to finish converge.
+ run_with_graceful_exit_option
+ end
+ @chef_client = nil
end
- @chef_client = nil
end
- end
- 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
- # running on is not windows before forking.
- Chef::Config[:client_fork] && Process.respond_to?(:fork) && !Chef::Platform.windows?
- end
-
- # Run chef-client once and then exit. If TERM signal is received, ignores the
- # signal to finish the converge and exists.
- def run_with_graceful_exit_option
- # Override the TERM signal.
- trap('TERM') do
- Chef::Log.debug("SIGTERM received during converge," +
- " finishing converge to exit normally (send SIGINT to terminate immediately)")
+ 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
+ # running on is not windows before forking.
+ Chef::Config[:client_fork] && Process.respond_to?(:fork) && !Chef::Platform.windows?
end
- @chef_client.run
- true
- end
-
- def fork_chef_client
- Chef::Log.info "Forking chef instance to converge..."
- pid = fork do
- # Want to allow forked processes to finish converging when
- # TERM singal is received (exit gracefully)
+ # Run chef-client once and then exit. If TERM signal is received, ignores the
+ # signal to finish the converge and exists.
+ def run_with_graceful_exit_option
+ # 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
- client_solo = Chef::Config[:solo] ? "chef-solo" : "chef-client"
- $0 = "#{client_solo} worker: ppid=#{Process.ppid};start=#{Time.new.strftime("%R:%S")};"
- begin
- Chef::Log.debug "Forked instance now converging"
- @chef_client.run
- rescue Exception => e
- Chef::Log.error(e.to_s)
- exit 1
- else
- exit 0
+ @chef_client.run
+ true
+ end
+
+ def fork_chef_client
+ Chef::Log.info "Forking chef instance to converge..."
+ pid = fork do
+ # Want to allow forked processes to finish converging when
+ # 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)")
+ end
+
+ client_solo = Chef::Config[:solo] ? "chef-solo" : "chef-client"
+ $0 = "#{client_solo} worker: ppid=#{Process.ppid};start=#{Time.new.strftime("%R:%S")};"
+ begin
+ Chef::Log.debug "Forked instance now converging"
+ @chef_client.run
+ rescue Exception => e
+ Chef::Log.error(e.to_s)
+ exit 1
+ else
+ exit 0
+ end
end
+ Chef::Log.debug "Fork successful. Waiting for new chef pid: #{pid}"
+ result = Process.waitpid2(pid)
+ handle_child_exit(result)
+ Chef::Log.debug "Forked instance successfully reaped (pid: #{pid})"
+ true
end
- Chef::Log.debug "Fork successful. Waiting for new chef pid: #{pid}"
- result = Process.waitpid2(pid)
- handle_child_exit(result)
- Chef::Log.debug "Forked instance successfully reaped (pid: #{pid})"
- true
- end
- def handle_child_exit(pid_and_status)
- status = pid_and_status[1]
- return true if status.success?
- message = if status.signaled?
- "Chef run process terminated by signal #{status.termsig} (#{Signal.list.invert[status.termsig]})"
- else
- "Chef run process exited unsuccessfully (exit code #{status.exitstatus})"
+ def handle_child_exit(pid_and_status)
+ status = pid_and_status[1]
+ return true if status.success?
+ message = if status.signaled?
+ "Chef run process terminated by signal #{status.termsig} (#{Signal.list.invert[status.termsig]})"
+ else
+ "Chef run process exited unsuccessfully (exit code #{status.exitstatus})"
+ end
+ raise Exceptions::ChildConvergeError, message
end
- raise Exceptions::ChildConvergeError, message
- end
- def apply_config(config_content, config_file_path)
- Chef::Config.from_string(config_content, config_file_path)
- rescue Exception => error
- Chef::Log.fatal("Configuration error #{error.class}: #{error.message}")
- filtered_trace = error.backtrace.grep(/#{Regexp.escape(config_file_path)}/)
- filtered_trace.each {|line| Chef::Log.fatal(" " + line )}
- Chef::Application.fatal!("Aborting due to error in '#{config_file_path}'", 2)
- end
+ def apply_config(config_content, config_file_path)
+ Chef::Config.from_string(config_content, config_file_path)
+ rescue Exception => error
+ Chef::Log.fatal("Configuration error #{error.class}: #{error.message}")
+ filtered_trace = error.backtrace.grep(/#{Regexp.escape(config_file_path)}/)
+ filtered_trace.each {|line| Chef::Log.fatal(" " + line )}
+ Chef::Application.fatal!("Aborting due to error in '#{config_file_path}'", 2)
+ end
- # Set ENV['http_proxy']
- 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])
- env['http_proxy'] = http_proxy_string unless env['http_proxy']
- env['HTTP_PROXY'] = http_proxy_string unless env['HTTP_PROXY']
+ # Set ENV['http_proxy']
+ 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])
+ env['http_proxy'] = http_proxy_string unless env['http_proxy']
+ env['HTTP_PROXY'] = http_proxy_string unless env['HTTP_PROXY']
+ end
end
- end
- # Set ENV['https_proxy']
- 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])
- env['https_proxy'] = https_proxy_string unless env['https_proxy']
- env['HTTPS_PROXY'] = https_proxy_string unless env['HTTPS_PROXY']
+ # Set ENV['https_proxy']
+ 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])
+ env['https_proxy'] = https_proxy_string unless env['https_proxy']
+ env['HTTPS_PROXY'] = https_proxy_string unless env['HTTPS_PROXY']
+ end
end
- end
- # Set ENV['ftp_proxy']
- 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])
- env['ftp_proxy'] = ftp_proxy_string unless env['ftp_proxy']
- env['FTP_PROXY'] = ftp_proxy_string unless env['FTP_PROXY']
+ # Set ENV['ftp_proxy']
+ 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])
+ env['ftp_proxy'] = ftp_proxy_string unless env['ftp_proxy']
+ env['FTP_PROXY'] = ftp_proxy_string unless env['FTP_PROXY']
+ end
end
- end
- # Set ENV['no_proxy']
- def configure_no_proxy
- if Chef::Config[:no_proxy]
- env['no_proxy'] = Chef::Config[:no_proxy] unless env['no_proxy']
- env['NO_PROXY'] = Chef::Config[:no_proxy] unless env['NO_PROXY']
+ # Set ENV['no_proxy']
+ def configure_no_proxy
+ if Chef::Config[:no_proxy]
+ env['no_proxy'] = Chef::Config[:no_proxy] unless env['no_proxy']
+ env['NO_PROXY'] = Chef::Config[:no_proxy] unless env['NO_PROXY']
+ end
end
- end
- # Builds a proxy uri. Examples:
- # http://username:password@hostname:port
- # https://username@hostname:port
- # ftp://hostname:port
- # when
- # scheme = "http", "https", or "ftp"
- # hostport = hostname:port
- # user = username
- # pass = password
- def configure_proxy(scheme, path, user, pass)
- begin
- path = "#{scheme}://#{path}" unless path.include?('://')
- # URI.split returns the following parts:
- # [scheme, userinfo, host, port, registry, path, opaque, query, fragment]
- parts = URI.split(URI.encode(path))
- # URI::Generic.build requires an integer for the port, but URI::split gives
- # returns a string for the port.
- parts[3] = parts[3].to_i if parts[3]
- if user
- userinfo = URI.encode(URI.encode(user), '@:')
- if pass
- userinfo << ":#{URI.encode(URI.encode(pass), '@:')}"
+ # Builds a proxy uri. Examples:
+ # http://username:password@hostname:port
+ # https://username@hostname:port
+ # ftp://hostname:port
+ # when
+ # scheme = "http", "https", or "ftp"
+ # hostport = hostname:port
+ # user = username
+ # pass = password
+ def configure_proxy(scheme, path, user, pass)
+ begin
+ path = "#{scheme}://#{path}" unless path.include?('://')
+ # URI.split returns the following parts:
+ # [scheme, userinfo, host, port, registry, path, opaque, query, fragment]
+ parts = URI.split(URI.encode(path))
+ # URI::Generic.build requires an integer for the port, but URI::split gives
+ # returns a string for the port.
+ parts[3] = parts[3].to_i if parts[3]
+ if user
+ userinfo = URI.encode(URI.encode(user), '@:')
+ if pass
+ userinfo << ":#{URI.encode(URI.encode(pass), '@:')}"
+ end
+ parts[1] = userinfo
end
- parts[1] = userinfo
+
+ return URI::Generic.build(parts).to_s
+ rescue URI::Error => e
+ # URI::Error messages generally include the offending string. Including a message
+ # for which proxy config item has the issue should help deduce the issue when
+ # the URI::Error message is vague.
+ raise Chef::Exceptions::BadProxyURI, "Cannot configure #{scheme} proxy. Does not comply with URI scheme. #{e.message}"
end
+ end
- return URI::Generic.build(parts).to_s
- rescue URI::Error => e
- # URI::Error messages generally include the offending string. Including a message
- # for which proxy config item has the issue should help deduce the issue when
- # the URI::Error message is vague.
- raise Chef::Exceptions::BadProxyURI, "Cannot configure #{scheme} proxy. Does not comply with URI scheme. #{e.message}"
+ # This is a hook for testing
+ def env
+ ENV
end
- end
- # This is a hook for testing
- def env
- ENV
- end
+ class << self
+ def debug_stacktrace(e)
+ message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
+ chef_stacktrace_out = "Generated at #{Time.now.to_s}\n"
+ chef_stacktrace_out += message
- class << self
- def debug_stacktrace(e)
- message = "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
- chef_stacktrace_out = "Generated at #{Time.now.to_s}\n"
- chef_stacktrace_out += message
+ Chef::FileCache.store("chef-stacktrace.out", chef_stacktrace_out)
+ Chef::Log.fatal("Stacktrace dumped to #{Chef::FileCache.load("chef-stacktrace.out", false)}")
+ Chef::Log.debug(message)
+ true
+ end
- Chef::FileCache.store("chef-stacktrace.out", chef_stacktrace_out)
- Chef::Log.fatal("Stacktrace dumped to #{Chef::FileCache.load("chef-stacktrace.out", false)}")
- Chef::Log.debug(message)
- true
- end
+ # Log a fatal error message to both STDERR and the Logger, exit the application
+ def fatal!(msg, err = -1)
+ Chef::Log.fatal(msg)
+ Process.exit err
+ end
- # Log a fatal error message to both STDERR and the Logger, exit the application
- def fatal!(msg, err = -1)
- Chef::Log.fatal(msg)
- Process.exit err
+ def exit!(msg, err = -1)
+ Chef::Log.debug(msg)
+ Process.exit err
+ end
end
- def exit!(msg, err = -1)
- Chef::Log.debug(msg)
- Process.exit err
- end
end
-
end
diff --git a/lib/chef/audit/chef_json_formatter.rb b/lib/chef/audit/chef_json_formatter.rb
new file mode 100644
index 0000000000..3c164120b4
--- /dev/null
+++ b/lib/chef/audit/chef_json_formatter.rb
@@ -0,0 +1,88 @@
+RSpec::Support.require_rspec_core "formatters/base_formatter"
+require 'control_group_data'
+require 'ffi_yajl'
+
+class Chef
+ class Audit
+ class ChefJsonFormatter < ::RSpec::Core::Formatters::BaseFormatter
+ ::RSpec::Core::Formatters.register self, :example_group_started, :message, :stop, :close, :example_failed
+
+ attr_reader :control_group_data
+
+ # TODO hopefully the runner can take care of this for us since there won't be an outer-most
+ # control group
+ @@outer_example_group_found = false
+
+ def initialize(output)
+ super
+ end
+
+ # Invoked for each `control`, `describe`, `context` block
+ def example_group_started(notification)
+ unless @@outer_example_group_found
+ @control_group_data = ControlGroupData.new(notification.group.description)
+ @@outer_example_group_found = true
+ end
+ end
+
+ def example_failed(notification)
+ e = notification.example.metadata[:execution_result].exception
+ raise e unless e.kind_of? ::RSpec::Expectations::ExpectationNotMetError
+ end
+
+ def message(notification)
+ puts "message: #{notification}"
+ end
+
+ def stop(notification)
+ notification.examples.each do |example|
+ control_data = build_control_from(example)
+ e = example.exception
+ if e
+ control = control_group_data.example_failure(e.message, control_data)
+ else
+ control = control_group_data.example_success(control_data)
+ end
+ control.line_number = example.metadata[:line_number]
+ end
+ end
+
+ def close(notification)
+ output.write FFI_Yajl::Encoder.encode(control_group_data.to_hash, pretty: true)
+ output.close if IO === output && output != $stdout
+ end
+
+ private
+
+ def build_control_from(example)
+ described_class = example.metadata[:described_class]
+ if described_class
+ resource_type = described_class.class.name.split(':')[-1]
+ # TODO submit github PR to expose this
+ resource_name = described_class.instance_variable_get(:@name)
+ end
+
+ 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
+ # TODO remove this when we're no longer wrapping everything with "mysql audit"
+ describe_groups.shift
+
+ {
+ :name => example.description,
+ :desc => example.full_description,
+ :resource_type => resource_type,
+ :resource_name => resource_name,
+ :context => describe_groups
+ }
+ 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..93abfb3c21
--- /dev/null
+++ b/lib/chef/audit/control_group_data.rb
@@ -0,0 +1,84 @@
+class Chef
+ class Audit
+ class ControlGroupData
+ attr_reader :name, :status, :number_success, :number_failed, :controls
+
+ def initialize(name)
+ @status = "success"
+ @controls = []
+ @number_success = 0
+ @number_failed = 0
+ @name = name
+ end
+
+
+ def example_success(opts={})
+ @number_success += 1
+ control = create_control(opts)
+ controls << control
+ control
+ end
+
+ def example_failure(details=nil, opts={})
+ @number_failed += 1
+ @status = "failure"
+ control = create_control(opts)
+ control.details = details if details
+ control.status = "failure"
+ controls << control
+ control
+ end
+
+ def to_hash
+ controls.sort! {|x,y| x.line_number <=> y.line_number}
+ {
+ :control_group => {
+ :name => name,
+ :status => status,
+ :number_success => number_success,
+ :number_failed => number_failed,
+ :controls => controls.collect { |c| c.to_hash }
+ }
+ }
+ end
+
+ private
+
+ def create_control(opts={})
+ name = opts[:name]
+ resource_type = opts[:resource_type]
+ resource_name = opts[:resource_name]
+ context = opts[:context]
+ ControlData.new(name, resource_type, resource_name, context)
+ end
+
+ end
+
+ class ControlData
+ attr_reader :name, :resource_type, :resource_name, :context
+ attr_accessor :status, :details
+ # TODO this only helps with debugging
+ attr_accessor :line_number
+
+ def initialize(name, resource_type, resource_name, context)
+ @context = context
+ @name = name
+ @resource_type = resource_type
+ @resource_name = resource_name
+ end
+
+ def to_hash
+ ret = {
+ :name => name,
+ :status => status,
+ :details => details,
+ :resource_type => resource_type,
+ :resource_name => resource_name
+ }
+ ret[:context] = context || []
+ ret
+ end
+ end
+
+ end
+end
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/provider/service/aix.rb b/lib/chef/provider/service/aix.rb
index 6f70f797b9..0aef62c62e 100644
--- a/lib/chef/provider/service/aix.rb
+++ b/lib/chef/provider/service/aix.rb
@@ -24,6 +24,8 @@ class Chef
class Aix < Chef::Provider::Service
attr_reader :status_load_success
+ provides :service, os: "aix"
+
def initialize(new_resource, run_context)
super
end
diff --git a/lib/chef/resource/windows_package.rb b/lib/chef/resource/windows_package.rb
index c563ba5fdc..9bf3443423 100644
--- a/lib/chef/resource/windows_package.rb
+++ b/lib/chef/resource/windows_package.rb
@@ -43,7 +43,7 @@ class Chef
set_or_return(
:installer_type,
arg,
- :kind_of => [ String ]
+ :kind_of => [ Symbol ]
)
end
diff --git a/spec/functional/resource/base.rb b/spec/functional/resource/base.rb
index cdb52fbc1b..10b26f924f 100644
--- a/spec/functional/resource/base.rb
+++ b/spec/functional/resource/base.rb
@@ -22,6 +22,7 @@ def run_context
node = Chef::Node.new
node.default[:platform] = ohai[:platform]
node.default[:platform_version] = ohai[:platform_version]
+ node.default[:os] = ohai[:os]
events = Chef::EventDispatch::Dispatcher.new
Chef::RunContext.new(node, {}, events)
end
diff --git a/spec/functional/resource/cron_spec.rb b/spec/functional/resource/cron_spec.rb
index 287b5a1391..ed30756583 100644
--- a/spec/functional/resource/cron_spec.rb
+++ b/spec/functional/resource/cron_spec.rb
@@ -56,8 +56,8 @@ describe Chef::Resource::Cron, :requires_root, :unix_only do
let(:new_resource) do
new_resource = Chef::Resource::Cron.new("Chef functional test cron", run_context)
new_resource.user 'root'
- # @hourly is not supported on solaris
- if ohai[:platform] == "solaris" || ohai[:platform] == "solaris2"
+ # @hourly is not supported on solaris, aix
+ if ohai[:platform] == "solaris" || ohai[:platform] == "solaris2" || ohai[:platform] == "aix"
new_resource.minute "0 * * * *"
else
new_resource.minute '@hourly'
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index b1d7cdbd64..cc5ba8c3ac 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -98,7 +98,7 @@ RSpec.configure do |config|
config.filter_run_excluding :external => true
# Only run these tests on platforms that are also chef workstations
- config.filter_run_excluding :workstation if solaris?
+ config.filter_run_excluding :workstation if solaris? or aix?
# Tests that randomly fail, but may have value.
config.filter_run_excluding :volatile => true
diff --git a/spec/support/shared/functional/windows_script.rb b/spec/support/shared/functional/windows_script.rb
index f677828167..866caf4b20 100644
--- a/spec/support/shared/functional/windows_script.rb
+++ b/spec/support/shared/functional/windows_script.rb
@@ -95,7 +95,7 @@ shared_context Chef::Resource::WindowsScript do
end
let (:architecture) { :x86_64 }
- it "should execute a 64-bit guard if the guard's architecture is specified as 64-bit" do
+ 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'
diff --git a/spec/unit/chef_fs/file_system_spec.rb b/spec/unit/chef_fs/file_system_spec.rb
index 383a2c81ab..50f20a7a1c 100644
--- a/spec/unit/chef_fs/file_system_spec.rb
+++ b/spec/unit/chef_fs/file_system_spec.rb
@@ -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')
@@ -127,8 +128,20 @@ describe Chef::ChefFS::FileSystem do
it 'resolves /a/aa/zz' do
Chef::ChefFS::FileSystem.resolve_path(fs, '/a/aa/zz').path.should == '/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
+ Chef::ChefFS::FileSystem.resolve_path(fs, '/q/x/w').path.should == '/q/x/w'
+ end
+ end
+
+ context 'empty?' do
+ it 'is not empty /' do
+ Chef::ChefFS::FileSystem.resolve_path(fs, '/').empty?.should be false
+ end
+ it 'is empty /y' do
+ Chef::ChefFS::FileSystem.resolve_path(fs, '/y').empty?.should be true
+ end
+ it 'is not a directory and can\'t be tested /x' do
+ lambda { Chef::ChefFS::FileSystem.resolve_path(fs, '/x').empty? }.should raise_error(NoMethodError)
end
end
end
diff --git a/spec/unit/resource/windows_package_spec.rb b/spec/unit/resource/windows_package_spec.rb
index 3c45548ece..0034a731b4 100644
--- a/spec/unit/resource/windows_package_spec.rb
+++ b/spec/unit/resource/windows_package_spec.rb
@@ -34,9 +34,9 @@ describe Chef::Resource::WindowsPackage, "initialize", :windows_only do
expect(resource.provider).to eql(Chef::Provider::Package::Windows)
end
- it "supports setting installer_type" do
- resource.installer_type("msi")
- expect(resource.installer_type).to eql("msi")
+ it "supports setting installer_type as a symbol" do
+ resource.installer_type(:msi)
+ expect(resource.installer_type).to eql(:msi)
end
# String, Integer