Skip to content

Commit

Permalink
(#22772) Add error checking to yaml format
Browse files Browse the repository at this point in the history
This will raise a FormatError if asked to intern invalid YAML instead of an
unintelligible ruby error.
  • Loading branch information
pcarlisle committed Oct 3, 2013
1 parent 5a4feef commit 513d8b5
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 19 deletions.
26 changes: 18 additions & 8 deletions lib/puppet/network/formats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,28 @@
Puppet::Network::FormatHandler.create_serialized_formats(:yaml) do
def intern(klass, text)
data = YAML.load(text, :safe => true, :deserialize_symbols => true)
return data if data.is_a?(klass)
klass.from_pson(data)
data_to_instance(klass, data)
end

def intern_multiple(klass, text)
YAML.load(text, :safe => true, :deserialize_symbols => true).collect do |data|
if data.is_a?(klass)
data
else
klass.from_pson(data)
end
data = YAML.load(text, :safe => true, :deserialize_symbols => true)
unless data.respond_to?(:collect)
raise Puppet::Network::FormatHandler::FormatError, "Serialized YAML did not contain a collection of instances when calling intern_multiple"
end

data.collect do |datum|
data_to_instance(klass, datum)
end
end

def data_to_instance(klass, data)
return data if data.is_a?(klass)

unless data.is_a? Hash
raise Puppet::Network::FormatHandler::FormatError, "Serialized YAML did not contain a valid instance of #{klass}"
end

klass.from_pson(data)
end

def render(instance)
Expand Down
32 changes: 21 additions & 11 deletions spec/unit/network/formats_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,27 +63,31 @@ def to_pson(*args)
@yaml.intern(String, YAML.dump(:foo)).should == "foo"
end

it "should fail when type does not match deserialized form and has no from_pson" do
expect do
@yaml.intern(Hash, YAML.dump("foo"))
end.to raise_error(NoMethodError)
end

it "should load from yaml when deserializing an array" do
text = YAML.dump(["foo"])
@yaml.intern_multiple(String, text).should == ["foo"]
end

it "should fail when one element does not have a from_pson" do
it "fails intelligibly instead of calling to_pson with something other than a hash" do
expect do
@yaml.intern(Puppet::Node, '')
end.to raise_error(Puppet::Network::FormatHandler::FormatError, /did not contain a valid instance/)
end

it "fails intelligibly when intern_multiple is called and yaml doesn't decode to an array" do
expect do
@yaml.intern_multiple(Hash, YAML.dump(["foo"]))
end.to raise_error(NoMethodError)
@yaml.intern_multiple(Puppet::Node, '')
end.to raise_error(Puppet::Network::FormatHandler::FormatError, /did not contain a collection/)
end

it "fails intelligibly instead of calling to_pson with something other than a hash when interning multiple" do
expect do
@yaml.intern_multiple(Puppet::Node, YAML.dump(["hello"]))
end.to raise_error(Puppet::Network::FormatHandler::FormatError, /did not contain a valid instance/)
end
end

describe "base64 compressed yaml", :if => Puppet.features.zlib? do
yaml = Puppet::Network::FormatHandler.format(:b64_zlib_yaml)

before do
@yaml = Puppet::Network::FormatHandler.format(:b64_zlib_yaml)
end
Expand Down Expand Up @@ -294,6 +298,12 @@ def to_pson(*args)
PsonTest.expects(:from_pson).with("baz").returns "BAZ"
@pson.intern_multiple(PsonTest, text).should == %w{BAR BAZ}
end

it "fails intelligibly when given invalid data" do
expect do
@pson.intern(Puppet::Node, '')
end.to raise_error(PSON::ParserError, /source did not contain any PSON/)
end
end
end

Expand Down

0 comments on commit 513d8b5

Please sign in to comment.