puppet 0.23.1 → 0.23.2

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 (55) hide show
  1. data/CHANGELOG +31 -0
  2. data/bin/puppetd +2 -1
  3. data/conf/redhat/puppet.spec +9 -6
  4. data/conf/redhat/server.init +4 -5
  5. data/examples/code/mac_dscl.pp +28 -0
  6. data/examples/code/mac_dscl_revert.pp +26 -0
  7. data/examples/code/mac_netinfo.pp +5 -0
  8. data/examples/code/mac_pkgdmg.pp +7 -0
  9. data/ext/puppet-test +69 -2
  10. data/lib/puppet.rb +2 -2
  11. data/lib/puppet/configuration.rb +5 -1
  12. data/lib/puppet/network/server/mongrel.rb +3 -3
  13. data/lib/puppet/parser/ast.rb +2 -2
  14. data/lib/puppet/parser/ast/component.rb +3 -3
  15. data/lib/puppet/parser/ast/node.rb +2 -2
  16. data/lib/puppet/parser/collector.rb +2 -2
  17. data/lib/puppet/parser/interpreter.rb +38 -215
  18. data/lib/puppet/parser/parser.rb +11 -228
  19. data/lib/puppet/parser/parser_support.rb +447 -0
  20. data/lib/puppet/parser/resource/param.rb +2 -2
  21. data/lib/puppet/provider.rb +5 -3
  22. data/lib/puppet/provider/cron/crontab.rb +22 -9
  23. data/lib/puppet/provider/group/directoryservice.rb +23 -0
  24. data/lib/puppet/provider/interface/redhat.rb +251 -0
  25. data/lib/puppet/provider/interface/sunos.rb +116 -0
  26. data/lib/puppet/provider/mount.rb +4 -1
  27. data/lib/puppet/provider/nameservice/directoryservice.rb +341 -0
  28. data/lib/puppet/provider/package/dpkg.rb +2 -2
  29. data/lib/puppet/provider/package/openbsd.rb +2 -2
  30. data/lib/puppet/provider/package/rpm.rb +2 -4
  31. data/lib/puppet/provider/package/sun.rb +2 -2
  32. data/lib/puppet/provider/parsedfile.rb +32 -29
  33. data/lib/puppet/provider/user/directoryservice.rb +116 -0
  34. data/lib/puppet/rails/host.rb +1 -1
  35. data/lib/puppet/reference/configuration.rb +7 -4
  36. data/lib/puppet/type/interface.rb +57 -0
  37. data/lib/puppet/type/pfile/group.rb +2 -2
  38. data/lib/puppet/util/config.rb +10 -3
  39. data/lib/puppet/util/fileparsing.rb +2 -2
  40. data/test/language/ast/hostclass.rb +1 -17
  41. data/test/language/interpreter.rb +18 -388
  42. data/test/language/node.rb +8 -8
  43. data/test/language/parser.rb +444 -45
  44. data/test/lib/puppettest/parsertesting.rb +2 -2
  45. data/test/lib/puppettest/support/collection.rb +2 -2
  46. data/test/network/server/mongrel_test.rb +24 -3
  47. data/test/rails/collection.rb +34 -1
  48. data/test/ral/providers/cron/crontab.rb +198 -40
  49. data/test/ral/providers/mount/parsed.rb +69 -46
  50. data/test/ral/providers/parsedfile.rb +20 -28
  51. data/test/ral/types/cron.rb +20 -24
  52. data/test/ral/types/interface.rb +40 -0
  53. data/test/ral/types/package.rb +6 -2
  54. data/test/util/config.rb +106 -30
  55. metadata +14 -2
