pdqtest 1.4.1 → 1.9.9beta2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +9 -3
  3. data/doc/acceptance_tests.md +100 -22
  4. data/doc/caching.md +5 -1
  5. data/doc/development.md +16 -5
  6. data/doc/emoji.md +20 -9
  7. data/doc/enabling_testing.md +15 -3
  8. data/doc/examples.md +25 -6
  9. data/doc/hiera.md +30 -11
  10. data/doc/installation.md +59 -8
  11. data/doc/pdk.md +334 -0
  12. data/doc/puppet_facts.md +45 -3
  13. data/doc/puppet_module_dependencies.md +34 -16
  14. data/doc/running_tests.md +35 -15
  15. data/doc/test_generation.md +11 -19
  16. data/doc/tips_and_tricks.md +17 -8
  17. data/doc/troubleshooting.md +19 -8
  18. data/doc/upgrading.md +125 -6
  19. data/doc/windows.md +51 -0
  20. data/docker_images/centos/Dockerfile +4 -3
  21. data/docker_images/centos/Makefile +1 -1
  22. data/docker_images/ubuntu/Dockerfile +3 -3
  23. data/docker_images/windows/Dockerfile +26 -0
  24. data/docker_images/windows/make.ps1 +2 -0
  25. data/exe/pdqtest +73 -28
  26. data/lib/pdqtest/core.rb +1 -1
  27. data/lib/pdqtest/docker.rb +143 -51
  28. data/lib/pdqtest/emoji.rb +33 -7
  29. data/lib/pdqtest/fastcheck.rb +19 -0
  30. data/lib/pdqtest/instance.rb +16 -15
  31. data/lib/pdqtest/logger.rb +35 -0
  32. data/lib/pdqtest/pdk.rb +98 -0
  33. data/lib/pdqtest/pdqtest1x.rb +115 -0
  34. data/lib/pdqtest/puppet.rb +277 -134
  35. data/lib/pdqtest/skeleton.rb +119 -39
  36. data/lib/pdqtest/upgrade.rb +42 -42
  37. data/lib/pdqtest/util.rb +82 -2
  38. data/lib/pdqtest/version.rb +1 -2
  39. data/pdqtest.gemspec +8 -13
  40. data/res/{skeleton → acceptance}/init.bats +0 -0
  41. data/res/{skeleton → acceptance}/init__before.bats +0 -0
  42. data/res/{skeleton → acceptance}/init__setup.sh +0 -0
  43. data/res/skeleton/.puppet-lint.rc +5 -0
  44. data/res/skeleton/{dot_travis.yml → .travis.yml} +0 -0
  45. data/res/skeleton/Makefile +20 -5
  46. data/res/skeleton/make.ps1 +66 -0
  47. data/res/skeleton/spec/fixtures/hiera.yaml +13 -0
  48. data/res/skeleton/spec/fixtures/hieradata/test.yaml +11 -0
  49. data/res/templates/examples_init.pp.erb +1 -1
  50. metadata +47 -115
  51. data/lib/pdqtest/lint.rb +0 -31
  52. data/lib/pdqtest/rspec.rb +0 -69
  53. data/lib/pdqtest/syntax.rb +0 -20
  54. data/res/skeleton/Gemfile +0 -7
  55. data/res/skeleton/Rakefile +0 -3
  56. data/res/skeleton/dot_gitignore +0 -9
  57. data/res/skeleton/dot_rspec +0 -2
  58. data/res/skeleton/hiera.yaml +0 -7
  59. data/res/skeleton/spec_helper.rb +0 -4
  60. data/res/skeleton/test.yaml +0 -3
@@ -4,26 +4,102 @@ require 'pdqtest/instance'
4
4
  require 'pdqtest/emoji'
5
5
  require 'escort'
6
6
  require 'yaml'
7
+ require 'json'
8
+ require 'logger'
7
9
 
8
10
  module PDQTest
9
11
  class Puppet
