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
@@ -7,6 +7,8 @@ require 'puppet/node/environment'
7
7
  require 'puppet/util/execution'
8
8
 
9
9
  describe Puppet::Node::Environment do
10
+ let(:env) { Puppet::Node::Environment.new("testing") }
11
+
10
12
  include PuppetSpec::Files
11
13
  after do
12
14
  Puppet::Node::Environment.clear
@@ -44,59 +46,57 @@ describe Puppet::Node::Environment do
44
46
 
45
47
  describe "when managing known resource types" do
46
48
  before do
47
- @env = Puppet::Node::Environment.new("dev")
48
- @collection = Puppet::Resource::TypeCollection.new(@env)
49
- @env.stubs(:perform_initial_import).returns(Puppet::Parser::AST::Hostclass.new(''))
49
+ @collection = Puppet::Resource::TypeCollection.new(env)
50
+ env.stubs(:perform_initial_import).returns(Puppet::Parser::AST::Hostclass.new(''))
50
51
  Thread.current[:known_resource_types] = nil
51
52
  end
52
53
 
53
54
  it "should create a resource type collection if none exists" do
54
- Puppet::Resource::TypeCollection.expects(:new).with(@env).returns @collection
55
- @env.known_resource_types.should equal(@collection)
55
+ Puppet::Resource::TypeCollection.expects(:new).with(env).returns @collection
56
+ env.known_resource_types.should equal(@collection)
56
57
  end
57
58
 
58
59
  it "should reuse any existing resource type collection" do
59
- @env.known_resource_types.should equal(@env.known_resource_types)
60
+ env.known_resource_types.should equal(env.known_resource_types)
60
61
  end
61
62
 
62
63
  it "should perform the initial import when creating a new collection" do
63
- @env = Puppet::Node::Environment.new("dev")
64
- @env.expects(:perform_initial_import).returns(Puppet::Parser::AST::Hostclass.new(''))
65
- @env.known_resource_types
64
+ env.expects(:perform_initial_import).returns(Puppet::Parser::AST::Hostclass.new(''))
65
+ env.known_resource_types
66
66
  end
67
67
 
68
68
  it "should return the same collection even if stale if it's the same thread" do
69
69
  Puppet::Resource::TypeCollection.stubs(:new).returns @collection
70
- @env.known_resource_types.stubs(:stale?).returns true
70
+ env.known_resource_types.stubs(:stale?).returns true
71
71
 
72
- @env.known_resource_types.should equal(@collection)
72
+ env.known_resource_types.should equal(@collection)
73
73
  end
74
74
 
75
75
  it "should return the current thread associated collection if there is one" do
76
76
  Thread.current[:known_resource_types] = @collection
77
77
 
78
- @env.known_resource_types.should equal(@collection)
78
+ env.known_resource_types.should equal(@collection)
79
79
  end
80
80
 
81
81
  it "should give to all threads using the same environment the same collection if the collection isn't stale" do
82
- original_thread_type_collection = Puppet::Resource::TypeCollection.new(@env)
83
- Puppet::Resource::TypeCollection.expects(:new).with(@env).returns original_thread_type_collection
84
- @env.known_resource_types.should equal(original_thread_type_collection)
82
+ original_thread_type_collection = Puppet::Resource::TypeCollection.new(env)
83
+ Puppet::Resource::TypeCollection.expects(:new).with(env).returns original_thread_type_collection
84
+ env.known_resource_types.should equal(original_thread_type_collection)
85
85
 
86
86
  original_thread_type_collection.expects(:require_reparse?).returns(false)
87
- Puppet::Resource::TypeCollection.stubs(:new).with(@env).returns @collection
87
+ Puppet::Resource::TypeCollection.stubs(:new).with(env).returns @collection
88
88
 
89
89
  t = Thread.new {
90
- @env.known_resource_types.should equal(original_thread_type_collection)
90
+ env.known_resource_types.should equal(original_thread_type_collection)
91
91
  }
92
92
  t.join
93
93
  end
94
94
 
95
95
  it "should generate a new TypeCollection if the current one requires reparsing" do
96
- old_type_collection = @env.known_resource_types
96
+ old_type_collection = env.known_resource_types
97
97
  old_type_collection.stubs(:require_reparse?).returns true
98
98
  Thread.current[:known_resource_types] = nil
99
- new_type_collection = @env.known_resource_types
99
+ new_type_collection = env.known_resource_types
100
100
 
101
101
  new_type_collection.should be_a Puppet::Resource::TypeCollection
102
102
  new_type_collection.should_not equal(old_type_collection)
@@ -109,14 +109,11 @@ describe Puppet::Node::Environment do
109
109
 
110
110
  Puppet[:modulepath] = path
111
111
 
112
- env = Puppet::Node::Environment.new("testing")
113
-
114
112
  env.modulepath.should == [real_file]
115
113
  end
116
114
 
117
115
  it "should prefix the value of the 'PUPPETLIB' environment variable to the module path if present" do
118
116
  Puppet::Util::Execution.withenv("PUPPETLIB" => %w{/l1 /l2}.join(File::PATH_SEPARATOR)) do
119
- env = Puppet::Node::Environment.new("testing")
120
117
  module_path = %w{/one /two}.join(File::PATH_SEPARATOR)
121
118
  env.expects(:validate_dirs).with(%w{/l1 /l2 /one /two}).returns %w{/l1 /l2 /one /two}
122
119
  env.expects(:[]).with(:modulepath).returns module_path
@@ -132,8 +129,6 @@ describe Puppet::Node::Environment do
132
129
  end
133
130
 
134
131
  it "should not return non-directories" do
135
- env = Puppet::Node::Environment.new("testing")
136
-
137
132
  FileTest.expects(:directory?).with(@path_one).returns true
