puppetbox 0.4.1 → 0.4.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6e98bf1892a07fa686429fd852a495629ebfde34
4
- data.tar.gz: 34175eff6de51aefee73c7e22af3168ba131311c
3
+ metadata.gz: bd53bc360e5558df6c0eb16ffce3ab13b0d21e48
4
+ data.tar.gz: 120393a564d129bf93a89bc35d378c6ec830dd04
5
5
  SHA512:
6
- metadata.gz: b556b35aecb7a91ef65c2a34b9ce4e3e10ee6ec5fdf4354ed9e0e09461af5f8970b91405fef116aac92b429238e9afed998b92d6f98fad3fac23cbe871b04fbc
7
- data.tar.gz: ce27a46a8dc3629fc82b60db99627a94433f160b2427d096c82d94af3b4626d39b383ce967b676e0491ebf28242f7958bfd84f4884bbb9755afba05a22b7665d
6
+ metadata.gz: dd0bcf8e48b6c0451de2aec7c73b4d4e0acba8418c3ad0945cbd7af20efec1c5fa9f51006a15929c2dd979728dec9c0040038400019b42690143da2831122310
7
+ data.tar.gz: 7fe318dc03b0a0e61c78509ebc014af8d8869cfc19bd858521295ad1dee8f026c44a2d5c31b16b584e6fb51e40a775db8abdb62f173ed82eaba77b71d5632e02
@@ -9,8 +9,11 @@ module PuppetBox
9
9
  WORKING_DIR_VAGRANT = "vagrant"
10
10
  PUPPET_CODE_MOUNT = "/etc/puppetlabs/code/environments/production"
11
11
 
12
- # mount spec/accpetance into the same directory name inside the VM for simplicity
13
- SPEC_ACCEPTANCE_MOUNT = "spec/acceptance:/spec/acceptance"
12
+ # mount spec/ into the same directory name inside the VM for simplicity -
13
+ # now we can easility access fixtures, tests, etc
14
+ SPEC_ACCEPTANCE_MOUNT = "spec:/spec"
15
+
16
+ PUPPET_TESTCASE_DIR = "/testcase"
14
17
 
15
18
  def node_name
16
19
  @name
@@ -18,15 +21,17 @@ module PuppetBox
18
21
 
19
22
  def initialize(name, codedir, config, keep_vm:false, working_dir:nil, logger: nil)
20
23
 
21
- @name = name
22
- @keep_vm = keep_vm
23
- @working_dir = File.join((working_dir || PuppetBox::WORKING_DIR), WORKING_DIR_VAGRANT)
24
- @config = config
25
- @result = Result.new
26
- @logger = Logger.new(logger).logger
24
+ @name = name
25
+ @keep_vm = keep_vm
26
+ @working_dir = working_dir || PuppetBox::WORKING_DIR
27
+ @vagrant_vm_dir = File.join(@working_dir, WORKING_DIR_VAGRANT)
28
+ @testcase_dir = File.join(@working_dir, PUPPET_TESTCASE_DIR)
29
+ @config = config
30
+ @result = Result.new
31
+ @logger = Logger.new(logger).logger
27
32
 
28
33
  # setup the instance
29
- @vom = Vagrantomatic::Vagrantomatic.new(vagrant_vm_dir:@working_dir, logger:@logger)
34
+ @vom = Vagrantomatic::Vagrantomatic.new(vagrant_vm_dir:@vagrant_vm_dir, logger:@logger)
30
35
  @logger.debug("creating instance metadata for #{@name}")
31
36
  @vm = @vom.instance(@name, config:@config)
32
37
 
@@ -36,6 +41,10 @@ module PuppetBox
36
41
  # ./spec/acceptance directory
37
42
  @vm.add_shared_folder(SPEC_ACCEPTANCE_MOUNT)
38
43
 
44
+ # mount the temporary testcase files (smoketests - the generated files
45
+ # holding 'include apache', etc)
46
+ @vm.add_shared_folder("#{@testcase_dir}:#{PUPPET_TESTCASE_DIR}")
47
+
39
48
  @logger.debug "instance #{name} initialised"
