puppet 0.9.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 (182) hide show
  1. data/CHANGELOG +0 -0
  2. data/COPYING +340 -0
  3. data/LICENSE +17 -0
  4. data/README +24 -0
  5. data/Rakefile +294 -0
  6. data/TODO +4 -0
  7. data/bin/cf2puppet +186 -0
  8. data/bin/puppet +176 -0
  9. data/bin/puppetca +213 -0
  10. data/bin/puppetd +246 -0
  11. data/bin/puppetdoc +184 -0
  12. data/bin/puppetmasterd +258 -0
  13. data/examples/code/allatonce +13 -0
  14. data/examples/code/assignments +11 -0
  15. data/examples/code/classing +35 -0
  16. data/examples/code/components +73 -0
  17. data/examples/code/execs +16 -0
  18. data/examples/code/failers/badclassnoparam +10 -0
  19. data/examples/code/failers/badclassparam +10 -0
  20. data/examples/code/failers/badcompnoparam +9 -0
  21. data/examples/code/failers/badcompparam +9 -0
  22. data/examples/code/failers/badtypeparam +3 -0
  23. data/examples/code/file.bl +11 -0
  24. data/examples/code/filedefaults +10 -0
  25. data/examples/code/fileparsing +116 -0
  26. data/examples/code/filerecursion +15 -0
  27. data/examples/code/functions +3 -0
  28. data/examples/code/groups +7 -0
  29. data/examples/code/head +30 -0
  30. data/examples/code/importing +8 -0
  31. data/examples/code/nodes +20 -0
  32. data/examples/code/one +8 -0
  33. data/examples/code/relationships +34 -0
  34. data/examples/code/selectors +28 -0
  35. data/examples/code/simpletests +11 -0
  36. data/examples/code/snippets/argumentdefaults +14 -0
  37. data/examples/code/snippets/casestatement +39 -0
  38. data/examples/code/snippets/classheirarchy.pp +15 -0
  39. data/examples/code/snippets/classincludes.pp +17 -0
  40. data/examples/code/snippets/classpathtest +11 -0
  41. data/examples/code/snippets/dirchmod +19 -0
  42. data/examples/code/snippets/failmissingexecpath.pp +13 -0
  43. data/examples/code/snippets/falsevalues.pp +3 -0
  44. data/examples/code/snippets/filecreate +11 -0
  45. data/examples/code/snippets/implicititeration +15 -0
  46. data/examples/code/snippets/multipleinstances +7 -0
  47. data/examples/code/snippets/namevartest +9 -0
  48. data/examples/code/snippets/scopetest +13 -0
  49. data/examples/code/snippets/selectorvalues.pp +22 -0
  50. data/examples/code/snippets/simpledefaults +5 -0
  51. data/examples/code/snippets/simpleselector +38 -0
  52. data/examples/code/svncommit +13 -0
  53. data/examples/root/bin/sleeper +69 -0
  54. data/examples/root/etc/configfile +0 -0
  55. data/examples/root/etc/debian-passwd +29 -0
  56. data/examples/root/etc/debian-syslog.conf +71 -0
  57. data/examples/root/etc/init.d/sleeper +65 -0
  58. data/examples/root/etc/otherfile +0 -0
  59. data/examples/root/etc/puppet/fileserver.conf +3 -0
  60. data/examples/root/etc/puppet/puppetmasterd.conf +10 -0
  61. data/ext/module:puppet +195 -0
  62. data/install.rb +270 -0
  63. data/lib/puppet.rb +249 -0
  64. data/lib/puppet/base64.rb +19 -0
  65. data/lib/puppet/client.rb +519 -0
  66. data/lib/puppet/config.rb +49 -0
  67. data/lib/puppet/daemon.rb +208 -0
  68. data/lib/puppet/element.rb +71 -0
  69. data/lib/puppet/event.rb +259 -0
  70. data/lib/puppet/log.rb +321 -0
  71. data/lib/puppet/metric.rb +250 -0
  72. data/lib/puppet/parsedfile.rb +38 -0
  73. data/lib/puppet/parser/ast.rb +1560 -0
  74. data/lib/puppet/parser/interpreter.rb +150 -0
  75. data/lib/puppet/parser/lexer.rb +226 -0
  76. data/lib/puppet/parser/parser.rb +1354 -0
  77. data/lib/puppet/parser/scope.rb +755 -0
  78. data/lib/puppet/server.rb +170 -0
  79. data/lib/puppet/server/authstore.rb +227 -0
  80. data/lib/puppet/server/ca.rb +140 -0
  81. data/lib/puppet/server/filebucket.rb +147 -0
  82. data/lib/puppet/server/fileserver.rb +477 -0
  83. data/lib/puppet/server/logger.rb +43 -0
  84. data/lib/puppet/server/master.rb +103 -0
  85. data/lib/puppet/server/servlet.rb +247 -0
  86. data/lib/puppet/sslcertificates.rb +737 -0
  87. data/lib/puppet/statechange.rb +150 -0
  88. data/lib/puppet/storage.rb +95 -0
  89. data/lib/puppet/transaction.rb +179 -0
  90. data/lib/puppet/transportable.rb +151 -0
  91. data/lib/puppet/type.rb +1354 -0
  92. data/lib/puppet/type/component.rb +141 -0
  93. data/lib/puppet/type/cron.rb +543 -0
  94. data/lib/puppet/type/exec.rb +316 -0
  95. data/lib/puppet/type/group.rb +152 -0
  96. data/lib/puppet/type/nameservice.rb +3 -0
  97. data/lib/puppet/type/nameservice/netinfo.rb +173 -0
  98. data/lib/puppet/type/nameservice/objectadd.rb +146 -0
  99. data/lib/puppet/type/nameservice/posix.rb +200 -0
  100. data/lib/puppet/type/package.rb +420 -0
  101. data/lib/puppet/type/package/apt.rb +70 -0
  102. data/lib/puppet/type/package/dpkg.rb +108 -0
  103. data/lib/puppet/type/package/rpm.rb +81 -0
  104. data/lib/puppet/type/package/sun.rb +117 -0
  105. data/lib/puppet/type/package/yum.rb +58 -0
  106. data/lib/puppet/type/pfile.rb +569 -0
  107. data/lib/puppet/type/pfile/checksum.rb +219 -0
  108. data/lib/puppet/type/pfile/create.rb +108 -0
  109. data/lib/puppet/type/pfile/group.rb +129 -0
  110. data/lib/puppet/type/pfile/mode.rb +131 -0
  111. data/lib/puppet/type/pfile/source.rb +264 -0
  112. data/lib/puppet/type/pfile/type.rb +31 -0
  113. data/lib/puppet/type/pfile/uid.rb +166 -0
  114. data/lib/puppet/type/pfilebucket.rb +80 -0
  115. data/lib/puppet/type/pprocess.rb +97 -0
  116. data/lib/puppet/type/service.rb +347 -0
  117. data/lib/puppet/type/service/base.rb +17 -0
  118. data/lib/puppet/type/service/debian.rb +50 -0
  119. data/lib/puppet/type/service/init.rb +145 -0
  120. data/lib/puppet/type/service/smf.rb +29 -0
  121. data/lib/puppet/type/state.rb +182 -0
  122. data/lib/puppet/type/symlink.rb +183 -0
  123. data/lib/puppet/type/tidy.rb +183 -0
  124. data/lib/puppet/type/typegen.rb +149 -0
  125. data/lib/puppet/type/typegen/filerecord.rb +243 -0
  126. data/lib/puppet/type/typegen/filetype.rb +316 -0
  127. data/lib/puppet/type/user.rb +290 -0
  128. data/lib/puppet/util.rb +138 -0
  129. data/test/certmgr/certmgr.rb +265 -0
  130. data/test/client/client.rb +203 -0
  131. data/test/executables/puppetbin.rb +53 -0
  132. data/test/executables/puppetca.rb +79 -0
  133. data/test/executables/puppetd.rb +71 -0
  134. data/test/executables/puppetmasterd.rb +153 -0
  135. data/test/executables/puppetmodule.rb +60 -0
  136. data/test/language/ast.rb +412 -0
  137. data/test/language/interpreter.rb +71 -0
  138. data/test/language/scope.rb +412 -0
  139. data/test/language/snippets.rb +445 -0
  140. data/test/other/events.rb +111 -0
  141. data/test/other/log.rb +195 -0
  142. data/test/other/metrics.rb +92 -0
  143. data/test/other/overrides.rb +115 -0
  144. data/test/other/parsedfile.rb +31 -0
  145. data/test/other/relationships.rb +113 -0
  146. data/test/other/state.rb +106 -0
  147. data/test/other/storage.rb +39 -0
  148. data/test/other/transactions.rb +235 -0
  149. data/test/parser/lexer.rb +120 -0
  150. data/test/parser/parser.rb +180 -0
  151. data/test/puppet/conffiles.rb +104 -0
  152. data/test/puppet/defaults.rb +100 -0
  153. data/test/puppet/error.rb +23 -0
  154. data/test/puppet/utiltest.rb +120 -0
  155. data/test/puppettest.rb +774 -0
  156. data/test/server/authstore.rb +209 -0
  157. data/test/server/bucket.rb +227 -0
  158. data/test/server/ca.rb +201 -0
  159. data/test/server/fileserver.rb +710 -0
  160. data/test/server/logger.rb +175 -0
  161. data/test/server/master.rb +150 -0
  162. data/test/server/server.rb +130 -0
  163. data/test/tagging/tagging.rb +80 -0
  164. data/test/test +51 -0
  165. data/test/types/basic.rb +119 -0
  166. data/test/types/component.rb +272 -0
  167. data/test/types/cron.rb +261 -0
  168. data/test/types/exec.rb +273 -0
  169. data/test/types/file.rb +616 -0
  170. data/test/types/filebucket.rb +167 -0
  171. data/test/types/fileignoresource.rb +287 -0
  172. data/test/types/filesources.rb +587 -0
  173. data/test/types/filetype.rb +162 -0
  174. data/test/types/group.rb +271 -0
  175. data/test/types/package.rb +205 -0
  176. data/test/types/query.rb +101 -0
  177. data/test/types/service.rb +100 -0
  178. data/test/types/symlink.rb +93 -0
  179. data/test/types/tidy.rb +124 -0
  180. data/test/types/type.rb +135 -0
  181. data/test/types/user.rb +371 -0
  182. metadata +243 -0