@@ -0,0 +1,116 @@
1
+ # Created by Jeff McCune on 2007-07-22
2
+ # Copyright (c) 2007. All rights reserved.
3
+ #
4
+ # This program is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU General Public License
6
+ # as published by the Free Software Foundation (version 2 of the License)
7
+ # This program is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ # GNU General Public License for more details.
11
+ # You should have received a copy of the GNU General Public License
12
+ # along with this program; if not, write to the Free Software
13
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
14
+
15
+ require 'puppet/provider/nameservice/directoryservice'
16
+
17
+ Puppet::Type.type(:user).provide :directoryservice, :parent => Puppet::Provider::NameService::DirectoryService do
18
+ desc "User management using DirectoryService on OS X."
19
+
20
+ commands :dscl => "/usr/bin/dscl"
21
+ confine :operatingsystem => :darwin
22
+
23
+ # JJM: DirectoryService can manage passwords.
24
+ # This needs to be a special option to dscl though (-passwd)
25
+ has_feature :manages_passwords
26
+
27
+ # JJM: comment matches up with the /etc/passwd concept of an user
28
+ options :comment, :key => "realname"
29
+ options :password, :key => "passwd"
30
+
31
+ autogen_defaults :home => "/var/empty", :shell => "/usr/bin/false"
32
+
33
+ verify :gid, "GID must be an integer" do |value|
34
+ value.is_a? Integer
35
+ end
36
+
37
+ verify :uid, "UID must be an integer" do |value|
38
+ value.is_a? Integer
39
+ end
40
+
41
+ def autogen_comment
42
+ return @resource[:name].capitalize
43
+ end
44
+
45
+ # The list of all groups the user is a member of. Different
46
+ # user mgmt systems will need to override this method.
47
+ # JJM: FIXME: Override this method...
48
+ def groups
49
+ groups = []
50
+
51
+ # user = @resource[:name]
52
+ # # Retrieve them all from netinfo
53
+ # open("| #{command(:nireport)} / /groups name users") do |file|
54
+ # file.each do |line|
55
+ # name, members = line.split(/\s+/)
56
+ # next unless members
57
+ # next if members =~ /NoValue/
58
+ # members = members.split(",")
59
+ #
60
+ # if members.include? user
61
+ # groups << name
62
+ # end
63
+ # end
64
+ # end
65
+
66
+ groups.join(",")
67
+ end
68
+
69
+ # This is really lame. We have to iterate over each
70
+ # of the groups and add us to them.
71
+ def groups=(groups)
72
+ # case groups
73
+ # when Fixnum:
74
+ # groups = [groups.to_s]
75
+ # when String
76
+ # groups = groups.split(/\s*,\s*/)
77
+ # else
78
+ # raise Puppet::DevError, "got invalid groups value %s of type %s" % [groups.class, groups]
79
+ # end
80
+ # # Get just the groups we need to modify
81
+ # diff = groups - (@is || [])
82
+ #
83
+ # data = {}
84
+ # open("| #{command(:nireport)} / /groups name users") do |file|
85
+ # file.each do |line|
86
+ # name, members = line.split(/\s+/)
87
+ #
88
+ # if members.nil? or members =~ /NoValue/
89
+ # data[name] = []
90
+ # else
91
+ # # Add each diff group's current members
92
+ # data[name] = members.split(/,/)
93
+ # end
94
+ # end
95
+ # end
96
+ #
97
+ # user = @resource[:name]
98
+ # data.each do |name, members|
99
+ # if members.include? user and groups.include? name
100
+ # # I'm in the group and should be
101
+ # next
102
+ # elsif members.include? user
103
+ # # I'm in the group and shouldn't be
104
+ # setuserlist(name, members - [user])
105
+ # elsif groups.include? name
106
+ # # I'm not in the group and should be
107
+ # setuserlist(name, members + [user])
108
+ # else
109
+ # # I'm not in the group and shouldn't be
110
+ # next
111
+ # end
112
+ # end
113
+ end
114
+
115
+
116
+ end
@@ -158,4 +158,4 @@ class Puppet::Rails::Host < ActiveRecord::Base
158
158
  end
159
159
  end
160
160
 
161
- # $Id: host.rb 2616 2007-06-18 21:03:18Z luke $
161
+ # $Id: host.rb 2735 2007-08-03 19:31:15Z lutter $
@@ -109,11 +109,14 @@ the executable in question with the `--genconfig` command. The executable
109
109
  will print a template configuration to standard output, which can be