40
49
  end
41
50
 
@@ -52,9 +61,9 @@ module PuppetBox
52
61
  # 2: The run succeeded, and some resources were changed.
53
62
  # 4: The run succeeded, and some resources failed.
54
63
  # 6: The run succeeded, and included both changes and failures.
55
- def run_puppet(puppet_class)
64
+ def run_puppet(puppet_file)
56
65
  status_code, messages = @vm.run(
57
- "sudo -i puppet apply --detailed-exitcodes -e 'include #{puppet_class}'"
66
+ "sudo -i puppet apply --detailed-exitcodes #{puppet_file}"
58
67
  )
59
68
  @result.save(status_code, messages)
60
69
  @result.passed?
@@ -64,6 +73,8 @@ module PuppetBox
64
73
  def open()
65
74
  # make sure working dir exists...
66
75
  FileUtils.mkdir_p(@working_dir)
76
+ FileUtils.mkdir_p(@vagrant_vm_dir)
77
+ FileUtils.mkdir_p(@testcase_dir)
67
78
  @vm.save
68
79
 
69
80
  @logger.debug("Instance saved and ready for starting")
@@ -73,13 +84,17 @@ module PuppetBox
73
84
  # Close a connection to a box (eg stop a vm, probaly doesn't need to do
74
85
  # anything on SSH...)
75
86
  def close()
76
- if ! @keep_vm
87
+ if @keep_vm
88
+ vagrant_cmd = "cd #{@vm.vm_instance_dir} && vagrant ssh"
89
+ @logger.info("VM #{@name} left running on user request, `#{vagrant_cmd}` to access - be sure to clean up your VMs!")
90
+ else
77
91
  @logger.info("Closing #{@name}")
78
92
  @vm.purge
79
93
  end
80
94
  end
81
95
 
82
96
  def reset()
97
+ @result = Result.new
83
98
  @vm.reset
84
99
  end
85
100
 
@@ -126,16 +141,20 @@ module PuppetBox
126
141
  status
127
142
  end
128
143
 
129
- def run_puppet_x2(puppet_class)
144
+ def run_puppet_x2(puppet_file)
130
145
  # if you need to link a module into puppet's modulepath either do it
131
146
  # before running puppet (yet to be supported) or use the @config hash
132
147
  # for vagrant to mount what you need as a shared folder
133
- if run_puppet(puppet_class)
148
+ if run_puppet(puppet_file)
134
149
  # Only do the second run if the first run passes
135
- run_puppet(puppet_class)
150
+ run_puppet(puppet_file)
136
151
  end
137
152
  end
138
153
 
154
+ # noop
155
+ def sync_testcase(node_name, test_name)
156
+ end
157
+
139
158
  end
140
159
  end
141
160
 
@@ -0,0 +1,12 @@
1
+ module PuppetBox
2
+ module Puppet
3
+ def self.include_class(class_name, pre:nil)
4
+ if pre
5
+ # apply a prerequisite and make sure there is a trailing newline. this
6
+ # will be eval'ed directly so make sure there are no mad characters
7
+ pre = "#{pre}\n"
8
+ end
9
+ "#{pre}include #{class_name}"
10
+ end
11
+ end
12
+ end
@@ -3,6 +3,8 @@ require "puppetbox/logger"
3
3
  require "puppetbox/nodeset"
4
4
  require "puppetbox/driver/vagrant"
5
5
  require "puppetbox/report"
6
+ require "puppetbox/puppet"
7
+ require "puppetbox/util"
6
8
 
7
9
  module PuppetBox
8
10
  class PuppetBox
@@ -12,7 +14,14 @@ module PuppetBox
12
14
  ACCEPTANCE_DEFAULT = "__ALL__"
13
15
  SETUP_SCRIPT_GLOB = "setup.*"
14
16
 