138
133
  FileTest.expects(:directory?).with(@path_two).returns false
139
134
 
@@ -142,7 +137,6 @@ describe Puppet::Node::Environment do
142
137
 
143
138
  it "should use the current working directory to fully-qualify unqualified paths" do
144
139
  FileTest.stubs(:directory?).returns true
145
- env = Puppet::Node::Environment.new("testing")
146
140
 
147
141
  two = File.expand_path(File.join(Dir.getwd, "two"))
148
142
  env.validate_dirs([@path_one, 'two']).should == [@path_one, two]
@@ -155,44 +149,75 @@ describe Puppet::Node::Environment do
155
149
  end
156
150
 
157
151
  it "should provide an array-like accessor method for returning any environment-specific setting" do
158
- env = Puppet::Node::Environment.new("testing")
159
152
  env.should respond_to(:[])
160
153
  end
161
154
 
162
155
  it "should ask the Puppet settings instance for the setting qualified with the environment name" do
163
156
  Puppet.settings.expects(:value).with("myvar", :testing).returns("myval")
164
- env = Puppet::Node::Environment.new("testing")
165
157
  env["myvar"].should == "myval"
166
158
  end
167
159
 
168
160
  it "should be able to return an individual module that exists in its module path" do
169
- env = Puppet::Node::Environment.new("testing")
170
161
 
171
162
  mod = mock 'module'
172
- Puppet::Module.expects(:new).with("one", env).returns mod
163
+ Puppet::Module.expects(:new).with("one", :environment => env).returns mod
173
164
  mod.expects(:exist?).returns true
174
165
 
175
166
  env.module("one").should equal(mod)
176
167
  end
177
168
 
178
169
  it "should return nil if asked for a module that does not exist in its path" do
179
- env = Puppet::Node::Environment.new("testing")
180
170
 
181
171
  mod = mock 'module'
182
- Puppet::Module.expects(:new).with("one", env).returns mod
172
+ Puppet::Module.expects(:new).with("one", :environment => env).returns mod
183
173
  mod.expects(:exist?).returns false
184
174
 
185
175
  env.module("one").should be_nil
186
176
  end
187
177
 
188
- it "should be able to return its modules" do
189
- Puppet::Node::Environment.new("testing").should respond_to(:modules)
178
+ describe ".modules_by_path" do
179
+ before do
180
+ dir = tmpdir("deep_path")
181
+
182
+ @first = File.join(dir, "first")
183
+ @second = File.join(dir, "second")
184
+ Puppet[:modulepath] = "#{@first}#{File::PATH_SEPARATOR}#{@second}"
185
+
186
+ FileUtils.mkdir_p(@first)
187
+ FileUtils.mkdir_p(@second)
188
+ end
189
+
190
+ it "should return an empty list if there are no modules" do
191
+ env.modules_by_path.should == {
192
+ @first => [],
193
+ @second => []
194
+ }
195
+ end
196
+
197
+ it "should include modules even if they exist in multiple dirs in the modulepath" do
198
+ modpath1 = File.join(@first, "foo")
199
+ FileUtils.mkdir_p(modpath1)
200
+ modpath2 = File.join(@second, "foo")
201
+ FileUtils.mkdir_p(modpath2)
202
+
203
+ env.modules_by_path.should == {
204
+ @first => [Puppet::Module.new('foo', :environment => env, :path => modpath1)],
205
+ @second => [Puppet::Module.new('foo', :environment => env, :path => modpath2)]
206
+ }
207
+ end
190
208
  end
191
209
 
192
210
  describe ".modules" do
211
+ it "should return an empty list if there are no modules" do
212
+ env.modulepath = %w{/a /b}
213
+ Dir.expects(:entries).with("/a").returns []
214
+ Dir.expects(:entries).with("/b").returns []
215
+
216
+ env.modules.should == []
217
+ end
218
+
193
219
  it "should return a module named for every directory in each module path" do
194
- env = Puppet::Node::Environment.new("testing")
195
- env.expects(:modulepath).at_least_once.returns %w{/a /b}
220
+ env.modulepath = %w{/a /b}
196
221
  Dir.expects(:entries).with("/a").returns %w{foo bar}
197
222
  Dir.expects(:entries).with("/b").returns %w{bee baz}
198
223
 
@@ -200,8 +225,7 @@ describe Puppet::Node::Environment do
200
225
  end
201
226
 
202
227
  it "should remove duplicates" do
203
- env = Puppet::Node::Environment.new("testing")
204
- env.expects(:modulepath).returns( %w{/a /b} ).at_least_once
228
+ env.modulepath = %w{/a /b}
205
229
  Dir.expects(:entries).with("/a").returns %w{foo}
206
230
  Dir.expects(:entries).with("/b").returns %w{foo}
207
231
 
@@ -209,8 +233,7 @@ describe Puppet::Node::Environment do
209
233
  end
210
234
 
211
235
  it "should ignore invalid modules" do
212
- env = Puppet::Node::Environment.new("testing")
213
- env.stubs(:modulepath).returns %w{/a}
236
+ env.modulepath = %w{/a}
214
237
  Dir.expects(:entries).with("/a").returns %w{foo bar}
215
238
 
216
239
  Puppet::Module.expects(:new).with { |name, env| name == "foo" }.returns mock("foomod", :name => "foo")
@@ -220,16 +243,14 @@ describe Puppet::Node::Environment do
220
243
  end
221
244
 
222
245
  it "should create modules with the correct environment" do
223
- env = Puppet::Node::Environment.new("testing")
224
- env.expects(:modulepath).at_least_once.returns %w{/a}
246
+ env.modulepath = %w{/a}
225
247
  Dir.expects(:entries).with("/a").returns %w{foo}