10
- METADATA = 'metadata.json'
11
- MODULE_DIR = '/etc/puppetlabs/code/modules'
12
- MAGIC_MARKER = '@PDQTest'
13
- MAGIC_MARKER_RE = /#\s*#{MAGIC_MARKER}/
14
- BATS_TESTS = './spec/acceptance'
15
- SETUP_SUFFIX = '__setup.sh'
16
- BEFORE_SUFFIX = '__before.bats'
17
- AFTER_SUFFIX = '.bats'
18
- EXAMPLES_DIR = './examples'
19
- MANIFESTS_DIR = './manifests'
12
+
13
+ #
14
+ # platform paths
15
+ #
16
+ CONTAINER_PATHS = {
17
+ :windows => {
18
+ :hiera_yaml => 'C:\\ProgramData\\PuppetLabs\\puppet\\etc\\hiera.yaml',
19
+ :hiera_dir => 'C:\\spec\\fixtures\\hieradata',
20
+ :module_dir => 'C:\\ProgramData\\PuppetLabs\\code\\modules',
21
+ :facts_dir => 'C:\\ProgramData\\PuppetLabs\\facter\\facts.d',
22
+ },
23
+ :linux => {
24
+ :hiera_yaml => '/etc/puppetlabs/puppet/hiera.yaml',
25
+ :yum_cache => "/var/cache/yum",
26
+ :hiera_dir => '/spec/fixtures/hieradata',
27
+ :module_dir => '/etc/puppetlabs/code/modules',
28
+ :facts_dir => '/etc/puppetlabs/facter/facts.d',
29
+ }
30
+ }
31
+
32
+ # path for common things on the *host* computer running pdqtest (vm, laptop, etc)
33
+ HOST_PATHS = {
34
+ :windows => {
35
+ :hiera_yaml => 'spec\\fixtures\\hiera.yaml',
36
+ :hiera_dir => 'spec\\fixtures\\hieradata',
37
+ :default_facts => 'spec\\default_facts.yml',
38
+ },
39
+ :linux => {
40
+ :hiera_yaml => 'spec/fixtures/hiera.yaml',
41
+ :hiera_dir => 'spec/fixtures/hieradata',
42
+ :default_facts => 'spec/default_facts.yml',
43
+ }
44
+ }
45
+
46
+
47
+ SETTINGS = {
48
+ :windows => {
49
+ :magic_marker => '@PDQTestWin',
50
+ :setup_suffix => '__setup.ps1',
51
+ :before_suffix => '__before.pats',
52
+ :after_suffix => '.pats',
53
+ :magic_marker_re => /#\s*@PDQTestWin\s$*/,
54
+ :name => "pats",
55
+ :test_cmd => "pats.ps1",
56
+ :puppet => "puppet.bat",
57
+ },
58
+ :linux => {
59
+ :magic_marker => '@PDQTest',
60
+ :setup_suffix => '__setup.sh',
61
+ :before_suffix =>'__before.bats',
62
+ :after_suffix => '.bats',
63
+ :magic_marker_re => /#\s*@PDQTest\s$*/,
64
+ :name => "bats",
65
+ :test_cmd => "bats",
66
+ :puppet => "puppet",
67
+ },
68
+ }
69
+
70
+ #
71
+ # statics
72
+ #
73
+ XATS_TESTS = Util.joinp('spec', 'acceptance')
74
+ EXAMPLES_DIR = 'examples'
75
+ MANIFESTS_DIR = 'manifests'
20
76
  CLASS_RE = /^class /
77
+ FIXTURES = '.fixtures.yml'
78
+ TMP_PUPPETFILE = '.Puppetfile.pdqtest'
79
+ METADATA = 'metadata.json'
80
+
81
+
82
+ #
83
+ # state
84
+ #
21
85
  @@bats_executed = []
22
86
  @@setup_executed = []
23
87
  @@skip_second_run = false
24
- FIXTURES = 'fixtures.yml'
25
- TMP_PUPPETFILE = '.Puppetfile.pdqtest'
26
88
 
89
+ def self.cp(key)
90
+ CONTAINER_PATHS[Util.host_platform][key] ||
91
+ raise("missing variable CONTAINER_PATHS[#{Util.host_platform}][#{key}]")
92
+ end
93
+
94
+ def self.hp(key)
95
+ HOST_PATHS[Util.host_platform][key] ||
96
+ raise("missing variable HOST_PATHS[#{Util.host_platform}][#{key}]")
97
+ end
98
+
99
+ def self.setting(key)
100
+ SETTINGS[Util.host_platform][key] ||
101
+ raise("missing variable SETTINGS[#{Util.host_platform}][#{key}]")
102
+ end
27
103
 
