# # Author:: Tyler Ball () # Copyright:: Copyright 2014-2016, Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # 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