226
248
 
227
249
  env.modules.each {|mod| mod.environment.should == env }
228
250
  end
229
251
 
230
252
  it "should cache the module list" do
231
- env = Puppet::Node::Environment.new("testing")
232
- env.expects(:modulepath).at_least_once.returns %w{/a}
253
+ env.modulepath = %w{/a}
233
254
  Dir.expects(:entries).once.with("/a").returns %w{foo}
234
255
 
235
256
  env.modules
@@ -244,20 +265,18 @@ describe Puppet::Node::Environment do
244
265
  @helper.extend(Puppet::Node::Environment::Helper)
245
266
  end
246
267
 
247
- it "should be able to set and retrieve the environment" do
268
+ it "should be able to set and retrieve the environment as a symbol" do
248
269
  @helper.environment = :foo
249
270
  @helper.environment.name.should == :foo
250
271
  end
251
272
 
252
273
  it "should accept an environment directly" do
253
- env = Puppet::Node::Environment.new :foo
254
- @helper.environment = env
274
+ @helper.environment = Puppet::Node::Environment.new(:foo)
255
275
  @helper.environment.name.should == :foo
256
276
  end
257
277
 
258
278
  it "should accept an environment as a string" do
259
- env = Puppet::Node::Environment.new "foo"
260
- @helper.environment = env
279
+ @helper.environment = 'foo'
261
280
  @helper.environment.name.should == :foo
262
281
  end
263
282
  end
@@ -266,14 +285,13 @@ describe Puppet::Node::Environment do
266
285
  before do
267
286
  @parser = Puppet::Parser::Parser.new("test")
268
287
  Puppet::Parser::Parser.stubs(:new).returns @parser
269
- @env = Puppet::Node::Environment.new("env")
270
288
  end
271
289
 
272
290
  it "should set the parser's string to the 'code' setting and parse if code is available" do
273
291
  Puppet.settings[:code] = "my code"
274
292
  @parser.expects(:string=).with "my code"
275
293
  @parser.expects(:parse)
276
- @env.instance_eval { perform_initial_import }
294
+ env.instance_eval { perform_initial_import }
277
295
  end
278
296
 
279
297
  it "should set the parser's file to the 'manifest' setting and parse if no code is available and the manifest is available" do
@@ -282,7 +300,7 @@ describe Puppet::Node::Environment do
282
300
  Puppet.settings[:manifest] = filename
283
301
  @parser.expects(:file=).with filename
284
302
  @parser.expects(:parse)
285
- @env.instance_eval { perform_initial_import }
303
+ env.instance_eval { perform_initial_import }
286
304
  end
287
305
 
288
306
  it "should pass the manifest file to the parser even if it does not exist on disk" do
@@ -291,15 +309,15 @@ describe Puppet::Node::Environment do
291
309
  Puppet.settings[:manifest] = filename
292
310
  @parser.expects(:file=).with(filename).once
293
311
  @parser.expects(:parse).once
294
- @env.instance_eval { perform_initial_import }
312
+ env.instance_eval { perform_initial_import }
295
313
  end
296
314
 
297
315
  it "should fail helpfully if there is an error importing" do
298
316
  File.stubs(:exist?).returns true
299
- @env.stubs(:known_resource_types).returns Puppet::Resource::TypeCollection.new(@env)
317
+ env.stubs(:known_resource_types).returns Puppet::Resource::TypeCollection.new(env)
300
318
  @parser.expects(:file=).once
301
319
  @parser.expects(:parse).raises ArgumentError
302
- lambda { @env.instance_eval { perform_initial_import } }.should raise_error(Puppet::Error)
320
+ lambda { env.instance_eval { perform_initial_import } }.should raise_error(Puppet::Error)
303
321
  end
304
322
 
305
323
  it "should not do anything if the ignore_import settings is set" do
@@ -307,15 +325,15 @@ describe Puppet::Node::Environment do
307
325
  @parser.expects(:string=).never
308
326
  @parser.expects(:file=).never
309
327
  @parser.expects(:parse).never
310
- @env.instance_eval { perform_initial_import }
328
+ env.instance_eval { perform_initial_import }
311
329
  end
312
330
 
313
331
  it "should mark the type collection as needing a reparse when there is an error parsing" do
314
332
  @parser.expects(:parse).raises Puppet::ParseError.new("Syntax error at ...")
315
- @env.stubs(:known_resource_types).returns Puppet::Resource::TypeCollection.new(@env)
333
+ env.stubs(:known_resource_types).returns Puppet::Resource::TypeCollection.new(env)
316
334
 
317
- lambda { @env.instance_eval { perform_initial_import } }.should raise_error(Puppet::Error, /Syntax error at .../)
318
- @env.known_resource_types.require_reparse?.should be_true
335
+ lambda { env.instance_eval { perform_initial_import } }.should raise_error(Puppet::Error, /Syntax error at .../)
336
+ env.known_resource_types.require_reparse?.should be_true
319
337
  end
320
338
  end
321
339
  end
@@ -91,7 +91,6 @@ describe Puppet::Parser::AST::ASTHash do
91
91
 
92
92
  it "should return a valid string with to_s" do
93
93
  hash = Puppet::Parser::AST::ASTHash.new(:value => { "a" => "b", "c" => "d" })
94
-
95
- hash.to_s.should == '{a => b, c => d}'
94
+ ["{a => b, c => d}", "{c => d, a => b}"].should be_include hash.to_s
96
95
  end
97
96
  end
@@ -151,6 +151,14 @@ describe Puppet::Parser::AST::HashOrArrayAccess do
151
151
  lambda { access.evaluate(@scope) }.should raise_error