28
104
  def self.skip_second_run(skip_second_run)
29
105
  @@skip_second_run = skip_second_run
@@ -46,8 +122,18 @@ module PDQTest
46
122
  end
47
123
 
48
124
  def self.module_metadata
49
- file = File.read(Dir.pwd + File::SEPARATOR + METADATA)
50
- JSON.parse(file)
125
+ if File.exist? METADATA
126
+ file = File.read(METADATA)
127
+ JSON.parse(file)
128
+ else
129
+ raise("Puppet metadata not found at #{METADATA} - not a valid puppet module")
130
+ end
131
+ end
132
+
133
+ def self.save_module_metadata(metadata)
134
+ File.open(METADATA,"w") do |f|
135
+ f.write(JSON.pretty_generate(metadata))
136
+ end
51
137
  end
52
138
 
53
139
  def self.module_name
@@ -58,38 +144,75 @@ module PDQTest
58
144
  module_metadata['operatingsystem_support'] || []
59
145
  end
60
146
 
61
- def self.link_module
62
- "test -e #{MODULE_DIR} || mkdir -p #{MODULE_DIR} && ln -s #{PDQTest::Instance::TEST_DIR} #{MODULE_DIR}/#{module_name}"
63
- end
64
147
 
65
- # Link all modules - this also saves re-downloading in the acceptance test
66
- # environment. Of course it means that you must have already run `make` to
67
- # download the modules on your host computer
68
- def self.link_deps
69
- "test -e #{MODULE_DIR} || mkdir -p #{MODULE_DIR} && ln -s #{PDQTest::Instance::TEST_DIR}/spec/fixtures/modules/* #{MODULE_DIR}"
70
- end
71
148
 
72
- # link /etc/facter/facts.d to /testcase/spec/merge_facts to allow additional
73
- # facts supplied by user to work automatically
74
- def self.link_merge_facts
75
- "mkdir -p /etc/facter/ && ln -s #{PDQTest::Instance::TEST_DIR}/spec/merge_facts /etc/facter/facts.d"
149
+ # Regenerate .fixtures.yml from metadata
150
+ # https://github.com/puppetlabs/puppetlabs_spec_helper#using-fixtures
151
+ # The format looks like this:
152
+ #
153
+ # ```
154
+ # fixtures:
155
+ # forge_modules:
156
+ # stdlib:
157
+ # repo: "puppetlabs/stdlib"
158
+ # ref: "2.6.0"
159
+ #
160
+ # Note that ref doesn't accept a range like metadata.json does, but then
161
+ # r10k doesn't follow dependencies anyway so may as well just code a static
162
+ # known good working version in it and not worry ---> use a known good
163
+ # version for testing, not a range `metadata.json`
164
+ def self.fixtures_yml
165
+ fixtures = {
166
+ "fixtures" => {
167
+ "forge_modules" => {}
168
+ }
169
+ }
170
+ module_metadata["dependencies"].each do |dep|
171
+ forge_name = dep["name"]
172
+ puppet_name = dep["name"].split("-")[1]
173
+ ref = dep["version_requirement"]
174
+
175
+ fixtures["fixtures"]["forge_modules"][puppet_name] = {
176
+ "repo" => forge_name,
177
+ "ref" => ref,
178
+ }
179
+ end
180
+
181
+ # now we have our list of fixtures from `metadata.json`, merge it with any
182
+ # exiting .fixtures.yml content to preserve any git fixtures that may have
183
+ # been added manually. Clobber/update any existing content that is NOT
184
+ # from `metadata.json` while preserving things that are from git. If we
185
+ # have ended up declaring different versions of the same module then its
186
+ # up to user's to resolve this by removing the dependency from either
187
+ # `metadata.json` or `.fixtures.yml`. You shouldn't be depending on git
188
+ # resources in `metadata.json` anyway so this shoudln't be an issue
189
+ if File.exist?(FIXTURES)
190
+ existing_fixtures = YAML.load_file(FIXTURES)
191
+ existing_fixtures.deep_merge(fixtures)
192
+ fixtures = existing_fixtures
193
+ end
194
+
195
+ File.open(FIXTURES, 'w') { |f| YAML.dump(fixtures, f) }
76
196
  end