15
- def initialize(logger:nil, nodeset_file: nil, working_dir: nil)
17
+ # we write testcases (smoketests) to this directory in our working dir...
18
+ PUPPET_TESTCASE_TEMPDIR = "testcase"
19
+
20
+ # ...and they appear on the system under test at this directory (like a
21
+ # wormhole) - the driver class is responsible for making this happen
22
+ PUPPET_TESTCASE_DIR = "/testcase"
23
+
24
+ def initialize(logger:nil, nodeset_file: nil, working_dir: nil, keep_test_system:false)
16
25
  # The results of all tests on all driver instances
17
26
  @result_set = ResultSet.new
18
27
 
@@ -28,19 +37,24 @@ module PuppetBox
28
37
  @nodeset = NodeSet.new(nodeset_file)
29
38
 
30
39
  @working_dir = working_dir || WORKING_DIR
40
+ @puppet_test_tempdir = File.join(@working_dir, PUPPET_TESTCASE_TEMPDIR)
41
+
42
+ @keep_test_system = keep_test_system
31
43
  end
32
44
 
33
45
 
34
46
  # Enqueue a test into the `testsuite` for
35
- def enqueue_test(node_name, run_from, puppet_class)
47
+ def enqueue_test_class(node_name, run_from, puppet_class, pre:nil)
36
48
  instantiate_driver(node_name, run_from)
37
- @testsuite[node_name]["classes"] << puppet_class
38
-
49
+ # eg @testsuite['centos']['apache']='include apache'
50
+ test_name=puppet_class
51
+ @testsuite[node_name]["tests"][test_name] = Puppet::include_class(puppet_class, pre:pre)
39
52
  end
40
53
 
41
54
  def run_testsuite
42
55
  @testsuite.each { |id, tests|
43
- run_puppet(tests["instance"], tests["classes"], logger:@logger, reset_after_run:true)
56
+ # tests for each node
57
+ run_puppet(tests["instance"], tests["tests"], logger:@logger, reset_after_run:true)
44
58
  }
45
59
  end
46
60
 
@@ -75,6 +89,7 @@ module PuppetBox
75
89
  # "#{repo.tempdir}/etc/puppetlabs/code/environments/production",
76
90
  logger: @logger,
77
91
  working_dir: @working_dir,
92
+ keep_vm: @keep_test_system
78
93
  )
79
94
 
80
95
  # immediately validate the configuration to allow us to fail-fast
@@ -85,7 +100,7 @@ module PuppetBox
85
100
 
86
101
  @testsuite[node_name] = {
87
102
  "instance" => di,
88
- "classes" => [],
103
+ "tests" => {},
89
104
  }
90
105
  end
91
106
  end
@@ -155,32 +170,42 @@ module PuppetBox
155
170
  end
156
171
  end
157
172
 
158
- # Run puppet using `driver_instance` to execute
159
- def run_puppet(driver_instance, puppet_classes, logger:nil, reset_after_run:true)
173
+
174
+ # Run puppet using `driver_instance` to execute `puppet_codes`
175
+ # @param puppet_test Hash of test names <-> puppet code, eg {"apache"=>"include apache","nginx"=>"include nginx"}}
176
+ def run_puppet(driver_instance, puppet_tests, logger:nil, reset_after_run:true)
160
177
  # use supplied logger in preference to the default puppetbox logger instance
161
178
  logger = logger || @logger
162
- logger.debug("#{driver_instance.node_name} running test for #{puppet_classes}")
163
- puppet_classes = Array(puppet_classes)
179
+ logger.debug("#{driver_instance.node_name} running #{puppet_tests.size} tests")
164
180
 
165
181
  if driver_instance.open
166
182
  logger.debug("#{driver_instance.node_name} started")
167
183
  if driver_instance.self_test
168
184
  logger.debug("#{driver_instance.node_name} self_test OK, running puppet")