152
152
  end
153
153
 
154
+ it "should be able to return :undef for an unknown array index" do
155
+ @scope.stubs(:lookupvar).with { |name,options| name == 'a'}.returns(["val1", "val2", "val3"])
156
+
157
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => 6 )
158
+
159
+ access.evaluate(@scope).should == :undef
160
+ end
161
+
154
162
  it "should be able to return an hash value" do
155
163
  @scope.stubs(:lookupvar).with { |name,options| name == 'a'}.returns({ "key1" => "val1", "key2" => "val2", "key3" => "val3" })
156
164
 
@@ -159,6 +167,14 @@ describe Puppet::Parser::AST::HashOrArrayAccess do
159
167
  access.evaluate(@scope).should == "val2"
160
168
  end
161
169
 
170
+ it "should be able to return :undef for unknown hash keys" do
171
+ @scope.stubs(:lookupvar).with { |name,options| name == 'a'}.returns({ "key1" => "val1", "key2" => "val2", "key3" => "val3" })
172
+
173
+ access = Puppet::Parser::AST::HashOrArrayAccess.new(:variable => "a", :key => "key12" )
174
+
175
+ access.evaluate(@scope).should == :undef
176
+ end
177
+
162
178
  it "should be able to return an hash value with a numerical key" do
163
179
  @scope.stubs(:lookupvar).with { |name,options| name == "a"}.returns({ "key1" => "val1", "key2" => "val2", "45" => "45", "key3" => "val3" })
164
180
 
@@ -35,8 +35,11 @@ describe klass do
35
35
  @property.should_to_s({:foo => "baz", :bar => "boo"}) == "foo=baz;bar=boo"
36
36
  end
37
37
 
38
- it "should return the passed in array values joined with the delimiter from is_to_s" do
39
- @property.is_to_s({"foo" => "baz" , "bar" => "boo"}).should == "foo=baz;bar=boo"
38
+ it "should return the passed in hash values joined with the delimiter from is_to_s" do
39
+ s = @property.is_to_s({"foo" => "baz" , "bar" => "boo"})
40
+
41
+ # We can't predict the order the hash is processed in...
42
+ ["foo=baz;bar=boo", "bar=boo;foo=baz"].should be_include s
40
43
  end
41
44
 
42
45
  describe "when calling inclusive?" do
@@ -3,161 +3,152 @@ require 'spec_helper'
3
3
  require 'puppet/property'
4
4
 
5
5
  describe Puppet::Property do
6
- before do
7
- @class = Class.new(Puppet::Property) do
8
- @name = :foo
9
- end
10
- @class.initvars
11
- @provider = mock 'provider'
12
- @resource = stub 'resource', :provider => @provider
13
- @resource.stub_everything
14
- @property = @class.new :resource => @resource
6
+ let :resource do Puppet::Type.type(:host).new :name => "foo" end
7
+
8
+ let :subclass do
9
+ # We need a completely fresh subclass every time, because we modify both
10
+ # class and instance level things inside the tests.
11
+ subclass = Class.new(Puppet::Property) do @name = :foo end
12
+ subclass.initvars
13
+ subclass
15
14
  end
16
15
 
17
- it "should return its name as a string when converted to a string" do
18
- @property.to_s.should == @property.name.to_s
19
- end
16
+ let :property do subclass.new :resource => resource end
20
17
 
21
18
  it "should be able to look up the modified name for a given value" do
22
- @class.newvalue(:foo)
23
- @class.value_name("foo").should == :foo
19
+ subclass.newvalue(:foo)
20
+ subclass.value_name("foo").should == :foo
24
21
  end
25
22
 
26
23
  it "should be able to look up the modified name for a given value matching a regex" do
27
- @class.newvalue(%r{.})
28
- @class.value_name("foo").should == %r{.}
24
+ subclass.newvalue(%r{.})
25
+ subclass.value_name("foo").should == %r{.}
29
26
  end
30
27
 
31
28
  it "should be able to look up a given value option" do
32
- @class.newvalue(:foo, :event => :whatever)
33
- @class.value_option(:foo, :event).should == :whatever
29
+ subclass.newvalue(:foo, :event => :whatever)
30
+ subclass.value_option(:foo, :event).should == :whatever
34
31
  end
35
32
 
36
33
  it "should be able to specify required features" do
37
- @class.should respond_to(:required_features=)
34
+ subclass.should respond_to(:required_features=)
38
35
  end
39
36
 
40
37
  {"one" => [:one],:one => [:one],%w{a} => [:a],[:b] => [:b],%w{one two} => [:one,:two],[:a,:b] => [:a,:b]}.each { |in_value,out_value|
41
38
  it "should always convert required features into an array of symbols (e.g. #{in_value.inspect} --> #{out_value.inspect})" do
42
- @class.required_features = in_value
43
- @class.required_features.should == out_value
39
+ subclass.required_features = in_value
40
+ subclass.required_features.should == out_value
44
41
  end
45
42
  }
46
43
 
44
+ it "should return its name as a string when converted to a string" do
45
+ property.to_s.should == property.name.to_s
46
+ end
47
+
47
48
  it "should be able to shadow metaparameters" do
48
- @property.must respond_to(:shadow)
49
+ property.must respond_to(:shadow)
49
50
  end
50
51
 
51
52
  describe "when returning the default event name" do
52
- before do
53
- @resource = stub 'resource'
54
- @instance = @class.new(:resource => @resource)
55
- @instance.stubs(:should).returns "myval"
56
- end
57
-
58
53
  it "should use the current 'should' value to pick the event name" do
59
- @instance.expects(:should).returns "myvalue"
60
- @class.expects(:value_option).with('myvalue', :event).returns :event_name
54
+ property.expects(:should).returns "myvalue"
55
+ subclass.expects(:value_option).with('myvalue', :event).returns :event_name
61
56
 