77
197
 
78
198
  def self.class2filename(c)
79
199
  if c == module_name
80
- f = "#{MANIFESTS_DIR}/init.pp"
200
+ f = "#{MANIFESTS_DIR}#{File::ALT_SEPARATOR||File::SEPARATOR}init.pp"
81
201
  else
82
- f = c.gsub(module_name, MANIFESTS_DIR).gsub('::', File::SEPARATOR) + '.pp'
202
+ f = c.gsub(module_name, MANIFESTS_DIR).gsub('::', (File::ALT_SEPARATOR||File::SEPARATOR)) + '.pp'
83
203
  end
84
204
 
85
205
  f
86
206
  end
87
207
 
88
208
  def self.filename2class(f)
89
- if f == "#{MANIFESTS_DIR}/init.pp"
209
+ # strip any leading `./`
210
+ f.sub!(/^\.\//,'')
211
+
212
+ if f == "#{MANIFESTS_DIR}#{File::ALT_SEPARATOR||File::SEPARATOR}init.pp"
90
213
  c = module_name
91
214
  else
92
- c = f.gsub(MANIFESTS_DIR, "#{module_name}").gsub(File::SEPARATOR, '::').gsub('.pp','')
215
+ c = f.gsub(MANIFESTS_DIR, "#{module_name}").gsub(File::ALT_SEPARATOR||File::SEPARATOR, '::').gsub('.pp','')
93
216
  end
94
217
 
95
218
  c
@@ -99,45 +222,15 @@ module PDQTest
99
222
  examples = []
100
223
  if Dir.exists?(EXAMPLES_DIR)
101
224
  Find.find(EXAMPLES_DIR) do |e|
102
- if ! File.directory?(e) and ! File.readlines(e).grep(MAGIC_MARKER_RE).empty?
225
+ if ! File.directory?(e) && ! File.readlines(e).grep(setting(:magic_marker_re)).empty?
103
226
  examples << e
104
227
  end
105
228
  end
106
229
  end
107
- Escort::Logger.output.puts "examples to run" + examples.to_s
230
+ $logger.info "examples to run" + examples.to_s
108
231
  examples
109
232
  end
110
233
 
111
- # process fixtures->repositories->* from fixtures.yml if present to
112
- # generate an array of commands to run ON THE DOCKER VM to checkout the
113
- # required modules from git
114
- def self.git_fixtures()
115
- refresh_cmd = []
116
- if File.exists?(FIXTURES)
117
- fixtures = YAML.load_file(FIXTURES)
118
- if fixtures.has_key?('repositories')
119
- fixtures['repositories'].each { |fixture, opts|
120
- target = "spec/fixtures/modules/#{fixture}"
121
- if opts.instance_of?(String)
122
- source = opts
123
- ref = 'master'
124
- elsif opts.instance_of?(Hash)
125
- source = opts['repo']
126
- if opts.has_key? 'ref'
127
- ref = opts['ref']
128
- else
129
- ref = 'master'
130
- end
131
- end
132
-
133
- refresh_cmd << "git_refresh refresh --target-dir #{target} --source-url #{source} --ref #{ref}"
134
- }
135
- end
136
- end
137
-
138
- refresh_cmd
139
- end
140
-
141
234
  # find the available classes in this module
142
235
  def self.find_classes()
143
236
  mod_name = module_name
@@ -150,7 +243,7 @@ module PDQTest
150
243
  # Class detected, work out class name and add to list of found classes
151
244
  classes << filename2class(m)
152
245
  else
153
- Escort::Logger.output.puts "no puppet class found in #{m}"
246
+ $logger.info "no puppet class found in #{m}"
154
247
  end
155
248
  end
156
249
  end
@@ -160,22 +253,23 @@ module PDQTest
160
253
  end
161
254
 
162
255
  def self.test_basename(t)
256
+ # remove any leading `./`
257
+ t.sub!(/^\.\//, '')
163
258
  # remove examples/ and .pp
164
259
  # eg ./examples/apache/mod/mod_php.pp --> apache/mod/mod_php
165
-
166
260
  t.gsub(EXAMPLES_DIR + '/','').gsub('.pp','')
167
261
  end
168
262
 
169
- def self.bats_test(container, example, suffix)
170
- testcase = BATS_TESTS + '/' + test_basename(example) + suffix
263
+ def self.xats_test(container, example, suffix)
264
+ testcase = Util.joinp(XATS_TESTS, test_basename(example) + suffix)
171
265
  if File.exists?(testcase)
172
- Escort::Logger.output.puts "*** bats test **** bats #{PDQTest::Instance::TEST_DIR}/#{testcase}"
173
- res = PDQTest::Docker.exec(container, "bats #{PDQTest::Instance::TEST_DIR}/#{testcase}")
266
+ $logger.info "*** #{setting(:name)} test **** #{setting(:test_cmd)} #{testcase}"
267
+ res = PDQTest::Docker.exec(container, "cd #{Docker.test_dir} ; #{setting(:test_cmd)} #{testcase}")
174
268
  status = PDQTest::Docker.exec_status(res)
175
269
  PDQTest::Docker.log_out(res)
176
270
  @@bats_executed << testcase
177
271
  else
178
- Escort::Logger.error.error "no #{suffix} tests for #{example} (should be at #{testcase})"
272
+ $logger.info "no #{suffix} tests for #{example} (should be at #{testcase})"
179
273
  status = true
180
274
  end
181
275
 
@@ -183,17 +277,22 @@ module PDQTest
183
277
  end
184
278
 
185
279
  def self.setup_test(container, example)
186
- setup = BATS_TESTS + '/' + test_basename(example) + SETUP_SUFFIX
187
- if File.exists?(setup)
188
- Escort::Logger.output.puts "Setting up test for #{example}"
189
- script = File.read(setup)
190
- res = PDQTest::Docker.exec(container, script)
191
- status = PDQTest::Docker.exec_status(res)
192
- PDQTest::Docker.log_out(res)
280
+ setup_script = Util.joinp(XATS_TESTS, test_basename(example)) + setting(:setup_suffix)
281
+ if File.exists?(setup_script)
282
+ script = File.read(setup_script)
283
+
284
+ if script =~ /^\s*$/
285
+ $logger.info "skipping empty setup script at #{setup_script}"
286
+ else
287
+ $logger.info "Setting up test for #{example}"
193
288
 
194
- @@setup_executed << setup
289
+ res = PDQTest::Docker.exec(container, script)
290
+ status = PDQTest::Docker.exec_status(res)
291
+ PDQTest::Docker.log_out(res)
292
+ end
293
+ @@setup_executed << setup_script
195
294
  else
196
- Escort::Logger.output.puts "no setup file for #{example} (should be in #{setup})"
295
+ $logger.info "no setup file for #{example} (should be in #{setup_script})"
197
296
  status = true
198
297
  end
199
298
 
@@ -201,18 +300,13 @@ module PDQTest
201
300
  end
202
301
 
203
302
  def self.run_example(container, example)
204
- if ! example.start_with?('./')
205
- # must prepend ./ to the example or we will not match the correct regexp
206
- # in test_basename
207
- example = "./#{example}"
208
- end
209
- Escort::Logger.output.puts "testing #{example}"
303
+ $logger.info "testing #{example}"
210
304
  status = false
211
305
 
212
306
  if setup_test(container, example)
213
307
 
214
308
  # see if we should run a bats test before running puppet
215
- if bats_test(container, example, BEFORE_SUFFIX)
309
+ if xats_test(container, example, setting(:before_suffix))
216
310
 
217
311
  # run puppet apply - 1st run
218
312
  res = PDQTest::Docker.exec(container, puppet_apply(example))
@@ -220,10 +314,10 @@ module PDQTest
220
314
  if PDQTest::Docker.exec_status(res, true) # allow 2 as exit status
221
315
 
222
316
  if @@skip_second_run
223
- Escort::Logger.output.puts "Skipping idempotency check as you requested..."
317
+ $logger.info "Skipping idempotency check as you requested..."
224
318
 
225
319
  # check the system right now since puppet ran OK once
226
- status = bats_test(container, example, AFTER_SUFFIX)
320
+ status = xats_test(container, example, setting(:after_suffix))
227
321
  else
228
322
  # run puppet apply - 2nd run (check for idempotencey/no more changes)
229
323
  res = PDQTest::Docker.exec(container, puppet_apply(example))
@@ -231,19 +325,19 @@ module PDQTest
231
325
 
232
326
  # run the bats test if nothing failed yet
233
327
  if PDQTest::Docker.exec_status(res) # only allow 0 as exit status
234
- status = bats_test(container, example, AFTER_SUFFIX)
328
+ status = xats_test(container, example, setting(:after_suffix))
235
329
  else
236
- Escort::Logger.error.error "Not idempotent: #{example}"
330
+ $logger.error "Not idempotent: #{example}"
237
331
  end
238
332
  end
239
333
  else
240
- Escort::Logger.error.error "First puppet run of #{example} failed"
334
+ $logger.error "First puppet run of #{example} failed (status: #{res[Docker::STATUS]})"
241
335
  end
242
336
  else
243
- Escort::Logger.error.error "Bats tests to run before #{example} failed"
337
+ $logger.error "#{setting(:name)} tests to run before #{example} failed (status: #{res[Docker::STATUS]})"
244
338
  end
245
339
  else
246
- Escort::Logger.error.error "Setup script for #{example} failed"
340
+ $logger.error "Setup script for #{example} failed (see previous error)"
247
341
  end
248
342
 
249
343
  status
@@ -254,68 +348,64 @@ module PDQTest
254
348
  # symlink back to the main module inside here...
255
349
  # (spec/fixtures/modules/foo -> /testcase)
256
350
  if ! Dir.exists?('spec/fixtures/modules')
257
- Escort::Logger.output.puts
351
+ $logger.info
258
352
  "creating empty spec/fixtures/modules, if you module fails to run due "
259
353
  "to missing dependencies run `make` or `pdqtest all` to retrieve them"
260
354
  FileUtils.mkdir_p('spec/fixtures/modules')
261
355
  end
262
356
 
263
357
  status = true
264
- Escort::Logger.output.puts "...linking dependencies"
265
- cmd = link_deps
266
- res = PDQTest::Docker.exec(container, cmd)
358
+ $logger.info "...running container setup"
359
+ setup_start = Time.now
360
+ res = PDQTest::Docker.exec(container, setup)
361
+ setup_end = Time.now
267
362
  status &= PDQTest::Docker.exec_status(res)
363
+ if Util.is_windows
364
+ # write a script to allow user to update modules
365
+ $logger.info "wasted #{((setup_end - setup_start))} seconds of your life on windows tax"
366
+ File.open("refresh.ps1", 'w') do |file|
367
+ res[Docker::REAL_CMD].each do |c|
368
+ file.puts("#{c[0]} #{c[1]} \"#{c[2]}\"")
369
+ end
370
+ end
371
+ Emoji.emoji_message(
372
+ :shame,
373
+ "run refresh.ps1 to update container after changing files on host!",
374
+ ::Logger::WARN)
375
+ end
268
376
  if status
269
- Escort::Logger.output.puts "...linking testcase (this module)"
270
- cmd = link_module
271
- res = PDQTest::Docker.exec(container, cmd)
272
- status &= PDQTest::Docker.exec_status(res)
273
- if status
274
- Escort::Logger.output.puts "...linking spec/merge_facts"
275
- cmd = link_merge_facts
276
- res = PDQTest::Docker.exec(container, cmd)
277
- status &= PDQTest::Docker.exec_status(res)
278
- if status
279
- Escort::Logger.output.puts "...run tests"
280
- if example
281
- status &= run_example(container, example)
282
- if ! status
283
- Escort::Logger.error.error "Example #{example} failed!"
284
- end
285
- else
286
- find_examples.each { |e|
287
- if status
288
- status &= run_example(container, e)
289
- if ! status
290
- Escort::Logger.error.error "Example #{e} failed! - skipping rest of tests"
291
- end
292
- end
293
- }
377
+ $logger.info "...run tests"
378
+ if example
379
+ status &= run_example(container, example)
380
+ if ! status
381
+ $logger.error "Example #{example} failed!"
294
382
  end
295
383
  else
296
- PDQTest::Docker.log_all(res)
297
- Escort::Logger.error.error "Error linking ./spec/merge_facts directory, see previous error, command was: #{cmd}"
384
+ find_examples.each { |e|
385
+ if status
386
+ status &= run_example(container, e)
387
+ if ! status
388
+ $logger.error "Example #{e} failed! - skipping rest of tests"
389
+ end
390
+ end
391
+ }
298
392
  end
299
- else
300
- PDQTest::Docker.log_all(res)
301
- Escort::Logger.error.error "Error linking testcase (this) module, see previous error, command was: #{cmd}"
302
- end
303
393
  else
304
394
  PDQTest::Docker.log_all(res)
305
- Escort::Logger.error.error "Error linking module, see previous error, command was: #{cmd}"
395
+ $logger.error "Error running puppet setup, see previous error, command was: #{res[Docker::REAL_CMD]}"
306
396
  end
307
397
 
308
398
  PDQTest::Emoji.partial_status(status, 'Puppet')
309
399
  status
310
400
  end
311
401
 
402
+
312
403
  def self.puppet_apply(example)
313
- "cd #{PDQTest::Instance::TEST_DIR} && puppet apply --detailed-exitcodes #{example}"
404
+ "cd #{Docker.test_dir} ; #{setting(:puppet)} apply --detailed-exitcodes #{example}"
314
405
  end
315
406
 
316
407
  def self.info
317
- Escort::Logger.output.puts "Parsed module name: #{module_name}"
318
- Escort::Logger.output.puts "Link module command: #{link_module}"
408
+ $logger.info "Parsed module name: #{module_name}"
319
409
  end
320
410
 
321
411
  # extract a Puppetfile from metadata.json and install modules using r10k
@@ -340,16 +430,69 @@ module PDQTest
340
430
  f.puts(puppetfile)
341
431
  end
342
432
 
343
- PDQTest::Emoji.emoji_message("🐌", "I'm downloading The Internet, please hold...")
433
+ PDQTest::Emoji.emoji_message(:slow, "I'm downloading The Internet, please hold...")
344
434
 
345
435
  cmd = "bundle exec r10k puppetfile install --verbose --moduledir ./spec/fixtures/modules --puppetfile #{TMP_PUPPETFILE}"
346
436
  status = system(cmd)
347
437
 
348
438
  if ! status
349
- Escort::Logger.error.error "Failed to run the R10K command: #{cmd}"
439
+ $logger.error "Failed to run the R10K command: #{cmd}"
350
440
  end
351
441
 
352
442
  status
353
443
  end
444
+
445
+ def self.setup
446
+ commands = []
447
+
448
+ # link testcase module
449
+ commands << Util.mk_link(
450
+ Util.joinp(cp(:module_dir), module_name),
451
+ PDQTest::Docker.test_dir
452
+ )
453
+
454
+
455
+ # link dependency modules
456
+ sfm = Util.joinp("spec", "fixtures", "modules")
457
+ if ! File.exist? sfm
458
+ raise("Modules directory does not exist - please run unit tests first to create it")
459
+ end
460
+ Dir.entries(sfm).select { |entry|
461
+ File.directory?(Util.joinp(sfm, entry)) && !(entry =='.' || entry == '..')
462
+ }.reject { |entry|
463
+ # do not copy the symlink of ourself (pdk creates it)
464
+ entry == module_name
465
+ }.each { |entry|
466
+ commands << Util.mk_link(
467
+ Util.joinp(cp(:module_dir), entry),
468
+ Util.joinp(PDQTest::Docker.test_dir, sfm, entry)
469
+ )
470
+ }
471
+
472
+
473
+ # link hieradata
474
+ if Dir.exist? hp(:hiera_dir)
475
+ commands << Util.mk_link(
476
+ cp(:hiera_dir),
477
+ Util.joinp(Docker.test_dir, hp(:hiera_dir))
478
+ )
479
+ end
480
+
481
+ # link hiera.yaml
482
+ if File.exist? hp(:hiera_yaml)
483
+ commands << Util.mk_link(
484
+ cp(:hiera_yaml),
485
+ Util.joinp(Docker.test_dir, hp(:hiera_yaml))
486
+ )
487
+ end
488
+
489
+ # link external facts
490
+ commands << Util.mk_link(
491
+ Util.joinp(cp(:facts_dir), File.basename(hp(:default_facts))),
492
+ Util.joinp(Docker.test_dir, hp(:default_facts))
493
+ )
494
+ commands
495
+
496
+ end
354
497
  end
355
498
  end