Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/rspec-puppet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def self.current_example
c.add_setting :fixture_hiera_configs, default: {}
c.add_setting :use_fixture_spec_hiera, default: false
c.add_setting :fallback_to_default_hiera, default: true
c.add_setting :strict_catalog_encoding, default: false

c.before(:all) do
RSpec::Puppet::Setup.safe_setup_directories(nil, false) if RSpec.configuration.setup_fixtures?
Expand Down
38 changes: 38 additions & 0 deletions lib/rspec-puppet/adapters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ def catalog(node, exported)

Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, catalog)

check_encoding(catalog)

catalog
end

Expand Down Expand Up @@ -179,6 +181,42 @@ def set_facter_impl(impl)
impl = impl.call if impl.is_a?(Proc)
Object.send(:const_set, :FacterImpl, impl)
end

# Puppet expects source code to be UTF-8, but other inputs to the
# compilation process can cause binary data to be added, which cause
# problems later when serializing the catalog as JSON. Warn or raise if
# there are any ASCII_8BIT strings or the byte representation does not
# match its encoding.
#
def check_encoding(obj, path = '')
case obj
when Puppet::Resource::Catalog
obj.resources.each do |r|
check_encoding(r)
end
when Puppet::Resource
obj.to_hash.each do |param, value|
check_encoding(value, "#{obj.type}[#{obj.title}]/#{param}")
end
when Array
obj.each_with_index do |elem, idx|
check_encoding(elem, "#{path}[#{idx}]")
end
when Hash
obj.each do |k, v|
check_encoding(k, "#{path}/key")
check_encoding(v, "#{path}/value")
end
when String
meth = RSpec.configuration.strict_catalog_encoding ? :raise : :warn
if obj.encoding == Encoding::ASCII_8BIT
send(meth, "#{path} must be wrapped in a Binary data type, not encoded as #{obj.encoding}")
elsif !obj.valid_encoding?
send(meth, "#{path} is not a valid #{obj.encoding} encoded String")
end
end
end
private :check_encoding
end

def self.get
Expand Down
Loading