~nvalcarcel/ubuntu/lucid/puppet/fix-546677

« back to all changes in this revision

Viewing changes to test/other/transactions.rb

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2009-12-23 00:48:10 UTC
  • mfrom: (1.1.10 upstream) (3.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091223004810-3i4oryds922g5n59
Tags: 0.25.1-3ubuntu1
* Merge from debian testing.  Remaining changes:
  - debian/rules:
    + Don't start puppet when first installing puppet.
  - debian/puppet.conf, lib/puppet/defaults.rb:
    + Move templates to /etc/puppet
  - lib/puppet/defaults.rb:
    + Fix /var/lib/puppet/state ownership.
  - man/man8/puppet.conf.8: 
    + Fix broken URL in manpage.
  - debian/control:
    + Update maintainer accordint to spec.
    + Puppetmaster Recommends -> Suggests
    + Created puppet-testsuite as a seperate. Allow the users to run puppet's 
      testsuite.
  - tests/Rakefile: Fix rakefile so that the testsuite can acutally be ran.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
    include PuppetTest::Support::Resources
14
14
    include PuppetTest::Support::Utils
15
15
    class Fakeprop <Puppet::Property
 
16
        initvars()
 
17
 
16
18
        attr_accessor :path, :is, :should, :name
17
19
        def should_to_s(value)
18
20
            value.to_s
23
25
        def info(*args)
24
26
            false
25
27
        end
 
28
 
 
29
        def set(value)
 
30
            # eh
 
31
        end
 
32
 
 
33
        def log(msg)
 
34
        end
26
35
    end
27
 
    
28
 
    
 
36
 
 
37
 
29
38
    def mkgenerator(&block)
30
39
        $finished = []
31
40
        cleanup { $finished = nil }
32
 
        
 
41
 
33
42
        # Create a bogus type that generates new instances with shorter
34
43
        type = Puppet::Type.newtype(:generator) do
35
44
            newparam(:name, :namevar => true)
43
52
        cleanup do
44
53
            Puppet::Type.rmtype(:generator)
45
54
        end
46
 
        
 
55
 
47
56
        return type
48
57
    end
49
 
    
 
58
 
50
59
    # Create a new type that generates instances with shorter names.
51
60
    def mkreducer(&block)
52
61
        type = mkgenerator() do
53
62
            def eval_generate
54
63
                ret = []
55
64
                if title.length > 1
56
 
                    ret << self.class.create(:title => title[0..-2])
 
65
                    ret << self.class.new(:title => title[0..-2])
57
66
                else
58
67
                    return nil
59
68
                end
60
69
                ret
61
70
            end
62
71
        end
63
 
        
 
72
 
64
73
        if block
65
74
            type.class_eval(&block)
66
75
        end
67
 
        
 
76
 
68
77
        return type
69
78
    end
70
79
 
72
81
        path1 = tempfile()
73
82
        path2 = tempfile()
74
83
        objects = []
75
 
        objects << Puppet::Type.type(:file).create(
 
84
        objects << Puppet::Type.type(:file).new(
76
85
            :path => path1,
77
86
            :content => "yayness"
78
87
        )
79
 
        objects << Puppet::Type.type(:file).create(
 
88
        objects << Puppet::Type.type(:file).new(
80
89
            :path => path2,
81
90
            :content => "booness"
82
91
        )
117
126
        type = Puppet::Type.newtype(name) do
118
127
            newparam(:name) {}
119
128
        end
120
 
        
 
129
 
121
130
        cleanup do
122
131
            Puppet::Type.rmtype(name)
123
132
        end
130
139
        end
131
140
 
132
141
        # Now create an instance
133
 
        inst = type.create :name => "yay"
134
 
        
 
142
        inst = type.new :name => "yay"
 
143
 
135
144
        # Create a transaction
136
145
        trans = Puppet::Transaction.new(mk_catalog(inst))
137
146
 
155
164
        path = tempfile()
156
165
        firstpath = tempfile()
157
166
        secondpath = tempfile()
158
 
        file = Puppet::Type.type(:file).create(:title => "file", :path => path, :content => "yayness")
159
 
        first = Puppet::Type.newexec(:title => "first",
 
167
        file = Puppet::Type.type(:file).new(:title => "file", :path => path, :content => "yayness")
 
168
        first = Puppet::Type.type(:exec).new(:title => "first",
160
169
                                     :command => "/bin/echo first > #{firstpath}",
161
 
                                     :subscribe => [:file, path],
 
170
                                     :subscribe => Puppet::Resource::Reference.new(:file, path),
162
171
                                     :refreshonly => true
163
172
        )
164
 
        second = Puppet::Type.newexec(:title => "second",
 
173
        second = Puppet::Type.type(:exec).new(:title => "second",
165
174
                                     :command => "/bin/echo second > #{secondpath}",
166
 
                                     :subscribe => [:exec, "first"],
 
175
                                     :subscribe => Puppet::Resource::Reference.new(:exec, "first"),
167
176
                                     :refreshonly => true
168
177
        )
169
178
 
219
228
 
220
229
        hash[:name] = tmpfile
221
230
        assert_nothing_raised() {
222
 
            return Puppet.type(:file).create(hash)
 
231
            return Puppet::Type.type(:file).new(hash)
223
232
        }
224
233
    end
225
234
 
226
235
    def newexec(file)
227
236
        assert_nothing_raised() {
228
 
            return Puppet.type(:exec).create(
 
237
            return Puppet::Type.type(:exec).new(
229
238
                :name => "touch %s" % file,
230
239
                :path => "/bin:/usr/bin:/sbin:/usr/sbin",
231
240
                :returns => 0
301
310
        @@tmpfiles << execfile
302
311
 
303
312
        # 'subscribe' expects an array of arrays
304
 
        exec[:subscribe] = [[file.class.name,file.name]]
 
313
        exec[:subscribe] = Puppet::Resource::Reference.new(file.class.name,file.name)
305
314
        exec[:refreshonly] = true
306
315
 
307
316
        assert_nothing_raised() {
346
355
        file[:group] = @groups[0]
347
356
        assert_apply(file)
348
357
 
349
 
        config = Puppet::Node::Catalog.new
350
 
        fcomp = Puppet::Type.type(:component).create(:name => "file")
 
358
        config = Puppet::Resource::Catalog.new
 
359
        fcomp = Puppet::Type.type(:component).new(:name => "file")
351
360
        config.add_resource fcomp
352
361
        config.add_resource file
353
362
        config.add_edge(fcomp, file)
354
363
 
355
 
        ecomp = Puppet::Type.type(:component).create(:name => "exec")
 
364
        ecomp = Puppet::Type.type(:component).new(:name => "exec")
356
365
        config.add_resource ecomp
357
366
        config.add_resource exec
358
367
        config.add_edge(ecomp, exec)
377
386
        path = tempfile()
378
387
        file1 = tempfile()
379
388
        file2 = tempfile()
380
 
        file = Puppet.type(:file).create(
 
389
        file = Puppet::Type.type(:file).new(
381
390
            :path => path,
382
391
            :ensure => "file"
383
392
        )
384
 
        exec1 = Puppet.type(:exec).create(
 
393
        exec1 = Puppet::Type.type(:exec).new(
385
394
            :path => ENV["PATH"],
386
395
            :command => "touch %s" % file1,
387
396
            :refreshonly => true,
388
 
            :subscribe => [:file, path]
 
397
            :subscribe => Puppet::Resource::Reference.new(:file, path)
389
398
        )
390
 
        exec2 = Puppet.type(:exec).create(
 
399
        exec2 = Puppet::Type.type(:exec).new(
391
400
            :path => ENV["PATH"],
392
401
            :command => "touch %s" % file2,
393
402
            :refreshonly => true,
394
 
            :subscribe => [:file, path]
 
403
            :subscribe => Puppet::Resource::Reference.new(:file, path)
395
404
        )
396
405
 
397
406
        assert_apply(file, exec1, exec2)
404
413
    def test_failedrefreshes
405
414
        path = tempfile()
406
415
        newfile = tempfile()
407
 
        file = Puppet.type(:file).create(
 
416
        file = Puppet::Type.type(:file).new(
408
417
            :path => path,
409
418
            :ensure => "file"
410
419
        )
411
 
        exec1 = Puppet.type(:exec).create(
 
420
        exec1 = Puppet::Type.type(:exec).new(
412
421
            :path => ENV["PATH"],
413
422
            :command => "touch /this/cannot/possibly/exist",
414
423
            :logoutput => true,
416
425
            :subscribe => file,
417
426
            :title => "one"
418
427
        )
419
 
        exec2 = Puppet.type(:exec).create(
 
428
        exec2 = Puppet::Type.type(:exec).new(
420
429
            :path => ENV["PATH"],
421
430
            :command => "touch %s" % newfile,
422
431
            :logoutput => true,
433
442
    def test_unscheduled_and_untagged_response
434
443
        Puppet::Type.type(:schedule).mkdefaultschedules
435
444
        Puppet[:ignoreschedules] = false
436
 
        file = Puppet.type(:file).create(
 
445
        file = Puppet::Type.type(:file).new(
437
446
            :name => tempfile(),
438
447
            :ensure => "file",
439
448
            :backup => false
440
449
        )
441
450
 
442
451
        fname = tempfile()
443
 
        exec = Puppet.type(:exec).create(
 
452
        exec = Puppet::Type.type(:exec).new(
444
453
            :name => "touch %s" % fname,
445
454
            :path => "/usr/bin:/bin",
446
455
            :schedule => "monthly",
447
 
            :subscribe => ["file", file.name]
 
456
            :subscribe => Puppet::Resource::Reference.new("file", file.name)
448
457
        )
449
458
 
450
459
        config = mk_catalog(file, exec)
484
493
    end
485
494
 
486
495
    def test_failed_reqs_mean_no_run
487
 
        exec = Puppet::Type.type(:exec).create(
 
496
        exec = Puppet::Type.type(:exec).new(
488
497
            :command => "/bin/mkdir /this/path/cannot/possibly/exit",
489
498
            :title => "mkdir"
490
499
        )
491
500
 
492
 
        file1 = Puppet::Type.type(:file).create(
 
501
        file1 = Puppet::Type.type(:file).new(
493
502
            :title => "file1",
494
503
            :path => tempfile(),
495
504
            :require => exec,
496
505
            :ensure => :file
497
506
        )
498
507
 
499
 
        file2 = Puppet::Type.type(:file).create(
 
508
        file2 = Puppet::Type.type(:file).new(
500
509
            :title => "file2",
501
510
            :path => tempfile(),
502
511
            :require => file1,
513
522
            "File got created even tho its deep dependency failed")
514
523
    end
515
524
    end
516
 
    
517
 
    def test_relationship_graph
518
 
        config = mktree
519
 
 
520
 
        config.meta_def(:f) do |name|
521
 
            self.resource("File[%s]" % name)
522
 
        end
523
 
        
524
 
        {"one" => "two", "File[f]" => "File[c]", "File[h]" => "middle"}.each do |source_ref, target_ref|
525
 
            source = config.resource(source_ref) or raise "Missing %s" % source_ref
526
 
            target = config.resource(target_ref) or raise "Missing %s" % target_ref
527
 
            target[:require] = source
528
 
        end
529
 
        
530
 
        trans = Puppet::Transaction.new(config)
531
 
        
532
 
        graph = nil
533
 
        assert_nothing_raised do
534
 
            graph = trans.relationship_graph
535
 
        end
536
 
 
537
 
        assert_instance_of(Puppet::Node::Catalog, graph,
538
 
            "Did not get relationship graph")
539
 
        
540
 
        # Make sure all of the components are gone
541
 
        comps = graph.vertices.find_all { |v| v.is_a?(Puppet::Type::Component)}
542
 
        assert(comps.empty?, "Deps graph still contains components %s" %
543
 
            comps.collect { |c| c.ref }.join(","))
544
 
        
545
 
        assert_equal([], comps, "Deps graph still contains components")
546
 
        
547
 
        # It must be reversed because of how topsort works
548
 
        sorted = graph.topsort.reverse
549
 
        
550
 
        # Now make sure the appropriate edges are there and are in the right order
551
 
        assert(graph.dependents(config.f(:f)).include?(config.f(:c)),
552
 
            "c not marked a dep of f")
553
 
        assert(sorted.index(config.f(:c)) < sorted.index(config.f(:f)),
554
 
            "c is not before f")
555
 
            
556
 
        config.resource("one").each do |o|
557
 
            config.resource("two").each do |t|
558
 
                assert(graph.dependents(o).include?(t),
559
 
                    "%s not marked a dep of %s" % [t.ref, o.ref])
560
 
                assert(sorted.index(t) < sorted.index(o),
561
 
                    "%s is not before %s" % [t.ref, o.ref])
562
 
            end
563
 
        end
564
 
        
565
 
        trans.catalog.leaves(config.resource("middle")).each do |child|
566
 
            assert(graph.dependents(config.f(:h)).include?(child),
567
 
                "%s not marked a dep of h" % [child.ref])
568
 
            assert(sorted.index(child) < sorted.index(config.f(:h)),
569
 
                "%s is not before h" % child.ref)
570
 
        end
571
 
        
572
 
        # Lastly, make sure our 'g' vertex made it into the relationship
573
 
        # graph, since it's not involved in any relationships.
574
 
        assert(graph.vertex?(config.f(:g)),
575
 
            "Lost vertexes with no relations")
576
 
 
577
 
        # Now make the reversal graph and make sure all of the vertices made it into that
578
 
        reverse = graph.reversal
579
 
        %w{a b c d e f g h}.each do |letter|
580
 
            file = config.f(letter)
581
 
            assert(reverse.vertex?(file), "%s did not make it into reversal" % letter)
582
 
        end
583
 
    end
584
 
    
585
 
    # Test pre-evaluation generation
586
 
    def test_generate
587
 
        mkgenerator() do
588
 
            def generate
589
 
                ret = []
590
 
                if title.length > 1
591
 
                    ret << self.class.create(:title => title[0..-2])
592
 
                else
593
 
                    return nil
594
 
                end
595
 
                ret
596
 
            end
597
 
        end
598
 
        
599
 
        yay = Puppet::Type.newgenerator :title => "yay"
600
 
        rah = Puppet::Type.newgenerator :title => "rah"
601
 
        config = mk_catalog(yay, rah)
602
 
        trans = Puppet::Transaction.new(config)
603
 
        
604
 
        assert_nothing_raised do
605
 
            trans.generate
606
 
        end
607
 
        
608
 
        %w{ya ra y r}.each do |name|
609
 
            assert(trans.catalog.vertex?(Puppet::Type.type(:generator)[name]),
610
 
                "Generated %s was not a vertex" % name)
611
 
            assert($finished.include?(name), "%s was not finished" % name)
612
 
        end
613
 
        
614
 
        # Now make sure that cleanup gets rid of those generated types.
615
 
        assert_nothing_raised do
616
 
            trans.cleanup
617
 
        end
618
 
        
619
 
        %w{ya ra y r}.each do |name|
620
 
            assert(!trans.catalog.vertex?(Puppet::Type.type(:generator)[name]),
621
 
                "Generated vertex %s was not removed from graph" % name)
622
 
            assert_nil(Puppet::Type.type(:generator)[name],
623
 
                "Generated vertex %s was not removed from class" % name)
624
 
        end
625
 
    end
626
 
    
627
 
    # Test mid-evaluation generation.
628
 
    def test_eval_generate
629
 
        $evaluated = []
630
 
        cleanup { $evaluated = nil }
631
 
        type = mkreducer() do
632
 
            def evaluate
633
 
                $evaluated << self.title
634
 
                return []
635
 
            end
636
 
        end
637
 
 
638
 
        yay = Puppet::Type.newgenerator :title => "yay"
639
 
        rah = Puppet::Type.newgenerator :title => "rah", :subscribe => yay
640
 
        config = mk_catalog(yay, rah)
641
 
        trans = Puppet::Transaction.new(config)
642
 
        
643
 
        trans.prepare
644
 
        
645
 
        # Now apply the resources, and make sure they appropriately generate
646
 
        # things.
647
 
        assert_nothing_raised("failed to apply yay") do
648
 
            trans.eval_resource(yay)
649
 
        end
650
 
        ya = type["ya"]
651
 
        assert(ya, "Did not generate ya")
652
 
        assert(trans.relationship_graph.vertex?(ya),
653
 
            "Did not add ya to rel_graph")
654
 
        
655
 
        # Now make sure the appropriate relationships were added
656
 
        assert(trans.relationship_graph.edge?(yay, ya),
657
 
            "parent was not required by child")
658
 
        assert(! trans.relationship_graph.edge?(ya, rah),
659
 
            "generated child ya inherited depencency on rah")
660
 
        
661
 
        # Now make sure it in turn eval_generates appropriately
662
 
        assert_nothing_raised("failed to apply yay") do
663
 
            trans.eval_resource(type["ya"])
664
 
        end
665
 
 
666
 
        %w{y}.each do |name|
667
 
            res = type[name]
668
 
            assert(res, "Did not generate %s" % name)
669
 
            assert(trans.relationship_graph.vertex?(res),
670
 
                "Did not add %s to rel_graph" % name)
671
 
            assert($finished.include?("y"), "y was not finished")
672
 
        end
673
 
        
674
 
        assert_nothing_raised("failed to eval_generate with nil response") do
675
 
            trans.eval_resource(type["y"])
676
 
        end
677
 
        assert(trans.relationship_graph.edge?(yay, ya), "no edge was created for ya => yay")
678
 
        
679
 
        assert_nothing_raised("failed to apply rah") do
680
 
            trans.eval_resource(rah)
681
 
        end
682
 
 
683
 
        ra = type["ra"]
684
 
        assert(ra, "Did not generate ra")
685
 
        assert(trans.relationship_graph.vertex?(ra),
686
 
            "Did not add ra to rel_graph" % name)
687
 
        assert($finished.include?("ra"), "y was not finished")
688
 
        
689
 
        # Now make sure this generated resource has the same relationships as
690
 
        # the generating resource
691
 
        assert(! trans.relationship_graph.edge?(yay, ra),
692
 
           "rah passed its dependencies on to its children")
693
 
        assert(! trans.relationship_graph.edge?(ya, ra),
694
 
            "children have a direct relationship")
695
 
        
696
 
        # Now make sure that cleanup gets rid of those generated types.
697
 
        assert_nothing_raised do
698
 
            trans.cleanup
699
 
        end
700
 
        
701
 
        %w{ya ra y r}.each do |name|
702
 
            assert(!trans.relationship_graph.vertex?(type[name]),
703
 
                "Generated vertex %s was not removed from graph" % name)
704
 
            assert_nil(type[name],
705
 
                "Generated vertex %s was not removed from class" % name)
706
 
        end
707
 
        
708
 
        # Now, start over and make sure that everything gets evaluated.
709
 
        trans = Puppet::Transaction.new(config)
710
 
        $evaluated.clear
711
 
        assert_nothing_raised do
712
 
            trans.evaluate
713
 
        end
714
 
        
715
 
        assert_equal(%w{yay ya y rah ra r}, $evaluated,
716
 
            "Not all resources were evaluated or not in the right order")
717
 
    end
718
525
 
719
526
    # We need to generate resources before we prefetch them, else generated
720
527
    # resources that require prefetching don't work.
729
536
        trans.prepare
730
537
        return
731
538
 
732
 
        resource = Puppet::Type.type(:file).create :ensure => :present, :path => tempfile()
 
539
        resource = Puppet::Type.type(:file).new :ensure => :present, :path => tempfile()
733
540
        other_resource = mock 'generated'
734
541
        def resource.generate
735
542
            [other_resource]
738
545
 
739
546
        config = mk_catalog(yay, rah)
740
547
        trans = Puppet::Transaction.new(config)
741
 
        
 
548
 
742
549
        assert_nothing_raised do
743
550
            trans.generate
744
551
        end
745
 
        
 
552
 
746
553
        %w{ya ra y r}.each do |name|
747
554
            assert(trans.catalog.vertex?(Puppet::Type.type(:generator)[name]),
748
555
                "Generated %s was not a vertex" % name)
749
556
            assert($finished.include?(name), "%s was not finished" % name)
750
557
        end
751
 
        
 
558
 
752
559
        # Now make sure that cleanup gets rid of those generated types.
753
560
        assert_nothing_raised do
754
561
            trans.cleanup
756
563
    end
757
564
 
758
565
    def test_ignore_tags?
759
 
        config = Puppet::Node::Catalog.new
 
566
        config = Puppet::Resource::Catalog.new
760
567
        config.host_config = true
761
568
        transaction = Puppet::Transaction.new(config)
762
569
        assert(! transaction.ignore_tags?, "Ignoring tags when applying a host catalog")
765
572
        transaction = Puppet::Transaction.new(config)
766
573
        assert(transaction.ignore_tags?, "Not ignoring tags when applying a non-host catalog")
767
574
    end
768
 
    
 
575
 
769
576
    def test_missing_tags?
770
577
        resource = stub 'resource', :tagged? => true
771
 
        config = Puppet::Node::Catalog.new
 
578
        config = Puppet::Resource::Catalog.new
772
579
 
773
580
        # Mark it as a host config so we don't care which test is first
774
581
        config.host_config = true
781
588
        transaction = Puppet::Transaction.new(config)
782
589
        assert(! transaction.missing_tags?(resource), "Considered a resource to be missing tags when not running a host catalog")
783
590
 
784
 
        # 
 
591
        #
785
592
        config.host_config = true
786
593
        transaction = Puppet::Transaction.new(config)
787
594
        assert(! transaction.missing_tags?(resource), "Considered a resource to be missing tags when running a host catalog and all tags are present")
790
597
        resource.stubs :tagged? => false
791
598
        assert(transaction.missing_tags?(resource), "Considered a resource not to be missing tags when running a host catalog and tags are missing")
792
599
    end
793
 
    
 
600
 
794
601
    # Make sure changes generated by eval_generated resources have proxies
795
602
    # set to the top-level resource.
796
603
    def test_proxy_resources
797
604
        type = mkreducer do
798
605
            def evaluate
799
606
                return Puppet::Transaction::Change.new(Fakeprop.new(
800
 
                    :path => :path, :is => :is, :should => :should, :name => self.name, :resource => "a parent"), :is)
 
607
                    :path => :path, :is => "start_value", :should => "desired_value", :name => self.name, :resource => "fake_parent"), :is)
801
608
            end
802
609
        end
803
 
        
804
 
        resource = type.create :name => "test"
 
610
 
 
611
        resource = type.new :name => "test"
805
612
        config = mk_catalog(resource)
806
613
        trans = Puppet::Transaction.new(config)
807
614
        trans.prepare
811
618
        end
812
619
 
813
620
        changes = trans.instance_variable_get("@changes")
814
 
        
 
621
 
815
622
        assert(changes.length > 0, "did not get any changes")
816
 
        
 
623
 
817
624
        changes.each do |change|
818
 
            assert_equal(resource, change.resource, "change did not get proxy set correctly")
 
625
            assert_equal(resource.object_id, change.resource.object_id, "change did not get proxy set correctly")
819
626
        end
820
627
    end
821
 
    
 
628
 
822
629
    # Make sure changes in contained files still generate callback events.
823
630
    def test_generated_callbacks
824
631
        dir = tempfile()
828
635
        File.open(file, "w") { |f| f.puts "" }
829
636
        File.chmod(0644, file)
830
637
        File.chmod(0755, dir) # So only the child file causes a change
831
 
        
832
 
        dirobj = Puppet::Type.type(:file).create :mode => "755", :recurse => true, :path => dir
833
 
        exec = Puppet::Type.type(:exec).create :title => "make",
 
638
 
 
639
        dirobj = Puppet::Type.type(:file).new :mode => "755", :recurse => true, :path => dir
 
640
        exec = Puppet::Type.type(:exec).new :title => "make",
834
641
            :command => "touch #{maker}", :path => ENV['PATH'], :refreshonly => true,
835
642
            :subscribe => dirobj
836
 
        
 
643
 
837
644
        assert_apply(dirobj, exec)
838
645
        assert(FileTest.exists?(maker), "Did not make callback file")
839
646
    end
861
668
        end
862
669
 
863
670
        # Make a graph with some stuff in it.
864
 
        graph = Puppet::Node::Catalog.new
 
671
        graph = Puppet::Resource::Catalog.new
865
672
 
866
673
        # Add a non-triggering edge.
867
674
        a = trigger.new(:a)
912
719
        assert(trans.triggered?(c, :refresh),
913
720
            "Transaction did not store the trigger")
914
721
    end
915
 
    
 
722
 
916
723
    def test_set_target
917
 
        file = Puppet::Type.type(:file).create(:path => tempfile(), :content => "yay")
918
 
        exec1 = Puppet::Type.type(:exec).create :command => "/bin/echo exec1"
919
 
        exec2 = Puppet::Type.type(:exec).create :command => "/bin/echo exec2"
 
724
        file = Puppet::Type.type(:file).new(:path => tempfile(), :content => "yay")
 
725
        exec1 = Puppet::Type.type(:exec).new :command => "/bin/echo exec1"
 
726
        exec2 = Puppet::Type.type(:exec).new :command => "/bin/echo exec2"
920
727
        trans = Puppet::Transaction.new(mk_catalog(file, exec1, exec2))
921
 
        
 
728
 
922
729
        # First try it with an edge that has no callback
923
730
        edge = Puppet::Relationship.new(file, exec1)
924
731
        assert_nothing_raised { trans.set_trigger(edge) }
925
732
        assert(! trans.targeted?(exec1), "edge with no callback resulted in a target")
926
 
        
 
733
 
927
734
        # Now with an edge that has an unsupported callback
928
735
        edge = Puppet::Relationship.new(file, exec1, :callback => :nosuchmethod, :event => :ALL_EVENTS)
929
736
        assert_nothing_raised { trans.set_trigger(edge) }
930
737
        assert(! trans.targeted?(exec1), "edge with invalid callback resulted in a target")
931
 
        
 
738
 
932
739
        # Lastly, with an edge with a supported callback
933
740
        edge = Puppet::Relationship.new(file, exec1, :callback => :refresh, :event => :ALL_EVENTS)
934
741
        assert_nothing_raised { trans.set_trigger(edge) }
935
742
        assert(trans.targeted?(exec1), "edge with valid callback did not result in a target")
936
743
    end
937
 
    
 
744
 
938
745
    # Testing #401 -- transactions are calling refresh() on classes that don't support it.
939
746
    def test_callback_availability
940
747
        $called = []
949
756
            Puppet::Type.rmtype(:norefresh)
950
757
        end
951
758
 
952
 
        file = Puppet::Type.type(:file).create :path => tempfile(), :content => "yay"
953
 
        one = klass.create :name => "one", :subscribe => file
954
 
        
 
759
        file = Puppet::Type.type(:file).new :path => tempfile(), :content => "yay"
 
760
        one = klass.new :name => "one", :subscribe => file
 
761
 
955
762
        assert_apply(file, one)
956
 
        
 
763
 
957
764
        assert(! $called.include?(:refresh), "Called refresh when it wasn't set as a method")
958
765
    end
959
766
 
960
767
    # Testing #437 - cyclic graphs should throw failures.
961
768
    def test_fail_on_cycle
962
 
        one = Puppet::Type.type(:exec).create(:name => "/bin/echo one")
963
 
        two = Puppet::Type.type(:exec).create(:name => "/bin/echo two")
 
769
        one = Puppet::Type.type(:exec).new(:name => "/bin/echo one")
 
770
        two = Puppet::Type.type(:exec).new(:name => "/bin/echo two")
964
771
        one[:require] = two
965
772
        two[:require] = one
966
773
 
983
790
        end
984
791
        cleanup { Puppet::Type.rmtype(:failer) }
985
792
 
986
 
        obj = type.create(:name => "testing")
 
793
        obj = type.new(:name => "testing")
987
794
 
988
795
        assert_apply(obj)
989
796
    end
990
 
    
 
797
 
991
798
    def test_self_refresh_causes_triggering
992
799
        type = Puppet::Type.newtype(:refresher, :self_refresh => true) do
993
800
            attr_accessor :refreshed, :testing
994
801
            newparam(:name) {}
995
802
            newproperty(:testing) do
 
803
                def retrieve
 
804
                    :eh
 
805
                end
 
806
 
996
807
                def sync
997
808
                    # noop
998
809
                    :ran_testing
1003
814
            end
1004
815
        end
1005
816
        cleanup { Puppet::Type.rmtype(:refresher)}
1006
 
        
1007
 
        obj = type.create(:name => "yay", :testing => "cool")
1008
 
        
 
817
 
 
818
        obj = type.new(:name => "yay", :testing => "cool")
 
819
 
1009
820
        assert(! obj.insync?(obj.retrieve), "fake object is already in sync")
1010
 
        
 
821
 
1011
822
        # Now make sure it gets refreshed when the change happens
1012
823
        assert_apply(obj)
1013
824
        assert(obj.refreshed, "object was not refreshed during transaction")
1014
825
    end
1015
 
    
 
826
 
1016
827
    # Testing #433
1017
828
    def test_explicit_dependencies_beat_automatic
1018
829
        # Create a couple of different resource sets that have automatic relationships and make sure the manual relationships win
1019
830
        rels = {}
1020
831
        # First users and groups
1021
 
        group = Puppet::Type.type(:group).create(:name => nonrootgroup.name, :ensure => :present)
1022
 
        user = Puppet::Type.type(:user).create(:name => nonrootuser.name, :ensure => :present, :gid => group.title)
1023
 
        
 
832
        group = Puppet::Type.type(:group).new(:name => nonrootgroup.name, :ensure => :present)
 
833
        user = Puppet::Type.type(:user).new(:name => nonrootuser.name, :ensure => :present, :gid => group.title)
 
834
 
1024
835
        # Now add the explicit relationship
1025
836
        group[:require] = user
1026
837
        rels[group] = user
1027
838
        # Now files
1028
839
        d = tempfile()
1029
840
        f = File.join(d, "file")
1030
 
        file = Puppet::Type.type(:file).create(:path => f, :content => "yay")
1031
 
        dir = Puppet::Type.type(:file).create(:path => d, :ensure => :directory, :require => file)
1032
 
        
 
841
        file = Puppet::Type.type(:file).new(:path => f, :content => "yay")
 
842
        dir = Puppet::Type.type(:file).new(:path => d, :ensure => :directory, :require => file)
 
843
 
1033
844
        rels[dir] = file
1034
845
        rels.each do |after, before|
1035
846
            config = mk_catalog(before, after)
1036
847
            trans = Puppet::Transaction.new(config)
1037
848
            str = "from %s to %s" % [before, after]
1038
 
        
 
849
 
1039
850
            assert_nothing_raised("Failed to create graph %s" % str) do
1040
851
                trans.prepare
1041
852
            end
1042
 
        
 
853
 
1043
854
            graph = trans.relationship_graph
1044
855
            assert(graph.edge?(before, after), "did not create manual relationship %s" % str)
1045
856
            assert(! graph.edge?(after, before), "created automatic relationship %s" % str)
1052
863
        path = tempfile
1053
864
        epath = tempfile
1054
865
        spath = tempfile
1055
 
        file = Puppet::Type.type(:file).create(:path => path, :ensure => :file,
 
866
        file = Puppet::Type.type(:file).new(:path => path, :ensure => :file,
1056
867
            :title => "file")
1057
 
        exec = Puppet::Type.type(:exec).create(:command => "touch %s" % epath,
 
868
        exec = Puppet::Type.type(:exec).new(:command => "touch %s" % epath,
1058
869
            :path => ENV["PATH"], :subscribe => file, :refreshonly => true,
1059
870
            :title => 'exec1')
1060
 
        exec2 = Puppet::Type.type(:exec).create(:command => "touch %s" % spath,
 
871
        exec2 = Puppet::Type.type(:exec).new(:command => "touch %s" % spath,
1061
872
            :path => ENV["PATH"], :subscribe => exec, :refreshonly => true,
1062
873
            :title => 'exec2')
1063
874
 
1090
901
        3.times do |i|
1091
902
            path = tempfile
1092
903
            paths << path
1093
 
            file = Puppet::Type.type(:file).create(:path => path, :ensure => :absent,
 
904
            file = Puppet::Type.type(:file).new(:path => path, :ensure => :absent,
1094
905
                :backup => false, :title => "file%s" % i)
1095
906
            File.open(path, "w") { |f| f.puts "" }
1096
907
            files << file
1109
920
    end
1110
921
 
1111
922
    def test_flush
1112
 
        $state = "absent"
 
923
        $state = :absent
1113
924
        $flushed = 0
1114
925
        type = Puppet::Type.newtype(:flushtest) do
1115
926
            newparam(:name)
1116
927
            newproperty(:ensure) do
 
928
                newvalues :absent, :present, :other
1117
929
                def retrieve
1118
930
                    $state
1119
931
                end
1130
942
 
1131
943
        cleanup { Puppet::Type.rmtype(:flushtest) }
1132
944
 
1133
 
        obj = type.create(:name => "test", :ensure => "present")
 
945
        obj = type.new(:name => "test", :ensure => :present)
1134
946
 
1135
947
        # first make sure it runs through and flushes
1136
948
        assert_apply(obj)
1137
949
 
1138
 
        assert_equal("present", $state, "Object did not make a change")
 
950
        assert_equal(:present, $state, "Object did not make a change")
1139
951
        assert_equal(1, $flushed, "object was not flushed")
1140
952
 
1141
953
        # Now run a noop and make sure we don't flush
1143
955
        obj[:noop] = true
1144
956
 
1145
957
        assert_apply(obj)
1146
 
        assert_equal("present", $state, "Object made a change in noop")
 
958
        assert_equal(:present, $state, "Object made a change in noop")
1147
959
        assert_equal(1, $flushed, "object was flushed in noop")
1148
960
    end
1149
961
end