110
110
  redirected to a file like so::
111
111
 
112
- $ puppetd --genconfig > /etc/puppet/puppetd.conf
112
+ $ puppetd --genconfig > /etc/puppet/puppet.conf
113
113
 
114
- Note that this invocation will \"clobber\" (throw away) the contents of any
115
- pre-existing `puppetd.conf` file, so make a backup of your present config
116
- if it contains valuable information.
114
+ Note that this invocation will replace the contents of any pre-existing
115
+ `puppet.conf` file, so make a backup of your present config if it contains
116
+ valuable information.
117
+
118
+ All parameters will be under a single section heading matching the name of
119
+ the process used to generate the configuraiton ('puppetd', in this case).
117
120
 
118
121
  Like the `--genconfig` argument, the executables also accept a `--genmanifest`
119
122
  argument, which will generate a manifest that can be used to manage all of
@@ -0,0 +1,57 @@
1
+ Puppet::Type.newtype(:interface) do
2
+ require 'erb'
3
+
4
+ @doc = "Create configuration for IP address aliases and loopback addresses."
5
+
6
+ newparam(:name, :namevar => true) do
7
+ desc "The ipaddress to add to alias or loopback/dummy interface"
8
+ end
9
+
10
+ ensurable
11
+
12
+ newparam(:interface) do
13
+ desc "The interface the IP should be added to"
14
+ end
15
+
16
+ newproperty(:interface_type) do
17
+ desc "The interface type, loopback (also dummy) or alias"
18
+
19
+ newvalue(:loopback)
20
+ newvalue(:alias)
21
+ newvalue(:normal)
22
+
23
+ # Make dummy and loopback equivalent
24
+ aliasvalue(:dummy, :loopback)
25
+
26
+ defaultto :normal
27
+ end
28
+
29
+ newparam(:interface_desc) do
30
+ desc "On Linux, the description / symbolic name you wish to refer to the
31
+ interface by. When absent, Redhat Linux defaults to uses the namevar
32
+ which will be either the IP address, or hostname."
33
+ end
34
+
35
+ newproperty(:onboot) do
36
+ desc "Whether the interface should be configured to come up on boot"
37
+ newvalue(:true)
38
+ newvalue(:false)
39
+ end
40
+
41
+ newproperty(:ifnum) do
42
+ desc "If not automatically configuring the dummy interface or
43
+ and alias. This is use to force a given number to be used"
44
+ end
45
+
46
+ newproperty(:ifopts) do
47
+ desc "Interface options."
48
+ end
49
+
50
+ newparam(:target) do
51
+ desc "The path to the file this resource creates."
52
+
53
+ defaultto { @resource.provider.file_path }
54
+ end
55
+ end
56
+
57
+ # $Id: interface.rb 2747 2007-08-05 19:01:39Z luke $
@@ -36,7 +36,7 @@ module Puppet
36
36
 
37
37
  def should_to_s(newvalue = @should)
38
38
  if newvalue.is_a? Integer
39
- id2name(newvalue) || newalue
39
+ id2name(newvalue) || newvalue
40
40
  else
41
41
  return newvalue.to_s
42
42
  end
@@ -118,4 +118,4 @@ module Puppet
118
118
  end
119
119
  end
120
120
 
121
- # $Id: group.rb 2500 2007-05-09 22:05:32Z luke $
121
+ # $Id: group.rb 2741 2007-08-03 23:14:32Z lutter $
@@ -541,8 +541,11 @@ Generated on #{Time.now}.
541
541
 
542
542
  }.gsub(/^/, "# ")
543
543
 
544
+ # Add a section heading that matches our name.
545
+ if @config.include?(:name)
546
+ str += "[%s]\n" % self[:name]
547
+ end
544
548
  eachsection do |section|
545
- str += "[#{section}]\n"
546
549
  persection(section) do |obj|
547
550
  str += obj.to_config + "\n"
548
551
  end
@@ -836,7 +839,11 @@ Generated on #{Time.now}.
836
839
  Puppet.warning "Discarded unknown configuration parameter %s" % param