169
- puppet_classes.each { |puppet_class|
185
+ puppet_tests.each { |test_name, puppet_code|
170
186
  if @result_set.class_size(driver_instance.node_name) > 0 and reset_after_run
171
187
  # purge and reboot the vm - this will save approximately 1 second
172
188
  # per class on the self-test which we now know will succeed
173
189
  driver_instance.reset
174
190
  end
175
- setup_test(driver_instance, puppet_class)
176
- logger.info("running test #{driver_instance.node_name} - #{puppet_class}")
177
- driver_instance.run_puppet_x2(puppet_class)
178
- @result_set.save(driver_instance.node_name, puppet_class, driver_instance.result)
191
+ setup_test(driver_instance, test_name)
192
+ logger.info("running test #{driver_instance.node_name} - #{test_name}")
193
+
194
+ # write out the local test file
195
+ relative_puppet_file = commit_testcase(
196
+ puppet_tests, driver_instance.node_name, test_name
197
+ )
198
+ driver_instance.sync_testcase(driver_instance.node_name, test_name)
199
+
200
+ puppet_file_remote = File.join(PUPPET_TESTCASE_DIR, relative_puppet_file)
201
+ driver_instance.run_puppet_x2(puppet_file_remote)
202
+ @logger.debug("Saved result #{driver_instance.node_name} #{test_name} #{driver_instance.result.passed?}")
203
+ @result_set.save(driver_instance.node_name, test_name, driver_instance.result)
179
204
 
180
205
  Report::log_test_result_or_errors(
181
206
  @logger,
182
207
  driver_instance.node_name,
183
- puppet_class,
208
+ test_name,
184
209
  driver_instance.result,
185
210
  )
186
211
  }
@@ -195,5 +220,19 @@ module PuppetBox
195
220
  driver_instance.close
196
221
  end
197
222
 
223
+ #
224
+ #@param testcases Pass in directly the testcases we are working against, to
225
+ # handle situations where `run_puppet()` was called directly
226
+ def commit_testcase(testcases, node_name, test_name)
227
+ puppet_code = testcases[test_name]
228
+ relative_filename = Util.test_file_name(node_name, test_name)
229
+ filename = File.join(@puppet_test_tempdir, relative_filename)
230
+ FileUtils.mkdir_p(File.dirname(filename))
231
+ File.write(filename, puppet_code)
232
+ @logger.debug("Saved testcase #{filename}: #{puppet_code.slice(0,50)}...(ellipsed)")
233
+
234
+ relative_filename
235
+ end
236
+
198
237
  end
199
238
  end
@@ -0,0 +1,13 @@
1
+ module PuppetBox
2
+ module Util
3
+
4
+
5
+ # return the filename that a testcase for a particular test should live in
6
+ # eg node_name=centos7, test_name=role::base should be in centos7/role__base.pp
7
+ def self.test_file_name(node_name, test_name)
8
+ test_name_safe = test_name.gsub(/::/,'__')
9
+ File.join(node_name, "#{test_name_safe}.pp")
10
+ end
11
+
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module PuppetBox
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.2"
3
3
  end
data/puppetbox.gemspec CHANGED
@@ -23,6 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
24
  spec.add_development_dependency "rspec", "~> 3.0"
25
25
 
26
- spec.add_dependency "vagrantomatic", "0.3.2"
26
+ spec.add_dependency "vagrantomatic", "0.3.3"
27
27
  spec.add_dependency "colorize"
28
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppetbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geoff Williams
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-04-16 00:00:00.000000000 Z
11
+ date: 2017-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 0.3.2
61
+ version: 0.3.3
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 0.3.2
68
+ version: 0.3.3
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: colorize
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -101,10 +101,12 @@ files:
101
101
  - lib/puppetbox/driver/vagrant.rb
102
102
  - lib/puppetbox/logger.rb
103
103
  - lib/puppetbox/nodeset.rb
104
+ - lib/puppetbox/puppet.rb
104
105
  - lib/puppetbox/puppetbox.rb
105
106
  - lib/puppetbox/report.rb
106
107
  - lib/puppetbox/result.rb
107
108
  - lib/puppetbox/result_set.rb
109
+ - lib/puppetbox/util.rb
108
110
  - lib/puppetbox/version.rb
109
111
  - puppetbox.gemspec
110
112
  homepage: https://github.com/GeoffWilliams/puppetbox