62
- @instance.event_name
57
+ property.event_name
63
58
  end
64
59
 
65
60
  it "should return any event defined with the specified value" do
66
- @instance.expects(:should).returns :myval
67
- @class.expects(:value_option).with(:myval, :event).returns :event_name
61
+ property.expects(:should).returns :myval
62
+ subclass.expects(:value_option).with(:myval, :event).returns :event_name
68
63
 
69
- @instance.event_name.should == :event_name
64
+ property.event_name.should == :event_name
70
65
  end
71
66
 
72
67
  describe "and the property is 'ensure'" do
73
- before do
74
- @instance.stubs(:name).returns :ensure
75
- @resource.expects(:type).returns :mytype
68
+ before :each do
69
+ property.stubs(:name).returns :ensure
70
+ resource.expects(:type).returns :mytype
76
71
  end
77
72
 
78
73
  it "should use <type>_created if the 'should' value is 'present'" do
79
- @instance.expects(:should).returns :present
80
- @instance.event_name.should == :mytype_created
74
+ property.expects(:should).returns :present
75
+ property.event_name.should == :mytype_created
81
76
  end
82
77
 
83
78
  it "should use <type>_removed if the 'should' value is 'absent'" do
84
- @instance.expects(:should).returns :absent
85
- @instance.event_name.should == :mytype_removed
79
+ property.expects(:should).returns :absent
80
+ property.event_name.should == :mytype_removed
86
81
  end
87
82
 
88
83
  it "should use <type>_changed if the 'should' value is not 'absent' or 'present'" do
89
- @instance.expects(:should).returns :foo
90
- @instance.event_name.should == :mytype_changed
84
+ property.expects(:should).returns :foo
85
+ property.event_name.should == :mytype_changed
91
86
  end
92
87
 
93
88
  it "should use <type>_changed if the 'should value is nil" do
94
- @instance.expects(:should).returns nil
95
- @instance.event_name.should == :mytype_changed
89
+ property.expects(:should).returns nil
90
+ property.event_name.should == :mytype_changed
96
91
  end
97
92
  end
98
93
 
99
94
  it "should use <property>_changed if the property is not 'ensure'" do
100
- @instance.stubs(:name).returns :myparam
101
- @instance.expects(:should).returns :foo
102
- @instance.event_name.should == :myparam_changed
95
+ property.stubs(:name).returns :myparam
96
+ property.expects(:should).returns :foo
97
+ property.event_name.should == :myparam_changed
103
98
  end
104
99
 
105
100
  it "should use <property>_changed if no 'should' value is set" do
106
- @instance.stubs(:name).returns :myparam
107
- @instance.expects(:should).returns nil
108
- @instance.event_name.should == :myparam_changed
101
+ property.stubs(:name).returns :myparam
102
+ property.expects(:should).returns nil
103
+ property.event_name.should == :myparam_changed
109
104
  end
110
105
  end
111
106
 
112
107
  describe "when creating an event" do
113
- before do
114
- @event = Puppet::Transaction::Event.new
115
-
116
- # Use a real resource so we can test the event creation integration
117
- @resource = Puppet::Type.type(:host).new :name => "foo"
118
- @instance = @class.new(:resource => @resource)
119
- @instance.stubs(:should).returns "myval"
108
+ before :each do
109
+ property.stubs(:should).returns "myval"
120
110
  end
121
111
 
122
112
  it "should use an event from the resource as the base event" do
123
113
  event = Puppet::Transaction::Event.new
124
- @resource.expects(:event).returns event
114
+ resource.expects(:event).returns event
125
115
 
126
- @instance.event.should equal(event)
116
+ property.event.should equal(event)
127
117
  end
128
118
 
129
119
  it "should have the default event name" do
130
- @instance.expects(:event_name).returns :my_event
131
- @instance.event.name.should == :my_event
120
+ property.expects(:event_name).returns :my_event
121
+ property.event.name.should == :my_event
132
122
  end
133
123
 
134
124
  it "should have the property's name" do
135
- @instance.event.property.should == @instance.name.to_s
125
+ property.event.property.should == property.name.to_s
136
126
  end
137
127
 
138
128
  it "should have the 'should' value set" do
139
- @instance.stubs(:should).returns "foo"
140
- @instance.event.desired_value.should == "foo"
129
+ property.stubs(:should).returns "foo"
130
+ property.event.desired_value.should == "foo"
141
131
  end
142
132
 
143
133
  it "should provide its path as the source description" do
144
- @instance.stubs(:path).returns "/my/param"
145
- @instance.event.source_description.should == "/my/param"
134
+ property.stubs(:path).returns "/my/param"
135
+ property.event.source_description.should == "/my/param"
146
136
  end
147
137
  end
148
138
 
149
139
  describe "when shadowing metaparameters" do
150
- before do
151
- @shadow_class = Class.new(Puppet::Property) do
140
+ let :shadow_class do
141
+ shadow_class = Class.new(Puppet::Property) do
152
142
  @name = :alias
153
143
  end
154
- @shadow_class.initvars
144
+ shadow_class.initvars
145
+ shadow_class
155
146
  end
156
147
 
157
148
  it "should create an instance of the metaparameter at initialization" do
158
- Puppet::Type.metaparamclass(:alias).expects(:new).with(:resource => @resource)
149
+ Puppet::Type.metaparamclass(:alias).expects(:new).with(:resource => resource)
159
150
 
160
- @shadow_class.new :resource => @resource
151
+ shadow_class.new :resource => resource
161
152
  end
162
153
 
163
154
  it "should munge values using the shadow's munge method" do