837
840
  next
838
841
  end
839
- self[param] = value
842
+ if @config[param].setbycli
843
+ Puppet.debug "Ignoring %s set by config file; overridden by cli" % param
844
+ else
845
+ self[param] = value
846
+ end
840
847
  end
841
848
 
842
849
  if meta = params[:_meta]
@@ -1106,4 +1113,4 @@ Generated on #{Time.now}.
1106
1113
  end
1107
1114
  end
1108
1115
 
1109
- # $Id: config.rb 2464 2007-05-06 05:42:53Z luke $
1116
+ # $Id: config.rb 2743 2007-08-04 00:36:47Z luke $
@@ -320,7 +320,7 @@ module Puppet::Util::FileParsing
320
320
  # Convert our parsed record into a text record.
321
321
  def to_line(details)
322
322
  unless record = record_type(details[:record_type])
323
- raise ArgumentError, "Invalid record type %s" % details[:record_type]
323
+ raise ArgumentError, "Invalid record type %s" % details[:record_type].inspect
324
324
  end
325
325
 
326
326
  if record.respond_to?(:pre_gen)
@@ -394,4 +394,4 @@ module Puppet::Util::FileParsing
394
394
  end
395
395
  end
396
396
 
397
- # $Id: fileparsing.rb 2697 2007-07-14 21:13:04Z luke $
397
+ # $Id: fileparsing.rb 2750 2007-08-06 17:59:37Z luke $
@@ -158,22 +158,6 @@ class TestASTHostClass < Test::Unit::TestCase
158
158
  assert(result, "could not find parent-defined definition from sub")
159
159
  assert(fun == result, "found incorrect parent-defined definition from sub")
160
160
  end
161
-
162
- # Make sure the subscopes we generate get the right type and name
163
- def test_subscope
164
- interp = mkinterp
165
-
166
- klass = interp.newclass("base")
167
- scope = mkscope(:interp => interp)
168
- scope.expects(:newscope).with(:name => "base", :type => "class", :namespace => "base").returns(mkscope(:interp => interp))
169
- klass.subscope(scope)
170
-
171
- # Now make sure it works for namespaces
172
- klass = interp.newclass("sub::type")
173
- scope = mkscope(:interp => interp)
174
- scope.expects(:newscope).with(:name => "sub::type", :type => "class", :namespace => "sub::type").returns(mkscope(:interp => interp))
175
- klass.subscope(scope)
176
- end
177
161
  end
178
162
 
179
- # $Id: hostclass.rb 2715 2007-07-19 19:23:56Z luke $
163
+ # $Id: hostclass.rb 2730 2007-07-31 02:34:07Z luke $
@@ -160,205 +160,6 @@ class TestInterpreter < PuppetTest::TestCase
160
160
  newdate = interp.parsedate
161
161
  assert(date != newdate, "Parsedate was not updated")
162
162
  end
