puppet 2.7.9 → 2.7.11

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (187) hide show
  1. data/CHANGELOG +413 -0
  2. data/README_DEVELOPER.md +28 -0
  3. data/conf/redhat/puppet.spec +10 -1
  4. data/conf/solaris/pkginfo +1 -1
  5. data/conf/suse/puppet.spec +7 -4
  6. data/ext/envpuppet.bat +13 -0
  7. data/ext/rack/files/apache2.conf +4 -0
  8. data/install.rb +4 -8
  9. data/lib/puppet.rb +1 -1
  10. data/lib/puppet/agent.rb +7 -0
  11. data/lib/puppet/agent/disabler.rb +27 -0
  12. data/lib/puppet/agent/locker.rb +0 -10
  13. data/lib/puppet/application.rb +3 -0
  14. data/lib/puppet/application/agent.rb +13 -3
  15. data/lib/puppet/application/apply.rb +6 -6
  16. data/lib/puppet/application/cert.rb +5 -5
  17. data/lib/puppet/application/instrumentation_data.rb +4 -0
  18. data/lib/puppet/application/instrumentation_listener.rb +4 -0
  19. data/lib/puppet/application/instrumentation_probe.rb +4 -0
  20. data/lib/puppet/configurer.rb +3 -1
  21. data/lib/puppet/configurer/downloader.rb +4 -2
  22. data/lib/puppet/configurer/fact_handler.rb +0 -21
  23. data/lib/puppet/daemon.rb +3 -4
  24. data/lib/puppet/defaults.rb +2 -2
  25. data/lib/puppet/face/instrumentation_data.rb +28 -0
  26. data/lib/puppet/face/instrumentation_listener.rb +96 -0
  27. data/lib/puppet/face/instrumentation_probe.rb +77 -0
  28. data/lib/puppet/face/module/list.rb +64 -0
  29. data/lib/puppet/face/module/uninstall.rb +50 -0
  30. data/lib/puppet/face/node/clean.rb +1 -4
  31. data/lib/puppet/feature/base.rb +1 -0
  32. data/lib/puppet/file_serving/content.rb +1 -1
  33. data/lib/puppet/indirector/facts/facter.rb +20 -7
  34. data/lib/puppet/indirector/facts/inventory_active_record.rb +14 -11
  35. data/lib/puppet/indirector/indirection.rb +7 -0
  36. data/lib/puppet/indirector/instrumentation_data.rb +3 -0
  37. data/lib/puppet/indirector/instrumentation_data/local.rb +19 -0
  38. data/lib/puppet/indirector/instrumentation_data/rest.rb +5 -0
  39. data/lib/puppet/indirector/instrumentation_listener.rb +3 -0
  40. data/lib/puppet/indirector/instrumentation_listener/local.rb +23 -0
  41. data/lib/puppet/indirector/instrumentation_listener/rest.rb +5 -0
  42. data/lib/puppet/indirector/instrumentation_probe.rb +3 -0
  43. data/lib/puppet/indirector/instrumentation_probe/local.rb +24 -0
  44. data/lib/puppet/indirector/instrumentation_probe/rest.rb +5 -0
  45. data/lib/puppet/indirector/rest.rb +1 -1
  46. data/lib/puppet/module.rb +13 -17
  47. data/lib/puppet/module_tool/applications.rb +1 -0
  48. data/lib/puppet/module_tool/applications/uninstaller.rb +33 -0
  49. data/lib/puppet/module_tool/contents_description.rb +1 -1
  50. data/lib/puppet/network/server.rb +2 -3
  51. data/lib/puppet/node/environment.rb +16 -3
  52. data/lib/puppet/parser/ast/leaf.rb +1 -1
  53. data/lib/puppet/parser/functions/create_resources.rb +1 -1
  54. data/lib/puppet/parser/type_loader.rb +1 -1
  55. data/lib/puppet/property.rb +46 -14
  56. data/lib/puppet/provider.rb +13 -4
  57. data/lib/puppet/provider/augeas/augeas.rb +6 -4
  58. data/lib/puppet/provider/group/pw.rb +24 -10
  59. data/lib/puppet/provider/nameservice/directoryservice.rb +146 -37
  60. data/lib/puppet/provider/package/pip.rb +1 -1
  61. data/lib/puppet/provider/package/yum.rb +1 -2
  62. data/lib/puppet/provider/service/debian.rb +14 -0
  63. data/lib/puppet/provider/service/launchd.rb +1 -1
  64. data/lib/puppet/provider/service/smf.rb +2 -2
  65. data/lib/puppet/provider/user/pw.rb +56 -2
  66. data/lib/puppet/provider/user/user_role_add.rb +32 -22
  67. data/lib/puppet/provider/user/windows_adsi.rb +1 -0
  68. data/lib/puppet/rails/benchmark.rb +1 -1
  69. data/lib/puppet/reports/store.rb +8 -1
  70. data/lib/puppet/resource/catalog.rb +5 -1
  71. data/lib/puppet/simple_graph.rb +11 -14
  72. data/lib/puppet/transaction.rb +10 -4
  73. data/lib/puppet/transaction/report.rb +9 -3
  74. data/lib/puppet/type.rb +19 -7
  75. data/lib/puppet/type/exec.rb +1 -1
  76. data/lib/puppet/type/file.rb +4 -1
  77. data/lib/puppet/type/file/ensure.rb +5 -1
  78. data/lib/puppet/type/file/mode.rb +45 -10
  79. data/lib/puppet/type/file/source.rb +4 -0
  80. data/lib/puppet/type/host.rb +17 -3
  81. data/lib/puppet/type/k5login.rb +3 -2
  82. data/lib/puppet/type/schedule.rb +3 -2
  83. data/lib/puppet/util.rb +83 -27
  84. data/lib/puppet/util/anonymous_filelock.rb +36 -0
  85. data/lib/puppet/util/docs.rb +18 -2
  86. data/lib/puppet/util/instrumentation.rb +173 -0
  87. data/lib/puppet/util/instrumentation/data.rb +34 -0
  88. data/lib/puppet/util/instrumentation/indirection_probe.rb +29 -0
  89. data/lib/puppet/util/instrumentation/instrumentable.rb +143 -0
  90. data/lib/puppet/util/instrumentation/listener.rb +60 -0
  91. data/lib/puppet/util/instrumentation/listeners/log.rb +29 -0
  92. data/lib/puppet/util/instrumentation/listeners/performance.rb +30 -0
  93. data/lib/puppet/util/monkey_patches.rb +8 -0
  94. data/lib/puppet/util/pidlock.rb +21 -25
  95. data/lib/puppet/util/rdoc/parser.rb +2 -2
  96. data/lib/puppet/util/reference.rb +8 -23
  97. data/lib/puppet/util/retryaction.rb +48 -0
  98. data/lib/puppet/util/suidmanager.rb +70 -39
  99. data/lib/puppet/util/symbolic_file_mode.rb +140 -0
  100. data/spec/integration/configurer_spec.rb +5 -0
  101. data/spec/integration/indirector/direct_file_server_spec.rb +1 -1
  102. data/spec/integration/indirector/file_content/file_server_spec.rb +7 -7
  103. data/spec/integration/provider/package_spec.rb +7 -0
  104. data/spec/unit/agent/disabler_spec.rb +60 -0
  105. data/spec/unit/agent/locker_spec.rb +0 -12
  106. data/spec/unit/agent_spec.rb +8 -0
  107. data/spec/unit/application/agent_spec.rb +38 -1
  108. data/spec/unit/application/apply_spec.rb +34 -40
  109. data/spec/unit/application/cert_spec.rb +1 -1
  110. data/spec/unit/application_spec.rb +6 -0
  111. data/spec/unit/configurer/downloader_spec.rb +29 -10
  112. data/spec/unit/configurer/fact_handler_spec.rb +5 -29
  113. data/spec/unit/configurer_spec.rb +8 -8
  114. data/spec/unit/daemon_spec.rb +12 -26
  115. data/spec/unit/face/instrumentation_data.rb +7 -0
  116. data/spec/unit/face/instrumentation_listener.rb +38 -0
  117. data/spec/unit/face/instrumentation_probe.rb +21 -0
  118. data/spec/unit/face/node_spec.rb +111 -111
  119. data/spec/unit/file_serving/content_spec.rb +2 -2
  120. data/spec/unit/indirector/facts/facter_spec.rb +25 -3
  121. data/spec/unit/indirector/facts/inventory_active_record_spec.rb +14 -4
  122. data/spec/unit/indirector/instrumentation_data/local_spec.rb +52 -0
  123. data/spec/unit/indirector/instrumentation_data/rest_spec.rb +11 -0
  124. data/spec/unit/indirector/instrumentation_listener/local_spec.rb +65 -0
  125. data/spec/unit/indirector/instrumentation_listener/rest_spec.rb +11 -0
  126. data/spec/unit/indirector/instrumentation_probe/local_spec.rb +65 -0
  127. data/spec/unit/indirector/instrumentation_probe/rest_spec.rb +11 -0
  128. data/spec/unit/module_spec.rb +39 -125
  129. data/spec/unit/module_tool/uninstaller_spec.rb +44 -0
  130. data/spec/unit/network/server_spec.rb +2 -20
  131. data/spec/unit/node/environment_spec.rb +76 -58
  132. data/spec/unit/parser/ast/asthash_spec.rb +1 -2
  133. data/spec/unit/parser/ast/leaf_spec.rb +16 -0
  134. data/spec/unit/property/keyvalue_spec.rb +5 -2
  135. data/spec/unit/property_spec.rb +260 -159
  136. data/spec/unit/provider/augeas/augeas_spec.rb +2 -2
  137. data/spec/unit/provider/group/pw_spec.rb +81 -0
  138. data/spec/unit/provider/nameservice/directoryservice_spec.rb +102 -0
  139. data/spec/unit/provider/package/pip_spec.rb +7 -0
  140. data/spec/unit/provider/package/yum_spec.rb +45 -1
  141. data/spec/unit/provider/service/debian_spec.rb +15 -0
  142. data/spec/unit/provider/service/launchd_spec.rb +48 -43
  143. data/spec/unit/provider/service/smf_spec.rb +3 -3
  144. data/spec/unit/provider/user/pw_spec.rb +183 -0
  145. data/spec/unit/provider/user/user_role_add_spec.rb +46 -39
  146. data/spec/unit/provider/user/windows_adsi_spec.rb +1 -0
  147. data/spec/unit/provider_spec.rb +32 -0
  148. data/spec/unit/reports/store_spec.rb +19 -1
  149. data/spec/unit/simple_graph_spec.rb +34 -19
  150. data/spec/unit/ssl/certificate_factory_spec.rb +3 -3
  151. data/spec/unit/transaction/report_spec.rb +29 -1
  152. data/spec/unit/transaction_spec.rb +32 -46
  153. data/spec/unit/type/file/mode_spec.rb +1 -1
  154. data/spec/unit/type/file/source_spec.rb +28 -3
  155. data/spec/unit/type/file_spec.rb +17 -16
  156. data/spec/unit/type/host_spec.rb +527 -0
  157. data/spec/unit/type/k5login_spec.rb +115 -0
  158. data/spec/unit/type/schedule_spec.rb +6 -6
  159. data/spec/unit/type_spec.rb +51 -0
  160. data/spec/unit/util/anonymous_filelock_spec.rb +78 -0
  161. data/spec/unit/util/execution_stub_spec.rb +2 -1
  162. data/spec/unit/util/instrumentation/data_spec.rb +44 -0
  163. data/spec/unit/util/instrumentation/indirection_probe_spec.rb +19 -0
  164. data/spec/unit/util/instrumentation/instrumentable_spec.rb +186 -0
  165. data/spec/unit/util/instrumentation/listener_spec.rb +100 -0
  166. data/spec/unit/util/instrumentation/listeners/log_spec.rb +34 -0
  167. data/spec/unit/util/instrumentation/listeners/performance_spec.rb +36 -0
  168. data/spec/unit/util/instrumentation_spec.rb +181 -0
  169. data/spec/unit/util/pidlock_spec.rb +208 -0
  170. data/spec/unit/util/rdoc/parser_spec.rb +1 -1
  171. data/spec/unit/util/reference_spec.rb +16 -6
  172. data/spec/unit/util/retryaction_spec.rb +62 -0
  173. data/spec/unit/util/suidmanager_spec.rb +101 -83
  174. data/spec/unit/util/symbolic_file_mode_spec.rb +182 -0
  175. data/spec/unit/util_spec.rb +126 -0
  176. data/tasks/rake/apple.rake +176 -0
  177. data/tasks/rake/templates/prototype.plist.erb +38 -0
  178. metadata +61 -13
  179. data/lib/puppet/application/module.rb +0 -3
  180. data/lib/puppet/face/module.rb +0 -12
  181. data/spec/unit/face/module/build_spec.rb +0 -30
  182. data/spec/unit/face/module/changes_spec.rb +0 -30
  183. data/spec/unit/face/module/clean_spec.rb +0 -30
  184. data/spec/unit/face/module/generate_spec.rb +0 -30
  185. data/spec/unit/face/module/install_spec.rb +0 -75
  186. data/spec/unit/face/module/search_spec.rb +0 -40
  187. data/test/util/pidlock.rb +0 -126
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+ require 'matchers/json'
5
+
6
+ require 'puppet/util/instrumentation'
7
+ require 'puppet/util/instrumentation/listener'
8
+
9
+ describe Puppet::Util::Instrumentation::Listener do
10
+
11
+ Listener = Puppet::Util::Instrumentation::Listener
12
+
13
+ before(:each) do
14
+ @delegate = stub 'listener', :notify => nil, :name => 'listener'
15
+ @listener = Listener.new(@delegate)
16
+ @listener.enabled = true
17
+ end
18
+
19
+ it "should indirect instrumentation_listener" do
20
+ Listener.indirection.name.should == :instrumentation_listener
21
+ end
22
+
23
+ it "should raise an error if delegate doesn't support notify" do
24
+ lambda { Listener.new(Object.new) }.should raise_error
25
+ end
26
+
27
+ it "should not be enabled by default" do
28
+ Listener.new(@delegate).should_not be_enabled
29
+ end
30
+
31
+ it "should delegate notification" do
32
+ @delegate.expects(:notify).with(:event, :start, {})
33
+ listener = Listener.new(@delegate)
34
+ listener.notify(:event, :start, {})
35
+ end
36
+
37
+ it "should not listen is not enabled" do
38
+ @listener.enabled = false
39
+ @listener.should_not be_listen_to(:label)
40
+ end
41
+
42
+ it "should listen to all label if created without pattern" do
43
+ @listener.should be_listen_to(:improbable_label)
44
+ end
45
+
46
+ it "should listen to specific string pattern" do
47
+ listener = Listener.new(@delegate, "specific")
48
+ listener.enabled = true
49
+ listener.should be_listen_to(:specific)
50
+ end
51
+
52
+ it "should not listen to non-matching string pattern" do
53
+ listener = Listener.new(@delegate, "specific")
54
+ listener.enabled = true
55
+ listener.should_not be_listen_to(:unspecific)
56
+ end
57
+
58
+ it "should listen to specific regex pattern" do
59
+ listener = Listener.new(@delegate, /spe.*/)
60
+ listener.enabled = true
61
+ listener.should be_listen_to(:specific_pattern)
62
+ end
63
+
64
+ it "should not listen to non matching regex pattern" do
65
+ listener = Listener.new(@delegate, /^match.*/)
66
+ listener.enabled = true
67
+ listener.should_not be_listen_to(:not_matching)
68
+ end
69
+
70
+ it "should delegate its name to the underlying listener" do
71
+ @delegate.expects(:name).returns("myname")
72
+ @listener.name.should == "myname"
73
+ end
74
+
75
+ it "should delegate data fetching to the underlying listener" do
76
+ @delegate.expects(:data).returns(:data)
77
+ @listener.data.should == {:data => :data }
78
+ end
79
+
80
+ describe "when serializing to pson" do
81
+ it "should return a pson object containing pattern, name and status" do
82
+ @listener.should set_json_attribute('enabled').to(true)
83
+ @listener.should set_json_attribute('name').to("listener")
84
+ end
85
+ end
86
+
87
+ describe "when deserializing from pson" do
88
+ it "should lookup the archetype listener from the instrumentation layer" do
89
+ Puppet::Util::Instrumentation.expects(:[]).with("listener").returns(@listener)
90
+ Puppet::Util::Instrumentation::Listener.from_pson({"name" => "listener"})
91
+ end
92
+
93
+ it "should create a new listener shell instance delegating to the archetypal listener" do
94
+ Puppet::Util::Instrumentation.expects(:[]).with("listener").returns(@listener)
95
+ @listener.stubs(:listener).returns(@delegate)
96
+ Puppet::Util::Instrumentation::Listener.expects(:new).with(@delegate, nil, true)
97
+ Puppet::Util::Instrumentation::Listener.from_pson({"name" => "listener", "enabled" => true})
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'puppet/util/instrumentation'
3
+
4
+ Puppet::Util::Instrumentation.init
5
+ log = Puppet::Util::Instrumentation.listener(:log)
6
+
7
+ describe log do
8
+ before(:each) do
9
+ @log = log.new
10
+ end
11
+
12
+ it "should have a notify method" do
13
+ @log.should respond_to(:notify)
14
+ end
15
+
16
+ it "should have a data method" do
17
+ @log.should respond_to(:data)
18
+ end
19
+
20
+ it "should keep data for stop event" do
21
+ @log.notify(:test, :stop, { :started => Time.at(123456789), :finished => Time.at(123456790)})
22
+ @log.data.should == {:test=>["test took 1.0"]}
23
+ end
24
+
25
+ it "should not keep data for start event" do
26
+ @log.notify(:test, :start, { :started => Time.at(123456789)})
27
+ @log.data.should be_empty
28
+ end
29
+
30
+ it "should not keep more than 20 events per label" do
31
+ 25.times { @log.notify(:test, :stop, { :started => Time.at(123456789), :finished => Time.at(123456790)}) }
32
+ @log.data[:test].size.should == 20
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'puppet/util/instrumentation'
3
+
4
+ Puppet::Util::Instrumentation.init
5
+ performance = Puppet::Util::Instrumentation.listener(:performance)
6
+
7
+ describe performance do
8
+ before(:each) do
9
+ @performance = performance.new
10
+ end
11
+
12
+ it "should have a notify method" do
13
+ @performance.should respond_to(:notify)
14
+ end
15
+
16
+ it "should have a data method" do
17
+ @performance.should respond_to(:data)
18
+ end
19
+
20
+ it "should keep data for stop event" do
21
+ @performance.notify(:test, :stop, { :started => Time.at(123456789), :finished => Time.at(123456790)})
22
+ @performance.data.should == {:test=>{:average=>1.0, :count=>1, :min=>1.0, :max=>1.0, :sum=>1.0}}
23
+ end
24
+
25
+ it "should accumulate performance statistics" do
26
+ @performance.notify(:test, :stop, { :started => Time.at(123456789), :finished => Time.at(123456790)})
27
+ @performance.notify(:test, :stop, { :started => Time.at(123456789), :finished => Time.at(123456791)})
28
+
29
+ @performance.data.should == {:test=>{:average=>1.5, :count=>2, :min=>1.0, :max=>2.0, :sum=>3.0}}
30
+ end
31
+
32
+ it "should not keep data for start event" do
33
+ @performance.notify(:test, :start, { :started => Time.at(123456789)})
34
+ @performance.data.should be_empty
35
+ end
36
+ end
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'puppet/util/instrumentation'
6
+
7
+ describe Puppet::Util::Instrumentation do
8
+
9
+ Instrumentation = Puppet::Util::Instrumentation
10
+
11
+ after(:each) do
12
+ Instrumentation.clear
13
+ end
14
+
15
+ it "should instance-load instrumentation listeners" do
16
+ Instrumentation.instance_loader(:listener).should be_instance_of(Puppet::Util::Autoload)
17
+ end
18
+
19
+ it "should have a method for registering instrumentation listeners" do
20
+ Instrumentation.should respond_to(:new_listener)
21
+ end
22
+
23
+ it "should have a method for retrieving instrumentation listener by name" do
24
+ Instrumentation.should respond_to(:listener)
25
+ end
26
+
27
+ describe "when registering listeners" do
28
+ it "should evaluate the supplied block as code for a class" do
29
+ Instrumentation.expects(:genclass).returns(Class.new { def notify(label, event, data) ; end })
30
+ Instrumentation.new_listener(:testing, :label_pattern => :for_this_label, :event => :all) { }
31
+ end
32
+
33
+ it "should subscribe a new listener instance" do
34
+ Instrumentation.expects(:genclass).returns(Class.new { def notify(label, event, data) ; end })
35
+ Instrumentation.new_listener(:testing, :label_pattern => :for_this_label, :event => :all) { }
36
+ Instrumentation.listeners.size.should == 1
37
+ Instrumentation.listeners[0].pattern.should == "for_this_label"
38
+ end
39
+
40
+ it "should be possible to access listeners by name" do
41
+ Instrumentation.expects(:genclass).returns(Class.new { def notify(label, event, data) ; end })
42
+ Instrumentation.new_listener(:testing, :label_pattern => :for_this_label, :event => :all) { }
43
+ Instrumentation["testing"].should_not be_nil
44
+ end
45
+
46
+ it "should be possible to store a new listener by name" do
47
+ listener = stub 'listener'
48
+ Instrumentation["testing"] = listener
49
+ Instrumentation["testing"].should == listener
50
+ end
51
+
52
+ it "should fail if listener is already subscribed" do
53
+ listener = stub 'listener', :notify => nil, :name => "mylistener"
54
+ Instrumentation.subscribe(listener, :for_this_label, :all)
55
+ expect { Instrumentation.subscribe(listener, :for_this_label, :all) }.to raise_error
56
+ end
57
+
58
+ it 'should call #unsubscribed' do
59
+ listener = stub 'listener', :notify => nil, :name => "mylistener"
60
+
61
+ listener.expects(:subscribed)
62
+
63
+ Instrumentation.subscribe(listener, :for_this_label, :all)
64
+ end
65
+ end
66
+
67
+ describe "when unsubscribing listener" do
68
+ it "should remove it from the listeners" do
69
+ listener = stub 'listener', :notify => nil, :name => "mylistener"
70
+ Instrumentation.subscribe(listener, :for_this_label, :all)
71
+ Instrumentation.unsubscribe(listener)
72
+ Instrumentation.listeners.size.should == 0
73
+ end
74
+
75
+ it "should warn if the listener wasn't subscribed" do
76
+ listener = stub 'listener', :notify => nil, :name => "mylistener"
77
+ Puppet.expects(:warning)
78
+ Instrumentation.unsubscribe(listener)
79
+ end
80
+
81
+ it 'should call #unsubscribed' do
82
+ listener = stub 'listener', :notify => nil, :name => "mylistener"
83
+ Instrumentation.subscribe(listener, :for_this_label, :all)
84
+
85
+ listener.expects(:unsubscribed)
86
+
87
+ Instrumentation.unsubscribe(listener)
88
+ end
89
+ end
90
+
91
+ describe "when firing events" do
92
+ it "should be able to find all listeners matching a label" do
93
+ listener = stub 'listener', :notify => nil, :name => "mylistener"
94
+ Instrumentation.subscribe(listener, :for_this_label, :all)
95
+ Instrumentation.listeners[0].enabled = true
96
+
97
+ count = 0
98
+ Instrumentation.each_listener(:for_this_label) { |l| count += 1 }
99
+ count.should == 1
100
+ end
101
+
102
+ it "should fire events to matching listeners" do
103
+ listener = stub 'listener', :notify => nil, :name => "mylistener"
104
+ Instrumentation.subscribe(listener, :for_this_label, :all)
105
+ Instrumentation.listeners[0].enabled = true
106
+
107
+ listener.expects(:notify).with(:for_this_label, :start, {})
108
+
109
+ Instrumentation.publish(:for_this_label, :start, {})
110
+ end
111
+
112
+ it "should not fire events to non-matching listeners" do
113
+ listener1 = stub 'listener1', :notify => nil, :name => "mylistener1"
114
+ listener2 = stub 'listener2', :notify => nil, :name => "mylistener2"
115
+ Instrumentation.subscribe(listener1, :for_this_label, :all)
116
+ Instrumentation.listeners[0].enabled = true
117
+ Instrumentation.subscribe(listener2, :for_this_other_label, :all)
118
+ Instrumentation.listeners[1].enabled = true
119
+
120
+ listener1.expects(:notify).never
121
+ listener2.expects(:notify).with(:for_this_other_label, :start, {})
122
+
123
+ Instrumentation.publish(:for_this_other_label, :start, {})
124
+ end
125
+ end
126
+
127
+ describe "when instrumenting code" do
128
+ before(:each) do
129
+ Instrumentation.stubs(:publish)
130
+ end
131
+ describe "with a block" do
132
+ it "should execute it" do
133
+ executed = false
134
+ Instrumentation.instrument(:event) do
135
+ executed = true
136
+ end
137
+ executed.should be_true
138
+ end
139
+
140
+ it "should publish an event before execution" do
141
+ Instrumentation.expects(:publish).with { |label,event,data| label == :event && event == :start }
142
+ Instrumentation.instrument(:event) {}
143
+ end
144
+
145
+ it "should publish an event after execution" do
146
+ Instrumentation.expects(:publish).with { |label,event,data| label == :event && event == :stop }
147
+ Instrumentation.instrument(:event) {}
148
+ end
149
+
150
+ it "should publish the event even when block raised an exception" do
151
+ Instrumentation.expects(:publish).with { |label,event,data| label == :event }
152
+ lambda { Instrumentation.instrument(:event) { raise "not working" } }.should raise_error
153
+ end
154
+
155
+ it "should retain start end finish time of the event" do
156
+ Instrumentation.expects(:publish).with { |label,event,data| data.include?(:started) and data.include?(:finished) }
157
+ Instrumentation.instrument(:event) {}
158
+ end
159
+ end
160
+
161
+ describe "without a block" do
162
+ it "should raise an error if stop is called with no matching start" do
163
+ lambda{ Instrumentation.stop(:event) }.should raise_error
164
+ end
165
+
166
+ it "should publish an event on stop" do
167
+ Instrumentation.expects(:publish).with { |label,event,data| event == :start }
168
+ Instrumentation.expects(:publish).with { |label,event,data| event == :stop and data.include?(:started) and data.include?(:finished) }
169
+ data = {}
170
+ Instrumentation.start(:event, data)
171
+ Instrumentation.stop(:event, 1, data)
172
+ end
173
+
174
+ it "should return a different id per event" do
175
+ data = {}
176
+ Instrumentation.start(:event, data).should == 1
177
+ Instrumentation.start(:event, data).should == 2
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env rspec
2
+ require 'spec_helper'
3
+
4
+ require 'puppet/util/pidlock'
5
+
6
+ describe Puppet::Util::Pidlock do
7
+ require 'puppet_spec/files'
8
+ include PuppetSpec::Files
9
+
10
+ before(:each) do
11
+ @lockfile = tmpfile("lock")
12
+ @lock = Puppet::Util::Pidlock.new(@lockfile)
13
+ end
14
+
15
+ it "should not be anonymous" do
16
+ @lock.should_not be_anonymous
17
+ end
18
+
19
+ describe "#lock" do
20
+ it "should not be locked at start" do
21
+ @lock.should_not be_locked
22
+ end
23
+
24
+ it "should not be mine at start" do
25
+ @lock.should_not be_mine
26
+ end
27
+
28
+ it "should become locked" do
29
+ @lock.lock
30
+ @lock.should be_locked
31
+ end
32
+
33
+ it "should become mine" do
34
+ @lock.lock
35
+ @lock.should be_mine
36
+ end
37
+
38
+ it "should be possible to lock multiple times" do
39
+ @lock.lock
40
+ lambda { @lock.lock }.should_not raise_error
41
+ end
42
+
43
+ it "should return true when locking" do
44
+ @lock.lock.should be_true
45
+ end
46
+
47
+ it "should return true if locked by me" do
48
+ @lock.lock
49
+ @lock.lock.should be_true
50
+ end
51
+
52
+ it "should return false if locked by someone else" do
53
+ Process.stubs(:kill)
54
+ File.open(@lockfile, "w") { |fd| fd.print('0') }
55
+
56
+ @lock.lock.should be_false
57
+ end
58
+
59
+ it "should create a lock file" do
60
+ @lock.lock
61
+ File.should be_exists(@lockfile)
62
+ end
63
+
64
+ it "should create a lock file containing our pid" do
65
+ @lock.lock
66
+ File.read(@lockfile).to_i.should == Process.pid.to_i
67
+ end
68
+ end
69
+
70
+ describe "#unlock" do
71
+ it "should not be locked anymore" do
72
+ @lock.lock
73
+ @lock.unlock
74
+ @lock.should_not be_locked
75
+ end
76
+
77
+ it "should return false if not locked" do
78
+ @lock.unlock.should be_false
79
+ end
80
+
81
+ it "should return true if properly unlocked" do
82
+ @lock.lock
83
+ @lock.unlock.should be_true
84
+ end
85
+
86
+ it "should get rid of the lock file" do
87
+ @lock.lock
88
+ @lock.unlock
89
+ File.should_not be_exists(@lockfile)
90
+ end
91
+
92
+ it "should not warn if the lockfile was deleted by someone else" do
93
+ @lock.lock
94
+ File.unlink(@lockfile)
95
+
96
+ Puppet.expects(:err).never # meh
97
+ @lock.unlock
98
+ end
99
+
100
+ it "should warn if the lockfile can't be deleted" do
101
+ @lock.lock
102
+ File.expects(:unlink).with(@lockfile).raises(Errno::EIO)
103
+ Puppet.expects(:err).with do |argument|
104
+ argument.should =~ /Input\/output error/
105
+ end
106
+ @lock.unlock
107
+
108
+ # This is necessary because our cleanup code uses File.unlink
109
+ File.unstub(:unlink)
110
+ @lock.unlock
111
+ end
112
+ end
113
+
114
+ describe "#locked?" do
115
+ it "should return true if locked" do
116
+ @lock.lock
117
+ @lock.should be_locked
118
+ end
119
+ end
120
+
121
+ describe "with a stale lock" do
122
+ before(:each) do
123
+ Process.stubs(:kill).with(0, 6789)
124
+ Process.stubs(:kill).with(0, 1234).raises(Errno::ESRCH)
125
+ Process.stubs(:pid).returns(6789)
126
+ File.open(@lockfile, 'w') { |fd| fd.write("1234") }
127
+ end
128
+
129
+ it "should not be locked" do
130
+ @lock.should_not be_locked
131
+ end
132
+
133
+ describe "#lock" do
134
+ it "should clear stale locks" do
135
+ @lock.locked?
136
+ File.should_not be_exists(@lockfile)
137
+ end
138
+
139
+ it "should replace with new locks" do
140
+ @lock.lock
141
+ File.should be_exists(@lockfile)
142
+ @lock.lock_pid.should == 6789
143
+ @lock.should be_mine
144
+ @lock.should be_locked
145
+ end
146
+ end
147
+
148
+ describe "#unlock" do
149
+ it "should not be allowed" do
150
+ @lock.unlock.should be_false
151
+ end
152
+
153
+ it "should not remove the lock file" do
154
+ @lock.unlock
155
+ File.should be_exists(@lockfile)
156
+ end
157
+ end
158
+ end
159
+
160
+ describe "with another process lock" do
161
+ before(:each) do
162
+ Process.stubs(:kill).with(0, 6789)
163
+ Process.stubs(:kill).with(0, 1234)
164
+ Process.stubs(:pid).returns(6789)
165
+ File.open(@lockfile, 'w') { |fd| fd.write("1234") }
166
+ end
167
+
168
+ it "should be locked" do
169
+ @lock.should be_locked
170
+ end
171
+
172
+ it "should not be mine" do
173
+ @lock.should_not be_mine
174
+ end
175
+
176
+ describe "#lock" do
177
+ it "should not be possible" do
178
+ @lock.lock.should be_false
179
+ end
180
+
181
+ it "should not overwrite the lock" do
182
+ @lock.lock
183
+ @lock.should_not be_mine
184
+ end
185
+ end
186
+
187
+ describe "#unlock" do
188
+ it "should not be possible" do
189
+ @lock.unlock.should be_false
190
+ end
191
+
192
+ it "should not remove the lock file" do
193
+ @lock.unlock
194
+ File.should be_exists(@lockfile)
195
+ end
196
+
197
+ it "should still not be our lock" do
198
+ @lock.unlock
199
+ @lock.should_not be_mine
200
+ end
201
+
202
+ it "should not warn" do
203
+ Puppet.expects(:err).never
204
+ @lock.unlock
205
+ end
206
+ end
207
+ end
208
+ end