@@ -166,244 +157,354 @@ describe Puppet::Property do
166
157
 
167
158
  shadow.expects(:munge).with "foo"
168
159
 
169
- property = @shadow_class.new :resource => @resource
160
+ property = shadow_class.new :resource => resource
170
161
  property.munge("foo")
171
162
  end
172
163
  end
173
164
 
174
165
  describe "when defining new values" do
175
166
  it "should define a method for each value created with a block that's not a regex" do
176
- @class.newvalue(:foo) { }
177
- @property.must respond_to(:set_foo)
167
+ subclass.newvalue(:foo) { }
168
+ property.must respond_to(:set_foo)
178
169
  end
179
170
  end
180
171
 
181
172
  describe "when assigning the value" do
182
173
  it "should just set the 'should' value" do
183
- @property.value = "foo"
184
- @property.should.must == "foo"
174
+ property.value = "foo"
175
+ property.should.must == "foo"
185
176
  end
186
177
 
187
178
  it "should validate each value separately" do
188
- @property.expects(:validate).with("one")
189
- @property.expects(:validate).with("two")
179
+ property.expects(:validate).with("one")
180
+ property.expects(:validate).with("two")
190
181
 
191
- @property.value = %w{one two}
182
+ property.value = %w{one two}
192
183
  end
193
184
 
194
185
  it "should munge each value separately and use any result as the actual value" do
195
- @property.expects(:munge).with("one").returns :one
196
- @property.expects(:munge).with("two").returns :two
186
+ property.expects(:munge).with("one").returns :one
187
+ property.expects(:munge).with("two").returns :two
197
188
 
198
189
  # Do this so we get the whole array back.
199
- @class.array_matching = :all
190
+ subclass.array_matching = :all
200
191
 
201
- @property.value = %w{one two}
202
- @property.should.must == [:one, :two]
192
+ property.value = %w{one two}
193
+ property.should.must == [:one, :two]
203
194
  end
204
195
 
205
196
  it "should return any set value" do
206
- (@property.value = :one).should == :one
197
+ (property.value = :one).should == :one
207
198
  end
208
199
  end
209
200
 
210
201
  describe "when returning the value" do
211
202
  it "should return nil if no value is set" do
212
- @property.should.must be_nil
203
+ property.should.must be_nil
213
204
  end
214
205
 
215
206
  it "should return the first set 'should' value if :array_matching is set to :first" do
216
- @class.array_matching = :first
217
- @property.should = %w{one two}
218
- @property.should.must == "one"
207
+ subclass.array_matching = :first
208
+ property.should = %w{one two}
209
+ property.should.must == "one"
219
210
  end
220
211
 
221
212
  it "should return all set 'should' values as an array if :array_matching is set to :all" do
222
- @class.array_matching = :all
223
- @property.should = %w{one two}
224
- @property.should.must == %w{one two}
213
+ subclass.array_matching = :all
214
+ property.should = %w{one two}
215
+ property.should.must == %w{one two}
225
216
  end
226
217
 
227
218
  it "should default to :first array_matching" do
228
- @class.array_matching.should == :first
219
+ subclass.array_matching.should == :first
229
220
  end
230
221
 
231
222
  it "should unmunge the returned value if :array_matching is set to :first" do
232
- @property.class.unmunge do |v| v.to_sym end
233
- @class.array_matching = :first
234
- @property.should = %w{one two}
223
+ property.class.unmunge do |v| v.to_sym end
224
+ subclass.array_matching = :first
225
+ property.should = %w{one two}
235
226
 
236
- @property.should.must == :one
227
+ property.should.must == :one
237
228
  end
238
229
 
239
230
  it "should unmunge all the returned values if :array_matching is set to :all" do
240
- @property.class.unmunge do |v| v.to_sym end
241
- @class.array_matching = :all
242
- @property.should = %w{one two}
231
+ property.class.unmunge do |v| v.to_sym end
232
+ subclass.array_matching = :all
233
+ property.should = %w{one two}
243
234
 
244
- @property.should.must == [:one, :two]
235
+ property.should.must == [:one, :two]
245
236
  end
246
237
  end
247
238
 
248
239
  describe "when validating values" do
249
240
  it "should do nothing if no values or regexes have been defined" do
250
- lambda { @property.should = "foo" }.should_not raise_error
241
+ lambda { property.should = "foo" }.should_not raise_error
251
242
  end
252
243
 
253
244
  it "should fail if the value is not a defined value or alias and does not match a regex" do
254
- @class.newvalue(:foo)
245
+ subclass.newvalue(:foo)
255
246
 
256
- lambda { @property.should = "bar" }.should raise_error
247
+ lambda { property.should = "bar" }.should raise_error
257
248
  end
258
249
 
259
250
  it "should succeeed if the value is one of the defined values" do
260
- @class.newvalue(:foo)
251
+ subclass.newvalue(:foo)
261
252
 
262
- lambda { @property.should = :foo }.should_not raise_error
253
+ lambda { property.should = :foo }.should_not raise_error
263
254
  end
264
255
 
265
256
  it "should succeeed if the value is one of the defined values even if the definition uses a symbol and the validation uses a string" do
266
- @class.newvalue(:foo)
257
+ subclass.newvalue(:foo)
267
258
 
268
- lambda { @property.should = "foo" }.should_not raise_error
259
+ lambda { property.should = "foo" }.should_not raise_error
269
260
  end
270
261
 
271
262
  it "should succeeed if the value is one of the defined values even if the definition uses a string and the validation uses a symbol" do
272
- @class.newvalue("foo")
263
+ subclass.newvalue("foo")
273
264
 
274
- lambda { @property.should = :foo }.should_not raise_error
265
+ lambda { property.should = :foo }.should_not raise_error
275
266
  end