163
-
164
- # Make sure our node gets added to the node table.
165
- def test_newnode
166
- interp = mkinterp
167
-
168
- # First just try calling it directly
169
- assert_nothing_raised {
170
- interp.newnode("mynode", :code => :yay)
171
- }
172
-
173
- assert_equal(:yay, interp.nodesearch_code("mynode").code)
174
-
175
- # Now make sure that trying to redefine it throws an error.
176
- assert_raise(Puppet::ParseError) {
177
- interp.newnode("mynode", {})
178
- }
179
-
180
- # Now try one with no code
181
- assert_nothing_raised {
182
- interp.newnode("simplenode", :parent => :foo)
183
- }
184
-
185
- # Make sure trying to get the parentclass throws an error
186
- assert_raise(Puppet::ParseError) do
187
- interp.nodesearch_code("simplenode").parentobj
188
- end
189
-
190
- # Now define the parent node
191
- interp.newnode(:foo)
192
-
193
- # And make sure we get things back correctly
194
- assert_equal("foo", interp.nodesearch_code("simplenode").parentobj.classname)
195
- assert_nil(interp.nodesearch_code("simplenode").code)
196
-
197
- # Now make sure that trying to redefine it throws an error.
198
- assert_raise(Puppet::ParseError) {
199
- interp.newnode("mynode", {})
200
- }
201
-
202
- # Test multiple names
203
- names = ["one", "two", "three"]
204
- assert_nothing_raised {
205
- interp.newnode(names, {:code => :yay, :parent => :foo})
206
- }
207
-
208
- names.each do |name|
209
- assert_equal(:yay, interp.nodesearch_code(name).code)
210
- assert_equal("foo", interp.nodesearch_code(name).parentobj.name)
211
- # Now make sure that trying to redefine it throws an error.
212
- assert_raise(Puppet::ParseError) {
213
- interp.newnode(name, {})
214
- }
215
- end
216
- end
217
-
218
- def test_fqfind
219
- interp = mkinterp
220
-
221
- table = {}
222
- # Define a bunch of things.
223
- %w{a c a::b a::b::c a::c a::b::c::d a::b::c::d::e::f c::d}.each do |string|
224
- table[string] = string
225
- end
226
-
227
- check = proc do |namespace, hash|
228
- hash.each do |thing, result|
229
- assert_equal(result, interp.fqfind(namespace, thing, table),
230
- "Could not find %s in %s" % [thing, namespace])
231
- end
232
- end
233
-
234
- # Now let's do some test lookups.
235
-
236
- # First do something really simple
237
- check.call "a", "b" => "a::b", "b::c" => "a::b::c", "d" => nil, "::c" => "c"
238
-
239
- check.call "a::b", "c" => "a::b::c", "b" => "a::b", "a" => "a"
240
-
241
- check.call "a::b::c::d::e", "c" => "a::b::c", "::c" => "c",
242
- "c::d" => "a::b::c::d", "::c::d" => "c::d"
243
-
244
- check.call "", "a" => "a", "a::c" => "a::c"
245
- end
246
-
247
- def test_newdefine
248
- interp = mkinterp
249
-
250
- assert_nothing_raised {
251
- interp.newdefine("mydefine", :code => :yay,
252
- :arguments => ["a", stringobj("b")])
253
- }
254
-
255
- mydefine = interp.finddefine("", "mydefine")
256
- assert(mydefine, "Could not find definition")
257
- assert_equal("mydefine", interp.finddefine("", "mydefine").classname)
258
- assert_equal("", mydefine.namespace)
259
- assert_equal("mydefine", mydefine.classname)
260
-
261
- assert_raise(Puppet::ParseError) do
262
- interp.newdefine("mydefine", :code => :yay,
263
- :arguments => ["a", stringobj("b")])
264
- end
265
-
266
- # Now define the same thing in a different scope
267
- assert_nothing_raised {
268
- interp.newdefine("other::mydefine", :code => :other,
269
- :arguments => ["a", stringobj("b")])
270
- }
271
- other = interp.finddefine("other", "mydefine")
272
- assert(other, "Could not find definition")
273
- assert(interp.finddefine("", "other::mydefine"),
274
- "Could not find other::mydefine")
275
- assert_equal(:other, other.code)
276
- assert_equal("other", other.namespace)
277
- assert_equal("other::mydefine", other.classname)
278
- end
279
-
280
- def test_newclass
281
- interp = mkinterp
282
-
283
- mkcode = proc do |ary|
284
- classes = ary.collect do |string|
285
- AST::FlatString.new(:value => string)
286
- end
287
- AST::ASTArray.new(:children => classes)
288
- end
289
- scope = Puppet::Parser::Scope.new(:interp => interp)
290
-
291
- # First make sure that code is being appended
292
- code = mkcode.call(%w{original code})
293
-
294
- klass = nil
295
- assert_nothing_raised {
296
- klass = interp.newclass("myclass", :code => code)
297
- }
298
-
299
- assert(klass, "Did not return class")
300
-
301
- assert(interp.findclass("", "myclass"), "Could not find definition")
302
- assert_equal("myclass", interp.findclass("", "myclass").classname)
303
- assert_equal(%w{original code},
304
- interp.findclass("", "myclass").code.evaluate(:scope => scope))
305
-
306
- # Now create the same class name in a different scope
307
- assert_nothing_raised {
308
- klass = interp.newclass("other::myclass",
309
- :code => mkcode.call(%w{something diff}))
310
- }
311
- assert(klass, "Did not return class")
312
- other = interp.findclass("other", "myclass")
313
- assert(other, "Could not find class")
314
- assert(interp.findclass("", "other::myclass"), "Could not find class")
315
- assert_equal("other::myclass", other.classname)
316
- assert_equal("other::myclass", other.namespace)
317
- assert_equal(%w{something diff},
318
- interp.findclass("other", "myclass").code.evaluate(:scope => scope))
319
-
320
- # Newclass behaves differently than the others -- it just appends
321
- # the code to the existing class.
322
- code = mkcode.call(%w{something new})
323
- assert_nothing_raised do
324
- klass = interp.newclass("myclass", :code => code)
325
- end
326
- assert(klass, "Did not return class when appending")
327
- assert_equal(%w{original code something new},
328
- interp.findclass("", "myclass").code.evaluate(:scope => scope))
329
-
330
- # Make sure newclass deals correctly with nodes with no code
331
- klass = interp.newclass("nocode")
332
- assert(klass, "Did not return class")
333
-
334
- assert_nothing_raised do
335
- klass = interp.newclass("nocode", :code => mkcode.call(%w{yay test}))
336
- end
337
- assert(klass, "Did not return class with no code")
338
- assert_equal(%w{yay test},
339
- interp.findclass("", "nocode").code.evaluate(:scope => scope))
340
-
341
- # Then try merging something into nothing
342
- interp.newclass("nocode2", :code => mkcode.call(%w{foo test}))
343
- assert(klass, "Did not return class with no code")
344
-
345
- assert_nothing_raised do
346
- klass = interp.newclass("nocode2")
347
- end
348
- assert(klass, "Did not return class with no code")
349
- assert_equal(%w{foo test},
350
- interp.findclass("", "nocode2").code.evaluate(:scope => scope))
351
-
352
- # And lastly, nothing and nothing
353
- klass = interp.newclass("nocode3")
354
- assert(klass, "Did not return class with no code")
355
-
356
- assert_nothing_raised do
357
- klass = interp.newclass("nocode3")
358
- end
359
- assert(klass, "Did not return class with no code")
360
- assert_nil(interp.findclass("", "nocode3").code)
361
- end
362
163
 