@@ -0,0 +1,774 @@
1
+ libdir = File.join(File.dirname(__FILE__), '../lib')
2
+ unless $:.include?(libdir)
3
+ $:.unshift libdir
4
+ end
5
+
6
+ require 'puppet'
7
+ require 'test/unit'
8
+
9
+ module TestPuppet
10
+ def newcomp(name,*ary)
11
+ if name.is_a?(Puppet::Type)
12
+ ary.unshift name
13
+ name = name.name
14
+ end
15
+ comp = Puppet::Type::Component.create(
16
+ :name => name
17
+ )
18
+ ary.each { |item| comp.push item }
19
+
20
+ return comp
21
+ end
22
+
23
+ def setup
24
+ if defined? @@testcount
25
+ @@testcount += 1
26
+ else
27
+ @@testcount = 0
28
+ end
29
+
30
+ @configpath = File.join(tmpdir,
31
+ self.class.to_s + "configdir" + @@testcount.to_s
32
+ )
33
+
34
+ Puppet[:puppetconf] = @configpath
35
+ Puppet[:puppetvar] = @configpath
36
+
37
+ unless File.exists?(@configpath)
38
+ Dir.mkdir(@configpath)
39
+ end
40
+
41
+ @@tmpfiles = [@configpath, tmpdir()]
42
+ @@tmppids = []
43
+
44
+ if $0 =~ /.+\.rb/ or Puppet[:debug]
45
+ Puppet[:logdest] = :console
46
+ Puppet[:loglevel] = :debug
47
+ $VERBOSE = 1
48
+ else
49
+ Puppet::Log.close
50
+ Puppet[:logdest] = "/dev/null"
51
+ Puppet[:httplog] = "/dev/null"
52
+ end
53
+ end
54
+
55
+
56
+ def spin
57
+ # Just disable spin, unless we really need it
58
+ return
59
+ if Puppet[:debug]
60
+ return
61
+ end
62
+ @modes = %w{| / - \\}
63
+ unless defined? @mode
64
+ @mode = 0
65
+ end
66
+
67
+ $stderr.print "%s" % @modes[@mode]
68
+ if @mode == @modes.length - 1
69
+ @mode = 0
70
+ else
71
+ @mode += 1
72
+ end
73
+ $stderr.flush
74
+ end
75
+
76
+ # stop any services that might be hanging around
77
+ def stopservices
78
+ if stype = Puppet::Type.type(:service)
79
+ stype.each { |service|
80
+ service[:running] = false
81
+ service.sync
82
+ }
83
+ end
84
+ end
85
+
86
+ def teardown
87
+ stopservices
88
+ @@tmpfiles.each { |file|
89
+ if FileTest.exists?(file)
90
+ system("chmod -R 755 %s" % file)
91
+ system("rm -rf %s" % file)
92
+ end
93
+ }
94
+ @@tmpfiles.clear
95
+
96
+ @@tmppids.each { |pid|
97
+ %x{kill -INT #{pid} 2>/dev/null}
98
+ }
99
+ @@tmppids.clear
100
+ Puppet::Type.allclear
101
+ Puppet.clear
102
+
103
+ # reset all of the logs
104
+ Puppet::Log.close
105
+ end
106
+
107
+ def tempfile
108
+ if defined? @tmpfilenum
109
+ @tmpfilenum += 1
110
+ else
111
+ @tmpfilenum = 1
112
+ end
113
+ f = File.join(self.tmpdir(), self.class.to_s + "testfile" + @tmpfilenum.to_s)
114
+ @@tmpfiles << f
115
+ return f
116
+ end
117
+
118
+ def testdir
119
+ if defined? @testdirnum
120
+ @testdirnum += 1
121
+ else
122
+ @testdirnum = 1
123
+ end
124
+ d = File.join(self.tmpdir(), self.class.to_s + "testdir" + @testdirnum.to_s)
125
+ @@tmpfiles << d
126
+ return d
127
+ end
128
+
129
+ def tmpdir
130
+ unless defined? @tmpdir and @tmpdir
131
+ @tmpdir = case Facter["operatingsystem"].value
132
+ when "Darwin": "/private/tmp"
133
+ when "SunOS": "/var/tmp"
134
+ else
135
+ "/tmp"
136
+ end
137
+
138
+ @tmpdir = File.join(@tmpdir, "puppettesting")
139
+
140
+ unless File.exists?(@tmpdir)
141
+ FileUtils.mkdir_p(@tmpdir)
142
+ File.chmod(01777, @tmpdir)
143
+ end
144
+ end
145
+ @tmpdir
146
+ end
147
+
148
+ def assert_rollback_events(trans, events, msg)
149
+ run_events(:rollback, trans, events, msg)
150
+ end
151
+
152
+ def assert_events(comp, events, msg = nil)
153
+ trans = nil
154
+ msg ||= comp.name
155
+ assert_nothing_raised("Component %s failed" % [msg]) {
156
+ trans = comp.evaluate
157
+ }
158
+
159
+ run_events(:evaluate, trans, events, msg)
160
+ end
161
+
162
+ def run_events(type, trans, events, msg)
163
+ case type
164
+ when :evaluate, :rollback: # things are hunky-dory
165
+ else
166
+ raise Puppet::DevError, "Incorrect run_events type"
167
+ end
168
+
169
+ method = type
170
+
171
+ newevents = nil
172
+ assert_nothing_raised("Transaction %s %s failed" % [type, msg]) {
173
+ newevents = trans.send(method).reject { |e| e.nil? }.collect { |e|
174
+ e.event
175
+ }
176
+ }
177
+
178
+ assert_equal(events, newevents, "Incorrect %s %s events" % [type, msg])
179
+
180
+ return trans
181
+ end
182
+
183
+ def nonrootuser
184
+ Etc.passwd { |user|
185
+ if user.uid != Process.uid and user.uid > 0
186
+ return user
187
+ end
188
+ }
189
+ end
190
+
191
+ def nonrootgroup
192
+ Etc.group { |group|
193
+ if group.gid != Process.gid and group.gid > 0
194
+ return group
195
+ end
196
+ }
197
+ end
198
+ end
199
+
200
+
201
+ module ServerTest
202
+ include TestPuppet
203
+ def setup
204
+ super
205
+
206
+ if defined? @@port
207
+ @@port += 1
208
+ else
209
+ @@port = 8085
210
+ end
211
+ end
212
+
213
+ # create a simple manifest that just creates a file
214
+ def mktestmanifest
215
+ file = File.join(Puppet[:puppetconf], "%ssite.pp" % (self.class.to_s + "test"))
216
+ @createdfile = File.join(tmpdir(), self.class.to_s + "servermanifesttesting")
217
+
218
+ File.open(file, "w") { |f|
219
+ f.puts "file { \"%s\": create => true, mode => 755 }\n" % @createdfile
220
+ }
221
+
222
+ @@tmpfiles << @createdfile
223
+ @@tmpfiles << file
224
+
225
+ return file
226
+ end
227
+
228
+ # create a server, forked into the background
229
+ def mkserver(handlers = nil)
230
+ # our default handlers
231
+ unless handlers
232
+ handlers = {
233
+ :CA => {}, # so that certs autogenerate
234
+ :Master => {
235
+ :File => mktestmanifest(),
236
+ :UseNodes => false
237
+ },
238
+ }
239
+ end
240
+
241
+ # then create the actual server
242
+ server = nil
243
+ assert_nothing_raised {
244
+ server = Puppet::Server.new(
245
+ :Port => @@port,
246
+ :Handlers => handlers
247
+ )
248
+ }
249
+
250
+ # fork it
251
+ spid = fork {
252
+ trap(:INT) { server.shutdown }
253
+ server.start
254
+ }
255
+
256
+ # and store its pid for killing
257
+ @@tmppids << spid
258
+
259
+ # give the server a chance to do its thing
260
+ sleep 1
261
+ return spid
262
+ end
263
+
264
+ end
265
+
266
+ module ExeTest
267
+ include ServerTest
268
+ unless ENV["PATH"] =~ /puppet/
269
+ # ok, we have to add the bin directory to our search path
270
+ ENV["PATH"] += ":" + File.join($puppetbase, "bin")
271
+
272
+ # and then the library directories
273
+ libdirs = $:.find_all { |dir|
274
+ dir =~ /puppet/ or dir =~ /\.\./
275
+ }
276
+ ENV["RUBYLIB"] = libdirs.join(":")
277
+ end
278
+
279
+ def startmasterd(args = "")
280
+ output = nil
281
+
282
+ manifest = mktestmanifest()
283
+ args += " --manifest %s" % manifest
284
+ args += " --confdir %s" % Puppet[:puppetconf]
285
+ args += " --vardir %s" % Puppet[:puppetvar]
286
+ args += " --port %s" % @@port
287
+ args += " --nonodes"
288
+ args += " --autosign"
289
+
290
+ cmd = "puppetmasterd %s" % args
291
+
292
+
293
+ assert_nothing_raised {
294
+ output = %x{#{cmd}}.chomp
295
+ }
296
+ assert($? == 0, "Puppetmasterd exit status was %s" % $?)
297
+ assert_equal("", output, "Puppetmasterd produced output %s" % output)
298
+ sleep(1)
299
+
300
+ return manifest
301
+ end
302
+
303
+ def stopmasterd(running = true)
304
+ ps = Facter["ps"].value || "ps -ef"
305
+
306
+ pidfile = File.join(Puppet[:puppetvar], "puppetmasterd.pid")
307
+
308
+ pid = nil
309
+ if FileTest.exists?(pidfile)
310
+ pid = File.read(pidfile).chomp.to_i
311
+ File.unlink(pidfile)
312
+ end
313
+
314
+ if running or pid
315
+ runningpid = nil
316
+ %x{#{ps}}.chomp.split(/\n/).each { |line|
317
+ if line =~ /ruby.+puppetmasterd/
318
+ next if line =~ /\.rb/ # skip the test script itself
319
+ ary = line.sub(/^\s+/, '').split(/\s+/)
320
+ runningpid = ary[1].to_i
321
+ end
322
+ }
323
+
324
+ if running
325
+ assert(runningpid, "Process is not running")
326
+ assert_equal(pid, runningpid, "PIDs are not equal")
327
+ else
328
+ return
329
+ end
330
+ end
331
+
332
+ # we default to mandating that it's running, but teardown
333
+ # doesn't require that
334
+ if pid
335
+ if pid == $$
336
+ raise Puppet::Error, "Tried to kill own pid"
337
+ end
338
+ assert_nothing_raised {
339
+ Process.kill("-INT", pid)
340
+ }
341
+ end
342
+ end
343
+
344
+ def teardown
345
+ stopmasterd(false)
346
+ super
347
+ end
348
+ end
349
+
350
+ module FileTesting
351
+ include TestPuppet
352
+ def cycle(comp)
353
+ trans = nil
354
+ assert_nothing_raised {
355
+ trans = comp.evaluate
356
+ }
357
+ assert_nothing_raised {
358
+ trans.evaluate
359
+ }
360
+ end
361
+
362
+ def randlist(list)
363
+ num = rand(4)
364
+ if num == 0
365
+ num = 1
366
+ end
367
+ set = []
368
+
369
+ ret = []
370
+ num.times { |index|
371
+ item = list[rand(list.length)]
372
+ if set.include?(item)
373
+ redo
374
+ end
375
+
376
+ ret.push item
377
+ }
378
+ return ret
379
+ end
380
+
381
+ def mkranddirsandfiles(dirs = nil,files = nil,depth = 3)
382
+ if depth < 0
383
+ return
384
+ end
385
+
386
+ unless dirs
387
+ dirs = %w{This Is A Set Of Directories}
388
+ end
389
+
390
+ unless files
391
+ files = %w{and this is a set of files}
392
+ end
393
+
394
+ tfiles = randlist(files)
395
+ tdirs = randlist(dirs)
396
+
397
+ tfiles.each { |file|
398
+ File.open(file, "w") { |of|
399
+ 4.times {
400
+ of.puts rand(100)
401
+ }
402
+ }
403
+ }
404
+
405
+ tdirs.each { |dir|
406
+ # it shouldn't already exist, but...
407
+ unless FileTest.exists?(dir)
408
+ Dir.mkdir(dir)
409
+ FileUtils.cd(dir) {
410
+ mkranddirsandfiles(dirs,files,depth - 1)
411
+ }
412
+ end
413
+ }
414
+ end
415
+
416
+ def file_list(dir)
417
+ list = nil
418
+ FileUtils.cd(dir) {
419
+ list = %x{find . 2>/dev/null}.chomp.split(/\n/)
420
+ }
421
+ return list
422
+ end
423
+
424
+ def assert_trees_equal(fromdir,todir)
425
+ assert(FileTest.directory?(fromdir))
426
+ assert(FileTest.directory?(todir))
427
+
428
+ # verify the file list is the same
429
+ fromlist = nil
430
+ FileUtils.cd(fromdir) {
431
+ fromlist = %x{find . 2>/dev/null}.chomp.split(/\n/).reject { |file|
432
+ ! FileTest.readable?(file)
433
+ }.sort
434
+ }
435
+ tolist = file_list(todir).sort
436
+
437
+ fromlist.sort.zip(tolist.sort).each { |a,b|
438
+ assert_equal(a, b,
439
+ "Fromfile %s with length %s does not match tofile %s with length %s" %
440
+ [a, fromlist.length, b, tolist.length])
441
+ }
442
+ #assert_equal(fromlist,tolist)
443
+
444
+ # and then do some verification that the files are actually set up
445
+ # the same
446
+ checked = 0
447
+ fromlist.each_with_index { |file,i|
448
+ fromfile = File.join(fromdir,file)
449
+ tofile = File.join(todir,file)
450
+ fromstat = File.stat(fromfile)
451
+ tostat = File.stat(tofile)
452
+ [:ftype,:gid,:mode,:uid].each { |method|
453
+ assert_equal(
454
+ fromstat.send(method),
455
+ tostat.send(method)
456
+ )
457
+
458
+ next if fromstat.ftype == "directory"
459
+ if checked < 10 and i % 3 == 0
460
+ from = File.open(fromfile) { |f| f.read }
461
+ to = File.open(tofile) { |f| f.read }
462
+
463
+ assert_equal(from,to)
464
+ checked += 1
465
+ end
466
+ }
467
+ }
468
+ end
469
+
470
+ def random_files(dir)
471
+ checked = 0
472
+ list = file_list(dir)
473
+ list.reverse.each_with_index { |file,i|
474
+ path = File.join(dir,file)
475
+ stat = File.stat(dir)
476
+ if checked < 10 and (i % 3) == 2
477
+ unless yield path
478
+ next
479
+ end
480
+ checked += 1
481
+ end
482
+ }
483
+ end
484
+
485
+ def delete_random_files(dir)
486
+ deleted = []
487
+ random_files(dir) { |file|
488
+ stat = File.stat(file)
489
+ begin
490
+ if stat.ftype == "directory"
491
+ false
492
+ else
493
+ deleted << file
494
+ File.unlink(file)
495
+ true
496
+ end
497
+ rescue => detail
498
+ # we probably won't be able to open our own secured files
499
+ puts detail
500
+ false
501
+ end
502
+ }
503
+
504
+ return deleted
505
+ end
506
+
507
+ def add_random_files(dir)
508
+ added = []
509
+ random_files(dir) { |file|
510
+ stat = File.stat(file)
511
+ begin
512
+ if stat.ftype == "directory"
513
+ name = File.join(file,"file" + rand(100).to_s)
514
+ File.open(name, "w") { |f|
515
+ f.puts rand(10)
516
+ }
517
+ added << name
518
+ else
519
+ false
520
+ end
521
+ rescue => detail
522
+ # we probably won't be able to open our own secured files
523
+ puts detail
524
+ false
525
+ end
526
+ }
527
+ return added
528
+ end
529
+
530
+ def modify_random_files(dir)
531
+ modded = []
532
+ random_files(dir) { |file|
533
+ stat = File.stat(file)
534
+ begin
535
+ if stat.ftype == "directory"
536
+ false
537
+ else
538
+ File.open(file, "w") { |f|
539
+ f.puts rand(10)
540
+ }
541
+ modded << name
542
+ true
543
+ end
544
+ rescue => detail
545
+ # we probably won't be able to open our own secured files
546
+ puts detail
547
+ false
548
+ end
549
+ }
550
+ return modded
551
+ end
552
+
553
+ def readonly_random_files(dir)
554
+ modded = []
555
+ random_files(dir) { |file|
556
+ stat = File.stat(file)
557
+ begin
558
+ if stat.ftype == "directory"
559
+ File.new(file).chmod(0111)
560
+ else
561
+ File.new(file).chmod(0000)
562
+ end
563
+ modded << file
564
+ rescue => detail
565
+ # we probably won't be able to open our own secured files
566
+ puts detail
567
+ false
568
+ end
569
+ }
570
+ return modded
571
+ end
572
+
573
+ def conffile
574
+ File.join($puppetbase,"examples/root/etc/configfile")
575
+ end
576
+ end
577
+
578
+ module ParserTesting
579
+ include TestPuppet
580
+ AST = Puppet::Parser::AST
581
+
582
+ def astarray
583
+ AST::ASTArray.new(
584
+ :children => []
585
+ )
586
+ end
587
+
588
+ def classobj(name, args = {})
589
+ unless args.include?(:name)
590
+ args[:name] = nameobj(name)
591
+ end
592
+ unless args.include?(:code)
593
+ args[:code] = AST::ASTArray.new(
594
+ :file => tempfile(),
595
+ :line => rand(100),
596
+ :children => [
597
+ varobj("%svar" % name, "%svalue" % name),
598
+ fileobj("/%s" % name)
599
+ ]
600
+ )
601
+ end
602
+ assert_nothing_raised("Could not create class %s" % name) {
603
+ return AST::ClassDef.new(args)
604
+ }
605
+ end
606
+
607
+ def compobj(name, args = {})
608
+ args[:file] = tempfile()
609
+ args[:line] = rand(100)
610
+ args[:name] = nameobj(name)
611
+ args[:code] = AST::ASTArray.new(
612
+ :file => tempfile(),
613
+ :line => rand(100),
614
+ :children => [
615
+ varobj("%svar" % name, "%svalue" % name),
616
+ fileobj("/%s" % name)
617
+ ]
618
+ )
619
+ assert_nothing_raised("Could not create compdef %s" % name) {
620
+ return AST::CompDef.new(args)
621
+ }
622
+ end
623
+
624
+ def fileobj(path, hash = {"owner" => "root"})
625
+ assert_nothing_raised("Could not create file %s" % path) {
626
+ return AST::ObjectDef.new(
627
+ :file => tempfile(),
628
+ :line => rand(100),
629
+ :name => stringobj(path),
630
+ :type => nameobj("file"),
631
+ :params => objectinst(hash)
632
+ )
633
+ }
634
+ end
635
+
636
+ def nameobj(name)
637
+ assert_nothing_raised("Could not create name %s" % name) {
638
+ return AST::Name.new(
639
+ :file => tempfile(),
640
+ :line => rand(100),
641
+ :value => name
642
+ )
643
+ }
644
+ end
645
+
646
+ def nodeobj(name)
647
+ assert_nothing_raised("Could not create node %s" % name) {
648
+ return AST::NodeDef.new(
649
+ :file => tempfile(),
650
+ :line => rand(100),
651
+ :names => nameobj(name),
652
+ :code => AST::ASTArray.new(
653
+ :children => [
654
+ varobj("%svar" % name, "%svalue" % name),
655
+ fileobj("/%s" % name)
656
+ ]
657
+ )
658
+ )
659
+ }
660
+ end
661
+
662
+ def objectinst(hash)
663
+ assert_nothing_raised("Could not create object instance") {
664
+ params = hash.collect { |param, value|
665
+ objectparam(param, value)
666
+ }
667
+ return AST::ObjectInst.new(
668
+ :file => tempfile(),
669
+ :line => rand(100),
670
+ :children => params
671
+ )
672
+ }
673
+ end
674
+
675
+ def objectparam(param, value)
676
+ assert_nothing_raised("Could not create param %s" % param) {
677
+ return AST::ObjectParam.new(
678
+ :file => tempfile(),
679
+ :line => rand(100),
680
+ :param => nameobj(param),
681
+ :value => stringobj(value)
682
+ )
683
+ }
684
+ end
685
+
686
+ def stringobj(value)
687
+ AST::String.new(
688
+ :file => tempfile(),
689
+ :line => rand(100),
690
+ :value => value
691
+ )
692
+ end
693
+
694
+ def varobj(name, value)
695
+ assert_nothing_raised("Could not create %s code" % name) {
696
+ return AST::VarDef.new(
697
+ :file => tempfile(),
698
+ :line => rand(100),
699
+ :name => nameobj(name),
700
+ :value => stringobj(value)
701
+ )
702
+ }
703
+ end
704
+ end
705
+
706
+ class PuppetTestSuite
707
+ attr_accessor :subdir
708
+
709
+ def self.basedir
710
+ unless defined? @basedir
711
+ @basedir = File.join($puppetbase, "test")
712
+ end
713
+ @basedir
714
+ end
715
+
716
+ def self.list
717
+ puts "testdir is %s" % self.basedir
718
+ Dir.entries(self.basedir).find_all { |file|
719
+ path = File.join(@basedir, file)
720
+ FileTest.directory?(path) and file !~ /^\./
721
+ }
722
+ end
723
+
724
+ def initialize(name)
725
+ path = File.join(self.class.basedir, name)
726
+ unless FileTest.directory?(path)
727
+ puts "TestSuites are directories containing test cases"
728
+ puts "no such directory: %s" % path
729
+ exit(65)
730
+ end
731
+
732
+ # load each of the files
733
+ Dir.entries(path).collect { |file|
734
+ File.join(path,file)
735
+ }.find_all { |file|
736
+ FileTest.file?(file) and file =~ /\.rb$/
737
+ }.sort { |a,b|
738
+ # in the order they were modified, so the last modified files
739
+ # are loaded and thus displayed last
740
+ File.stat(b) <=> File.stat(a)
741
+ }.each { |file|
742
+ require file
743
+ }
744
+ end
745
+ end
746
+
747
+ # a list of files that we can parse for testing
748
+ def textfiles
749
+ textdir = File.join($puppetbase,"examples","code", "snippets")
750
+ Dir.entries(textdir).reject { |f|
751
+ f =~ /^\./ or f =~ /fail/
752
+ }.each { |f|
753
+ yield File.join(textdir, f)
754
+ }
755
+ end
756
+
757
+ def failers
758
+ textdir = File.join($puppetbase,"examples","code", "failers")
759
+ # only parse this one file now
760
+ files = Dir.entries(textdir).reject { |file|
761
+ file =~ %r{\.swp}
762
+ }.reject { |file|
763
+ file =~ %r{\.disabled}
764
+ }.collect { |file|
765
+ File.join(textdir,file)
766
+ }.find_all { |file|
767
+ FileTest.file?(file)
768
+ }.sort.each { |file|
769
+ Puppet.debug "Processing %s" % file
770
+ yield file
771
+ }
772
+ end
773
+
774
+ # $Id: puppettest.rb 750 2005-11-22 05:34:43Z luke $