276
267
 
277
268
  it "should succeed if the value is one of the defined aliases" do
278
- @class.newvalue("foo")
279
- @class.aliasvalue("bar", "foo")
269
+ subclass.newvalue("foo")
270
+ subclass.aliasvalue("bar", "foo")
280
271
 
281
- lambda { @property.should = :bar }.should_not raise_error
272
+ lambda { property.should = :bar }.should_not raise_error
282
273
  end
283
274
 
284
275
  it "should succeed if the value matches one of the regexes" do
285
- @class.newvalue(/./)
276
+ subclass.newvalue(/./)
286
277
 
287
- lambda { @property.should = "bar" }.should_not raise_error
278
+ lambda { property.should = "bar" }.should_not raise_error
288
279
  end
289
280
 
290
281
  it "should validate that all required features are present" do
291
- @class.newvalue(:foo, :required_features => [:a, :b])
282
+ subclass.newvalue(:foo, :required_features => [:a, :b])
292
283
 
293
- @provider.expects(:satisfies?).with([:a, :b]).returns true
284
+ resource.provider.expects(:satisfies?).with([:a, :b]).returns true
294
285
 
295
- @property.should = :foo
286
+ property.should = :foo
296
287
  end
297
288
 
298
289
  it "should fail if required features are missing" do
299
- @class.newvalue(:foo, :required_features => [:a, :b])
290
+ subclass.newvalue(:foo, :required_features => [:a, :b])
300
291
 
301
- @provider.expects(:satisfies?).with([:a, :b]).returns false
292
+ resource.provider.expects(:satisfies?).with([:a, :b]).returns false
302
293
 
303
- lambda { @property.should = :foo }.should raise_error(Puppet::Error)
294
+ lambda { property.should = :foo }.should raise_error(Puppet::Error)
304
295
  end
305
296
 
306
297
  it "should internally raise an ArgumentError if required features are missing" do
307
- @class.newvalue(:foo, :required_features => [:a, :b])
298
+ subclass.newvalue(:foo, :required_features => [:a, :b])
308
299
 
309
- @provider.expects(:satisfies?).with([:a, :b]).returns false
300
+ resource.provider.expects(:satisfies?).with([:a, :b]).returns false
310
301
 
311
- lambda { @property.validate_features_per_value :foo }.should raise_error(ArgumentError)
302
+ lambda { property.validate_features_per_value :foo }.should raise_error(ArgumentError)
312
303
  end
313
304
 
314
305
  it "should validate that all required features are present for regexes" do
315
- value = @class.newvalue(/./, :required_features => [:a, :b])
306
+ value = subclass.newvalue(/./, :required_features => [:a, :b])
316
307
 
317
- @provider.expects(:satisfies?).with([:a, :b]).returns true
308
+ resource.provider.expects(:satisfies?).with([:a, :b]).returns true
318
309
 
319
- @property.should = "foo"
310
+ property.should = "foo"
320
311
  end
321
312
 
322
313
  it "should support specifying an individual required feature" do
323
- value = @class.newvalue(/./, :required_features => :a)
314
+ value = subclass.newvalue(/./, :required_features => :a)
324
315
 
325
- @provider.expects(:satisfies?).returns true
316
+ resource.provider.expects(:satisfies?).returns true
326
317
 
327
- @property.should = "foo"
318
+ property.should = "foo"
328
319
  end
329
320
  end
330
321
 
331
322
  describe "when munging values" do
332
323
  it "should do nothing if no values or regexes have been defined" do
333
- @property.munge("foo").should == "foo"
324
+ property.munge("foo").should == "foo"
334
325
  end
335
326
 
336
327
  it "should return return any matching defined values" do
337
- @class.newvalue(:foo)
338
- @property.munge("foo").should == :foo
328
+ subclass.newvalue(:foo)
329
+ property.munge("foo").should == :foo
339
330
  end
340
331
 
341
332
  it "should return any matching aliases" do
342
- @class.newvalue(:foo)
343
- @class.aliasvalue(:bar, :foo)
344
- @property.munge("bar").should == :foo
333
+ subclass.newvalue(:foo)
334
+ subclass.aliasvalue(:bar, :foo)
335
+ property.munge("bar").should == :foo
345
336
  end
346
337
 
347
338
  it "should return the value if it matches a regex" do
348
- @class.newvalue(/./)
349
- @property.munge("bar").should == "bar"
339
+ subclass.newvalue(/./)
340
+ property.munge("bar").should == "bar"
350
341
  end
351
342
 
352
343
  it "should return the value if no other option is matched" do
353
- @class.newvalue(:foo)
354
- @property.munge("bar").should == "bar"
344
+ subclass.newvalue(:foo)
345
+ property.munge("bar").should == "bar"
355
346
  end
356
347
  end
357
348
 
358
349
  describe "when syncing the 'should' value" do
359
350
  it "should set the value" do
360
- @class.newvalue(:foo)
361
- @property.should = :foo
362
- @property.expects(:set).with(:foo)
363
- @property.sync
351
+ subclass.newvalue(:foo)
352
+ property.should = :foo
353
+ property.expects(:set).with(:foo)
354
+ property.sync
364
355
  end
365
356
  end
366
357
 
367
358
  describe "when setting a value" do
368
359
  it "should catch exceptions and raise Puppet::Error" do
369
- @class.newvalue(:foo) { raise "eh" }
370
- lambda { @property.set(:foo) }.should raise_error(Puppet::Error)
360
+ subclass.newvalue(:foo) { raise "eh" }
361
+ lambda { property.set(:foo) }.should raise_error(Puppet::Error)
371
362
  end
372
363
 