363
164
  # Make sure class, node, and define methods are case-insensitive
364
165
  def test_structure_case_insensitivity
@@ -388,88 +189,6 @@ class TestInterpreter < PuppetTest::TestCase
388
189
  assert_equal(result, interp.nodesearch("yaYtEst.domAin.cOm"),
389
190
  "yaYtEst.domAin.cOm was not matched")
390
191
  end
391
-
392
- # Now make sure we get appropriate behaviour with parent class conflicts.
393
- def test_newclass_parentage
394
- interp = mkinterp
395
- interp.newclass("base1")
396
- interp.newclass("one::two::three")
397
-
398
- # First create it with no parentclass.
399
- assert_nothing_raised {
400
- interp.newclass("sub")
401
- }
402
- assert(interp.findclass("", "sub"), "Could not find definition")
403
- assert_nil(interp.findclass("", "sub").parentclass)
404
-
405
- # Make sure we can't set the parent class to ourself.
406
- assert_raise(Puppet::ParseError) {
407
- interp.newclass("sub", :parent => "sub")
408
- }
409
-
410
- # Now create another one, with a parentclass.
411
- assert_nothing_raised {
412
- interp.newclass("sub", :parent => "base1")
413
- }
414
-
415
- # Make sure we get the right parent class, and make sure it's not an object.
416
- assert_equal("base1",
417
- interp.findclass("", "sub").parentclass)
418
- assert_equal(interp.findclass("", "base1"),
419
- interp.findclass("", "sub").parentobj)
420
-
421
- # Now make sure we get a failure if we try to conflict.
422
- assert_raise(Puppet::ParseError) {
423
- interp.newclass("sub", :parent => "one::two::three")
424
- }
425
-
426
- # Make sure that failure didn't screw us up in any way.
427
- assert_equal(interp.findclass("", "base1"),
428
- interp.findclass("", "sub").parentobj)
429
- # But make sure we can create a class with a fq parent
430
- assert_nothing_raised {
431
- interp.newclass("another", :parent => "one::two::three")
432
- }
433
- assert_equal(interp.findclass("", "one::two::three"),
434
- interp.findclass("", "another").parentobj)
435
-
436
- end
437
-
438
- def test_namesplit
439
- interp = mkinterp
440
-
441
- assert_nothing_raised do
442
- {"base::sub" => %w{base sub},
443
- "main" => ["", "main"],
444
- "one::two::three::four" => ["one::two::three", "four"],
445
- }.each do |name, ary|
446
- result = interp.namesplit(name)
447
- assert_equal(ary, result, "%s split to %s" % [name, result])
448
- end
449
- end
450
- end
451
-
452
- # Make sure you can't have classes and defines with the same name in the
453
- # same scope.
454
- def test_classes_beat_defines
455
- interp = mkinterp
456
-
457
- assert_nothing_raised {
458
- interp.newclass("yay::funtest")
459
- }
460
-
461
- assert_raise(Puppet::ParseError) do
462
- interp.newdefine("yay::funtest")
463
- end
464
-
465
- assert_nothing_raised {
466
- interp.newdefine("yay::yaytest")
467
- }
468
-
469
- assert_raise(Puppet::ParseError) do
470
- interp.newclass("yay::yaytest")
471
- end
472
- end
473
192
 
