1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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
|