puppetbox 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
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