474
193
  # Make sure our whole chain works.
475
194
  def test_evaluate
@@ -925,118 +644,29 @@ class TestInterpreter < PuppetTest::TestCase
925
644
  assert_equal({"base" => "true", "center" => "boo", "master" => "far"}, node.parameters, "node parameters were not set correctly with the top node")
926
645
  end
927
646
 
928
- # Setup a module.
929
- def mk_module(name, files = {})
930
- mdir = File.join(@dir, name)
931
- mandir = File.join(mdir, "manifests")
932
- FileUtils.mkdir_p mandir
647
+ # Make sure that reparsing is atomic -- failures don't cause a broken state, and we aren't subject
648
+ # to race conditions if someone contacts us while we're reparsing.
649
+ def test_atomic_reparsing
650
+ Puppet[:filetimeout] = -10
651
+ file = tempfile
652
+ File.open(file, "w") { |f| f.puts %{file { '/tmp': ensure => directory }} }
653
+ interp = mkinterp :Manifest => file, :UseNodes => false
933
654
 
934
- if defs = files[:define]
935
- files.delete(:define)
655
+ assert_nothing_raised("Could not compile the first time") do
656
+ interp.run("yay", {})
936
657
  end
937
- Dir.chdir(mandir) do
938
- files.each do |file, classes|
939
- File.open("%s.pp" % file, "w") do |f|
940
- classes.each { |klass|
941
- if defs
942
- f.puts "define %s {}" % klass
943
- else
944
- f.puts "class %s {}" % klass
945
- end
946
- }
947
- end
948
- end
949
- end
950
- end
951
-
952
- # #596 - make sure classes and definitions load automatically if they're in modules, so we don't have to manually load each one.
953
- def test_module_autoloading
954
- @dir = tempfile
955
- Puppet[:modulepath] = @dir
956
-
957
- FileUtils.mkdir_p @dir
958
-
959
- interp = mkinterp
960
-
961
- # Make sure we fail like normal for actually missing classes
962
- assert_nil(interp.findclass("", "nosuchclass"), "Did not return nil on missing classes")
963
-
964
- # test the simple case -- the module class itself
965
- name = "simple"
966
- mk_module(name, :init => [name])
967
658
 
