+1 On Mon, Aug 23, 2010 at 8:55 AM, Paul Berry <[email protected]> wrote:
> The ZAML class was using class variables to keep track of labels and > backreferences while serializing object to YAML. This made it > possible to get ill-formed or incorrect YAML output if two threads > tried to serialize objects at the same time. > > Changed to use instance variables of the ZAML class, so there is no > race condition. > > Also added some more spec tests to verify that labels are generated > properly. > > Signed-off-by: Paul Berry <[email protected]> > --- > lib/puppet/util/zaml.rb | 23 +++++++++++------------ > spec/unit/util/zaml_spec.rb | 25 +++++++++++++++++++++++++ > 2 files changed, 36 insertions(+), 12 deletions(-) > > diff --git a/lib/puppet/util/zaml.rb b/lib/puppet/util/zaml.rb > index 8ecc2c8..b60e639 100644 > --- a/lib/puppet/util/zaml.rb > +++ b/lib/puppet/util/zaml.rb > @@ -29,7 +29,8 @@ class ZAML > @result = [] > @indent = nil > @structured_key_prefix = nil > - Label.counter_reset > + @previously_emitted_object = {} > + @next_free_label_number = 0 > emit('--- ') > end > def nested(tail=' ') > @@ -55,31 +56,29 @@ class ZAML > # which we will encounter a reference to the object as we serialize > # it can be handled). > # > - def self.counter_reset > - @@previously_emitted_object = {} > - @@next_free_label_number = 0 > - end > + attr_accessor :this_label_number > def initialize(obj,indent) > @indent = indent > @this_label_number = nil > - @@previously_emitted_object[obj.object_id] = self > end > def to_s > @this_label_number ? ('&id%03d%s' % [...@this_label_number, @indent]) : > '' > end > def reference > - @this_label_number ||= (@@next_free_label_number += 1) > @reference ||= '*id%03d' % @this_label_number > end > - def self.for(obj) > - @@previously_emitted_object[obj.object_id] > - end > + end > + def label_for(obj) > + @previously_emitted_object[obj.object_id] > end > def new_label_for(obj) > - Label.new(obj,(Hash === obj || Array === obj) ? "#...@indent || "\n"} " > : ' ') > + label = Label.new(obj,(Hash === obj || Array === obj) ? "#...@indent || > "\n"} " : ' ') > + @previously_emitted_object[obj.object_id] = label > + label > end > def first_time_only(obj) > - if label = Label.for(obj) > + if label = label_for(obj) > + label.this_label_number ||= (@next_free_label_number += 1) > emit(label.reference) > else > if @structured_key_prefix and not obj.is_a? String > diff --git a/spec/unit/util/zaml_spec.rb b/spec/unit/util/zaml_spec.rb > index 4de57e6..14cf94f 100644 > --- a/spec/unit/util/zaml_spec.rb > +++ b/spec/unit/util/zaml_spec.rb > @@ -34,5 +34,30 @@ describe "Pure ruby yaml implementation" do > lambda { YAML.load(o.to_yaml) }.should_not raise_error > end > } > + > + it "should emit proper labels and backreferences for common objects" do > + # Note: this test makes assumptions about the names ZAML chooses > + # for labels. > + x = [1, 2] > + y = [3, 4] > + z = [x, y, x, y] > + z.to_yaml.should == "--- \n - &id001\n - 1\n - 2\n - &id002\n > - 3\n - 4\n - *id001\n - *id002" > + z2 = YAML.load(z.to_yaml) > + z2.should == z > + z2[0].should equal(z2[2]) > + z2[1].should equal(z2[3]) > + end > + > + it "should emit proper labels and backreferences for recursive objects" > do > + x = [1, 2] > + x << x > + x.to_yaml.should == "--- &id001\n \n - 1\n - 2\n - *id001" > + x2 = YAML.load(x.to_yaml) > + x2.should be_a(Array) > + x2.length.should == 3 > + x2[0].should == 1 > + x2[1].should == 2 > + x2[2].should equal(x2) > + end > end > > -- > 1.7.2 > > -- > You received this message because you are subscribed to the Google Groups > "Puppet Developers" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]<puppet-dev%[email protected]> > . > For more options, visit this group at > http://groups.google.com/group/puppet-dev?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en.