373
364
  describe "that was defined without a block" do
374
365
  it "should call the settor on the provider" do
375
- @class.newvalue(:bar)
376
- @provider.expects(:foo=).with :bar
377
- @property.set(:bar)
366
+ subclass.newvalue(:bar)
367
+ resource.provider.expects(:foo=).with :bar
368
+ property.set(:bar)
378
369
  end
379
370
  end
380
371
 
381
372
  describe "that was defined with a block" do
382
373
  it "should call the method created for the value if the value is not a regex" do
383
- @class.newvalue(:bar) {}
384
- @property.expects(:set_bar)
385
- @property.set(:bar)
374
+ subclass.newvalue(:bar) {}
375
+ property.expects(:set_bar)
376
+ property.set(:bar)
386
377
  end
387
378
 
388
379
  it "should call the provided block if the value is a regex" do
389
- @class.newvalue(/./) { self.test }
390
- @property.expects(:test)
391
- @property.set("foo")
380
+ subclass.newvalue(/./) { self.test }
381
+ property.expects(:test)
382
+ property.set("foo")
392
383
  end
393
384
  end
394
385
  end
395
386
 
396
387
  describe "when producing a change log" do
397
388
  it "should say 'defined' when the current value is 'absent'" do
398
- @property.change_to_s(:absent, "foo").should =~ /^defined/
389
+ property.change_to_s(:absent, "foo").should =~ /^defined/
399
390
  end
400
391
 
401
392
  it "should say 'undefined' when the new value is 'absent'" do
402
- @property.change_to_s("foo", :absent).should =~ /^undefined/
393
+ property.change_to_s("foo", :absent).should =~ /^undefined/
403
394
  end
404
395
 
405
396
  it "should say 'changed' when neither value is 'absent'" do
406
- @property.change_to_s("foo", "bar").should =~ /changed/
397
+ property.change_to_s("foo", "bar").should =~ /changed/
398
+ end
399
+ end
400
+
401
+ shared_examples_for "#insync?" do
402
+ # We share a lot of behaviour between the all and first matching, so we
403
+ # use a shared behaviour set to emulate that. The outside world makes
404
+ # sure the class, etc, point to the right content.
405
+ [[], [12], [12, 13]].each do |input|
406
+ it "should return true if should is empty with is => #{input.inspect}" do
407
+ property.should = []
408
+ property.must be_insync(input)
409
+ end
410
+ end
411
+ end
412
+
413
+ describe "#insync?" do
414
+ context "array_matching :all" do
415
+ # `@should` is an array of scalar values, and `is` is an array of scalar values.
416
+ before :each do
417
+ property.class.array_matching = :all
418
+ end
419
+
420
+ it_should_behave_like "#insync?"
421
+
422
+ context "if the should value is an array" do
423
+ before :each do property.should = [1, 2] end
424
+
425
+ it "should match if is exactly matches" do
426
+ property.must be_insync [1, 2]
427
+ end
428
+
429
+ it "should match if it matches, but all stringified" do
430
+ property.must be_insync ["1", "2"]
431
+ end
432
+
433
+ it "should not match if some-but-not-all values are stringified" do
434
+ property.must_not be_insync ["1", 2]
435
+ property.must_not be_insync [1, "2"]
436
+ end
437
+
438
+ it "should not match if order is different but content the same" do
439
+ property.must_not be_insync [2, 1]
440
+ end
441
+
442
+ it "should not match if there are more items in should than is" do
443
+ property.must_not be_insync [1]
444
+ end
445
+
446
+ it "should not match if there are less items in should than is" do
447
+ property.must_not be_insync [1, 2, 3]
448
+ end
449
+
450
+ it "should not match if `is` is empty but `should` isn't" do
451
+ property.must_not be_insync []
452
+ end
453
+ end
454
+ end
455
+
456
+ context "array_matching :first" do
457
+ # `@should` is an array of scalar values, and `is` is a scalar value.
458
+ before :each do
459
+ property.class.array_matching = :first
460
+ end
461
+
462
+ it_should_behave_like "#insync?"
463
+
464
+ [[1], # only the value
465
+ [1, 2], # matching value first
466
+ [2, 1], # matching value last
467
+ [0, 1, 2], # matching value in the middle
468
+ ].each do |input|
469
+ it "should by true if one unmodified should value of #{input.inspect} matches what is" do
470
+ property.should = input
471
+ property.must be_insync 1
472
+ end
473
+
474
+ it "should be true if one stringified should value of #{input.inspect} matches what is" do
475
+ property.should = input
476
+ property.must be_insync "1"
477
+ end
478
+ end
479
+
480
+ it "should not match if we expect a string but get the non-stringified value" do
481
+ property.should = ["1"]
482
+ property.must_not be_insync 1
483
+ end
484
+
485
+ [[0], [0, 2]].each do |input|
486
+ it "should not match if no should values match what is" do
487
+ property.should = input
488
+ property.must_not be_insync 1
489
+ property.must_not be_insync "1" # shouldn't match either.
490
+ end
491
+ end
492
+ end
493
+ end
494
+
495
+ describe "#property_matches?" do
496
+ [1, "1", [1], :one].each do |input|
497
+ it "should treat two equal objects as equal (#{input.inspect})" do
498
+ property.property_matches?(input, input).should be_true
499
+ end
500
+ end
501
+
502
+ it "should treat two objects as equal if the first argument is the stringified version of the second" do
503
+ property.property_matches?("1", 1).should be_true
504
+ end
505
+
506
+ it "should NOT treat two objects as equal if the first argument is not a string, and the second argument is a string, even if it stringifies to the first" do
507
+ property.property_matches?(1, "1").should be_false
407
508
  end
408
509
  end
409
510
  end