968
- # Try to load the module automatically now
969
- klass = interp.findclass("", name)
970
- assert_instance_of(AST::HostClass, klass, "Did not autoload class from module init file")
971
- assert_equal(name, klass.classname, "Incorrect class was returned")
659
+ oldparser = interp.send(:instance_variable_get, "@parser")
972
660
 
973
- # Try loading the simple module when we're in something other than the base namespace.
974
- interp = mkinterp
975
- klass = interp.findclass("something::else", name)
976
- assert_instance_of(AST::HostClass, klass, "Did not autoload class from module init file")
977
- assert_equal(name, klass.classname, "Incorrect class was returned")
978
-
979
- # Now try it with a definition as the base file
980
- name = "simpdef"
981
- mk_module(name, :define => true, :init => [name])
982
-
983
- klass = interp.finddefine("", name)
984
- assert_instance_of(AST::Component, klass, "Did not autoload class from module init file")
985
- assert_equal(name, klass.classname, "Incorrect class was returned")
986
-
987
- # Now try it with namespace classes where both classes are in the init file
988
- interp = mkinterp
989
- modname = "both"
990
- name = "sub"
991
- mk_module(modname, :init => %w{both both::sub})
992
-
993
- # First try it with a namespace
994
- klass = interp.findclass("both", name)
995
- assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from module init file with a namespace")
996
- assert_equal("both::sub", klass.classname, "Incorrect class was returned")
997
-
998
- # Now try it using the fully qualified name
999
- interp = mkinterp
1000
- klass = interp.findclass("", "both::sub")
1001
- assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from module init file with no namespace")
1002
- assert_equal("both::sub", klass.classname, "Incorrect class was returned")
1003
-
1004
-
1005
- # Now try it with the class in a different file
1006
- interp = mkinterp
1007
- modname = "separate"
1008
- name = "sub"
1009
- mk_module(modname, :init => %w{separate}, :sub => %w{separate::sub})
1010
-
1011
- # First try it with a namespace
1012
- klass = interp.findclass("separate", name)
1013
- assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from separate file with a namespace")
1014
- assert_equal("separate::sub", klass.classname, "Incorrect class was returned")
1015
-
1016
- # Now try it using the fully qualified name
1017
- interp = mkinterp
1018
- klass = interp.findclass("", "separate::sub")
1019
- assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from separate file with no namespace")
1020
- assert_equal("separate::sub", klass.classname, "Incorrect class was returned")
1021
-
1022
- # Now make sure we don't get a failure when there's no module file
1023
- interp = mkinterp
1024
- modname = "alone"
1025
- name = "sub"
1026
- mk_module(modname, :sub => %w{alone::sub})
1027
-
1028
- # First try it with a namespace
1029
- assert_nothing_raised("Could not autoload file when module file is missing") do
1030
- klass = interp.findclass("alone", name)
661
+ # Now add a syntax failure
662
+ File.open(file, "w") { |f| f.puts %{file { /tmp: ensure => directory }} }
663
+ assert_nothing_raised("Could not compile the first time") do
664
+ interp.run("yay", {})
1031
665
  end
1032
- assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from alone file with a namespace")
1033
- assert_equal("alone::sub", klass.classname, "Incorrect class was returned")
1034
666
 
1035
- # Now try it using the fully qualified name
1036
- interp = mkinterp
1037
- klass = interp.findclass("", "alone::sub")
1038
- assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from alone file with no namespace")
1039
- assert_equal("alone::sub", klass.classname, "Incorrect class was returned")
667
+ # And make sure the old parser is still there
668
+ newparser = interp.send(:instance_variable_get, "@parser")
669
+ assert_equal(oldparser.object_id, newparser.object_id, "Failed parser still replaced existing parser")
1040
670
  end
1041
671
  end
1042
672
 
@@ -1171,4 +801,4 @@ class LdapReconnectTests < PuppetTest::TestCase
1171
801
  end
1172
802
  end
1173
803
 
1174
- # $Id: interpreter.rb 2686 2007-07-12 19:49:41Z luke $
804
+ # $Id: interpreter.rb 2742 2007-08-03 23:49:53Z luke $