summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorClaire McQuin <claire@getchef.com>2014-11-20 12:05:53 -0800
committerClaire McQuin <claire@getchef.com>2014-11-20 12:05:53 -0800
commit3e85b330c453980c20960ae53e80558c2e0ae45b (patch)
tree8c78904e844e721a3ba60fbb7b8c9de5042f7576 /lib
parentf3d19b686fdefb665098ed3f93ad91d95ec0e865 (diff)
parent48a7c01f6446225dd3c661058c2ceaa6c6688e00 (diff)
downloadchef-3e85b330c453980c20960ae53e80558c2e0ae45b.tar.gz
Merge branch 'mcquin/controls_group_object' of github.com:opscode/chef into mcquin/include-recipe-test
Diffstat (limited to 'lib')
-rw-r--r--lib/chef/audit.rb10
-rw-r--r--lib/chef/audit/controls.rb120
-rw-r--r--lib/chef/audit/runner.rb82
-rw-r--r--lib/chef/client.rb13
-rw-r--r--lib/chef/dsl/audit.rb5
5 files changed, 134 insertions, 96 deletions
diff --git a/lib/chef/audit.rb b/lib/chef/audit.rb
index ed8db93d96..1c28e7ea75 100644
--- a/lib/chef/audit.rb
+++ b/lib/chef/audit.rb
@@ -16,14 +16,6 @@
# limitations under the License.
#
-require 'rspec'
-require 'rspec/its'
-
-require 'serverspec/matcher'
-require 'serverspec/helper'
-require 'serverspec/subject'
-
-require 'specinfra'
-
require 'chef/dsl/audit'
+require 'chef/audit/controls'
require 'chef/audit/runner'
diff --git a/lib/chef/audit/controls.rb b/lib/chef/audit/controls.rb
new file mode 100644
index 0000000000..61e01b70f2
--- /dev/null
+++ b/lib/chef/audit/controls.rb
@@ -0,0 +1,120 @@
+#
+# 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 'chef/audit/audit_event_proxy'
+
+class Chef
+ class Audit
+ class Controls
+
+ attr_reader :run_context
+ private :run_context
+
+ ::RSpec::Core::ExampleGroup.define_example_group_method :control
+ ::RSpec::Core::ExampleGroup.define_example_group_method :__controls__
+
+ def initialize(run_context, *args, &block)
+ # To avoid cross-contamination between the configuration in our and other
+ # spec/spec_helper.rb files and the configuration for audits, we give
+ # each `controls` group its own RSpec. The files required here manipulate
+ # RSpec's global configuration, so we wait to load them.
+ #
+ # Additionally, name conflicts emerged between Chef's `package` and
+ # Serverspec's `package`. Requiring serverspec in here eliminates those
+ # namespace conflict.
+ #
+ # TODO: Once we have specs written for audit-mode, I'd like to play with
+ # which files can be moved around. I'm concerned about how much overhead
+ # we introduce by sequestering RSpec by `controls` group instead of in
+ # a common class or shared module.
+ require 'rspec'
+ require 'rspec/its'
+ require 'serverspec/matcher'
+ require 'serverspec/helper'
+ require 'serverspec/subject'
+ require 'specinfra'
+
+ @run_context = run_context
+ configure
+ world.register(RSpec::Core::ExampleGroup.__controls__(*args, &block))
+ end
+
+ def run
+ # The first parameter passed to RSpec::Core::Runner.new
+ # is an instance of RSpec::Core::ConfigurationOptions, which is
+ # responsible for processing command line options passed through rspec.
+ # This then gets merged with the configuration. We'll just communicate
+ # directly with the Configuration here.
+ RSpec::Core::Runner.new(nil, configuration, world).run_specs(world.ordered_example_groups)
+ end
+
+ private
+ def configuration
+ RSpec.configuration
+ end
+
+ def world
+ RSpec.world
+ end
+
+ # Sets up where output and error streams should stream to, adds formatters
+ # for people-friendly output of audit results and json for reporting. Also
+ # configures expectation frameworks.
+ def configure
+ # We're setting the output stream, but that will only be used for error situations
+ # Our formatter forwards events to the Chef event message bus
+ # TODO so some testing to see if these output to a log file - we probably need
+ # to register these before any formatters are added.
+ configuration.output_stream = Chef::Config[:log_location]
+ configuration.error_stream = Chef::Config[:log_location]
+
+ add_formatters
+ disable_should_syntax
+ configure_specinfra
+ end
+
+ def add_formatters
+ configuration.add_formatter(RSpec::Core::Formatters::DocumentationFormatter)
+ configuration.add_formatter(Chef::Audit::AuditEventProxy)
+ Chef::Audit::AuditEventProxy.events = run_context.events
+ end
+
+ # Explicitly disable :should syntax.
+ #
+ # :should is deprecated in RSpec 3 and we have chosen to explicitly disable it
+ # in audits. If :should is used in an audit, the audit will fail with error
+ # message "undefined method `:should`" rather than issue a deprecation warning.
+ #
+ # This can be removed when :should is fully removed from RSpec.
+ def disable_should_syntax
+ RSpec.configure do |config|
+ config.expect_with :rspec do |c|
+ c.syntax = :expect
+ end
+ end
+ end
+
+ def configure_specinfra
+ # TODO: We may need to change this based on operating system (there is a
+ # powershell backend) or roll our own.
+ Specinfra.configuration.backend = :exec
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/audit/runner.rb b/lib/chef/audit/runner.rb
index 0758dacd6d..28997088a3 100644
--- a/lib/chef/audit/runner.rb
+++ b/lib/chef/audit/runner.rb
@@ -16,11 +16,6 @@
# limitations under the License.
#
-require 'chef/audit'
-require 'chef/audit/audit_event_proxy'
-require 'chef/audit/rspec_formatter'
-require 'chef/config'
-
class Chef
class Audit
class Runner
@@ -33,83 +28,8 @@ class Chef
end
def run
- setup
- register_controls_groups
-
- # The first parameter passed to RSpec::Core::Runner.new
- # is an instance of RSpec::Core::ConfigurationOptions, which is
- # responsible for processing command line options passed through rspec.
- # This then gets merged with the configuration. We'll just communicate
- # directly with the Configuration here.
- audit_runner = RSpec::Core::Runner.new(nil, configuration, world)
- audit_runner.run_specs(world.ordered_example_groups)
- end
-
- private
-
- # RSpec configuration and world objects are heavy, so let's wait until
- # we actually need them.
- def configuration
- RSpec.configuration
- end
-
- def world
- RSpec.world
- end
-
- # Configure audits before run.
- # Sets up where output and error streams should stream to, adds formatters
- # for people-friendly output of audit results and json for reporting. Also
- # configures expectation frameworks.
- def setup
- # We're setting the output stream, but that will only be used for error situations
- # Our formatter forwards events to the Chef event message bus
- # TODO so some testing to see if these output to a log file - we probably need
- # to register these before any formatters are added.
- configuration.output_stream = Chef::Config[:log_location]
- configuration.error_stream = Chef::Config[:log_location]
- # TODO im pretty sure I only need this because im running locally in rvmsudo
- configuration.backtrace_exclusion_patterns.push(Regexp.new("/Users".gsub("/", File::SEPARATOR)))
- configuration.backtrace_exclusion_patterns.push(Regexp.new("(eval)"))
- configuration.color = Chef::Config[:color]
- configuration.expose_dsl_globally = false
-
- add_formatters
- disable_should_syntax
- configure_specinfra
+ run_context.controls_groups.each { |ctls_grp| ctls_grp.run }
end
-
- def add_formatters
- configuration.add_formatter(Chef::Audit::RspecFormatter)
- configuration.add_formatter(Chef::Audit::AuditEventProxy)
- Chef::Audit::AuditEventProxy.events = run_context.events
- end
-
- # Explicitly disable :should syntax.
- #
- # :should is deprecated in RSpec 3 and we have chosen to explicitly disable it
- # in audits. If :should is used in an audit, the audit will fail with error
- # message "undefined method `:should`" rather than issue a deprecation warning.
- #
- # This can be removed when :should is fully removed from RSpec.
- def disable_should_syntax
- configuration.expect_with :rspec do |c|
- c.syntax = :expect
- end
- end
-
- def configure_specinfra
- # TODO: We may need to change this based on operating system (there is a
- # powershell backend) or roll our own.
- Specinfra.configuration.backend = :exec
- end
-
- # Register each controls group with the world, which will handle
- # the ordering of the audits that will be run.
- def register_controls_groups
- run_context.controls_groups.each { |ctls_grp| world.register(ctls_grp) }
- end
-
end
end
end
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index b27a2b693d..c7ddded1ff 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -441,8 +441,17 @@ class Chef
run_context = setup_run_context
- converge_error = converge_and_save(run_context) unless (Chef::Config[:audit_mode] == true)
- audit_error = run_audits(run_context) unless (Chef::Config[:audit_mode] == false)
+ unless Chef::Config[:audit_mode] == true
+ converge_error = converge_and_save(run_context)
+ else
+ Chef::Log.debug("Skipping converge. Chef is configured to run audits only.")
+ end
+
+ unless Chef::Config[:audit_mode] == false
+ audit_error = run_audits(run_context)
+ else
+ Chef::Log.debug("Skipping audits. Chef is configured to converge the node only.")
+ end
if converge_error || audit_error
e = Chef::Exceptions::RunFailedWrappingError.new(converge_error, audit_error)
diff --git a/lib/chef/dsl/audit.rb b/lib/chef/dsl/audit.rb
index 1849b65633..520a667cd4 100644
--- a/lib/chef/dsl/audit.rb
+++ b/lib/chef/dsl/audit.rb
@@ -23,16 +23,13 @@ class Chef
module Audit
# Can encompass tests in a `control` block or `describe` block
- ::RSpec::Core::ExampleGroup.define_example_group_method :control
- ::RSpec::Core::ExampleGroup.define_example_group_method :__controls__
-
# Adds the controls group and block (containing controls to execute) to the runner's list of pending examples
def controls(*args, &block)
raise ::Chef::Exceptions::NoAuditsProvided unless block
name = args[0]
raise AuditNameMissing if name.nil? || name.empty?
- run_context.controls_groups << ::RSpec::Core::ExampleGroup.__controls__(*args, &block)
+ run_context.controls_groups << Chef::Audit::Controls.new(run_context, args, &block)
end
end