puppet_litmus 0.17.0 → 0.18.0

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
  SHA256:
3
- metadata.gz: c81ccd0186b54db2eb71534a0cc10e5191e1b6103201e8ef44231cc017cf5faa
4
- data.tar.gz: dd027dff77884a4b09b66447c966c3636a2cf237e21c1b4f0ec1d28182188937
3
+ metadata.gz: b57432738dbfa9e3c83c891565286c43703437df4d4b8f3a1c09431012dd869d
4
+ data.tar.gz: 7d4213842c29f689b943dea1a89fc1ea5c4cda272a67fad70c2d55a9b74114a8
5
5
  SHA512:
6
- metadata.gz: 38db1fa85c7ca655540aad80563bd095c8de46b492e618541a9dbd42b4a9305447ce2538c4ed30882f87582f4a21ebac7d0a1352288f3920d33b42af4d53fa4d
7
- data.tar.gz: 849c989f388d9b1b4dde8a44a2788657c015c50bbfb8ff399255d64c3390557bca7e319939134a2bb2918f3ffc48b0c59a27c29ab7d0779d480c07f9a392a3dc
6
+ metadata.gz: 01344ef395005540dc7ae2d109b19e6bf94064f0a27031e886c2f114cdaec8c33c6cbcd71c57a0c164b4724cc5014fb17b7b8ddf12220189f2e10bb22ead26b7
7
+ data.tar.gz: 4f6a4144f1785e618d40560463de94e874d03208c1a35ba2ca3d031752e9791b133466105f45b50e4ef59f0f12a3e0736e606d2140d0e517b63c633a0dd7aae6
data/README.md CHANGED
@@ -8,27 +8,23 @@
8
8
  </div>
9
9
 
10
10
  ## Overview
11
- Litmus provides a simple command line tool for Puppet content creators, to enable both simple and complex test deployments against specifically configured target systems. It is available as a gem, and can be installed by running ```gem install puppet_litmus```.
12
11
 
13
- Litmus allows Puppet module developers to:
14
- * provision targets to test against,
15
- * install the Puppet Agent,
16
- * install a module,
17
- * run tests, and
18
- * tear down the infrastructure.
12
+ Litmus is a command line tool that allows you to run acceptance tests against Puppet modules.
19
13
 
20
- The tool facilitates parallel test runs, running tests in isolation, and each step is standalone, allowing other operations between test runs, such as debugging, or configuration updates on the test targets.
14
+ Litmus allows you to:
15
+ * Provision targets to test against
16
+ * Install a Puppet agent
17
+ * Install a module
18
+ * Run tests
19
+ * Tear down the infrastructure
21
20
 
22
- ## Documentation
21
+ Litmus also facilitates parallel test runs and running tests in isolation. Each step is standalone, allowing other operations between test runs, such as debugging or configuration updates on the test targets.
22
+
23
+ Install Litmus as a gem by running ```gem install puppet_litmus```.
23
24
 
24
- All our documentation is currently available in the [Wiki](https://github.com/puppetlabs/puppet_litmus/wiki).
25
+ ## Documentation
25
26
 
26
- * [Overview](https://github.com/puppetlabs/puppet_litmus/wiki/Overview-of-Litmus) of the main functions
27
- * [Architecture](https://github.com/puppetlabs/puppet_litmus/wiki/Architecture-of-puppet-litmus) with an explanation of what's going on under the hood
28
- * [Step-by-step guide](https://github.com/puppetlabs/puppet_litmus/wiki/Tutorial:-use-Litmus-to-execute-acceptance-tests-with-a-sample-module-(MoTD)) of how to use Litmus with the popular and simple [MoTD Puppet module](https://forge.puppet.com/puppetlabs/motd).
29
- * [How to guide](https://github.com/puppetlabs/puppet_litmus/wiki/Converting-a-module-to-use-Litmus) walking through how to use Litmus in a module
30
- * [Helper functions](https://github.com/puppetlabs/puppet_litmus/wiki/Helper-Functions-for-Litmus) a guide to the various helper functions within Litmus.
31
- ## Known issues
27
+ For documentation, see our [Litmus Wiki](https://github.com/puppetlabs/puppet_litmus/wiki).
32
28
 
33
29
  ## Other Resources
34
30
 
data/lib/puppet_litmus.rb CHANGED
@@ -4,6 +4,7 @@
4
4
  module PuppetLitmus; end
5
5
 
6
6
  require 'bolt_spec/run'
7
+ require 'puppet_litmus/honeycomb_utils'
7
8
  require 'puppet_litmus/inventory_manipulation'
8
9
  require 'puppet_litmus/puppet_helpers'
9
10
  require 'puppet_litmus/rake_helper'
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PuppetLitmus; end # rubocop:disable Style/Documentation
4
+
5
+ # a set of semi-private utility functions that should not contaminate the global namespace
6
+ module PuppetLitmus::HoneycombUtils
7
+ module_function
8
+
9
+ def add_platform_field(inventory_hash, target_node_name)
10
+ facts = facts_from_node(inventory_hash, target_node_name)
11
+ Honeycomb.current_span.add_field('litmus.platform', facts&.dig('platform'))
12
+ end
13
+ end
@@ -37,7 +37,6 @@ module PuppetLitmus::InventoryManipulation
37
37
  'uri' => 'litmus_localhost',
38
38
  'config' => { 'transport' => 'local' },
39
39
  'feature' => 'puppet-agent',
40
- 'facts' => { 'platform' => 'localhost' },
41
40
  },
42
41
  ],
43
42
  },
@@ -32,6 +32,7 @@ module PuppetLitmus::PuppetHelpers
32
32
  # :manifest_file_location [Path] The place on the target system.
33
33
  # :hiera_config [Path] The path to the hiera.yaml configuration on the runner.
34
34
  # :prefix_command [String] prefixes the puppet apply command; eg "export LANGUAGE='ja'".
35
+ # :trace [Boolean] run puppet apply with the trace flag (defaults to `true`).
35
36
  # :debug [Boolean] run puppet apply with the debug flag.
36
37
  # :noop [Boolean] run puppet apply with the noop flag.
37
38
  # @yieldreturn [Block] this method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
@@ -48,6 +49,8 @@ module PuppetLitmus::PuppetHelpers
48
49
  raise 'please specify only one of `catch_changes`, `expect_changes`, `catch_failures` or `expect_failures`' if
49
50
  [opts[:catch_changes], opts[:expect_changes], opts[:catch_failures], opts[:expect_failures]].compact.length > 1
50
51
 
52
+ opts = { trace: true }.merge(opts)
53
+
51
54
  if opts[:catch_changes]
52
55
  use_detailed_exit_codes = true
53
56
  acceptable_exit_codes = [0]
@@ -70,9 +73,10 @@ module PuppetLitmus::PuppetHelpers
70
73
  raise "Target '#{target_node_name}' not found in inventory.yaml" unless target_in_inventory?(inventory_hash, target_node_name)
71
74
 
72
75
  span.add_field('litmus.node_name', target_node_name)
73
- span.add_field('litmus.platform', facts_from_node(inventory_hash, target_node_name)['platform'])
76
+ PuppetLitmus::HoneycombUtils.add_platform_field(inventory_hash, target_node_name)
74
77
 
75
78
  command_to_run = "#{opts[:prefix_command]} puppet apply #{manifest_file_location}"
79
+ command_to_run += ' --trace' if !opts[:trace].nil? && (opts[:trace] == true)
76
80
  command_to_run += " --modulepath #{Dir.pwd}/spec/fixtures/modules" if target_node_name == 'litmus_localhost'
77
81
  command_to_run += " --hiera_config='#{opts[:hiera_config]}'" unless opts[:hiera_config].nil?
78
82
  command_to_run += ' --debug' if !opts[:debug].nil? && (opts[:debug] == true)
@@ -84,9 +88,9 @@ module PuppetLitmus::PuppetHelpers
84
88
  bolt_result = run_command(command_to_run, target_node_name, config: nil, inventory: inventory_hash)
85
89
  span.add_field('litmus.bolt_result', bolt_result)
86
90
 
87
- result = OpenStruct.new(exit_code: bolt_result.first['result']['exit_code'],
88
- stdout: bolt_result.first['result']['stdout'],
89
- stderr: bolt_result.first['result']['stderr'])
91
+ result = OpenStruct.new(exit_code: bolt_result.first['value']['exit_code'],
92
+ stdout: bolt_result.first['value']['stdout'],
93
+ stderr: bolt_result.first['value']['stderr'])
90
94
  span.add_field('litmus.result', result.to_h)
91
95
 
92
96
  status = result.exit_code
@@ -129,12 +133,12 @@ module PuppetLitmus::PuppetHelpers
129
133
  # transfer to TARGET_HOST
130
134
  inventory_hash = inventory_hash_from_inventory_file
131
135
  span.add_field('litmus.node_name', target_node_name)
132
- span.add_field('litmus.platform', facts_from_node(inventory_hash, target_node_name)['platform'])
136
+ PuppetLitmus::HoneycombUtils.add_platform_field(inventory_hash, target_node_name)
133
137
 
134
138
  manifest_file_location = "/tmp/#{File.basename(manifest_file)}"
135
139
  bolt_result = upload_file(manifest_file.path, manifest_file_location, target_node_name, options: {}, config: nil, inventory: inventory_hash)
136
140
  span.add_field('litmus.bolt_result', bolt_result)
137
- raise bolt_result.first['result'].to_s unless bolt_result.first['status'] == 'success'
141
+ raise bolt_result.first['value'].to_s unless bolt_result.first['status'] == 'success'
138
142
  end
139
143
 
140
144
  span.add_field('litmus.manifest_file_location', manifest_file_location)
@@ -160,19 +164,19 @@ module PuppetLitmus::PuppetHelpers
160
164
  raise "Target '#{target_node_name}' not found in inventory.yaml" unless target_in_inventory?(inventory_hash, target_node_name)
161
165
 
162
166
  span.add_field('litmus.node_name', target_node_name)
163
- span.add_field('litmus.platform', facts_from_node(inventory_hash, target_node_name)['platform'])
167
+ PuppetLitmus::HoneycombUtils.add_platform_field(inventory_hash, target_node_name)
164
168
 
165
169
  bolt_result = run_command(command_to_run, target_node_name, config: nil, inventory: inventory_hash)
166
170
  span.add_field('litmus.bolt_result', bolt_result)
167
171
 
168
- if bolt_result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true
172
+ if bolt_result.first['value']['exit_code'] != 0 && opts[:expect_failures] != true
169
173
  raise "shell failed\n`#{command_to_run}`\n======\n#{bolt_result}"
170
174
  end
171
175
 
172
- result = OpenStruct.new(exit_code: bolt_result.first['result']['exit_code'],
173
- exit_status: bolt_result.first['result']['exit_code'],
174
- stdout: bolt_result.first['result']['stdout'],
175
- stderr: bolt_result.first['result']['stderr'])
176
+ result = OpenStruct.new(exit_code: bolt_result.first['value']['exit_code'],
177
+ exit_status: bolt_result.first['value']['exit_code'],
178
+ stdout: bolt_result.first['value']['stdout'],
179
+ stderr: bolt_result.first['value']['stderr'])
176
180
  span.add_field('litmus.result', result.to_h)
177
181
  yield result if block_given?
178
182
  result
@@ -199,16 +203,16 @@ module PuppetLitmus::PuppetHelpers
199
203
  raise "Target '#{target_node_name}' not found in inventory.yaml" unless target_in_inventory?(inventory_hash, target_node_name)
200
204
 
201
205
  span.add_field('litmus.node_name', target_node_name)
202
- span.add_field('litmus.platform', facts_from_node(inventory_hash, target_node_name)['platform'])
206
+ PuppetLitmus::HoneycombUtils.add_platform_field(inventory_hash, target_node_name)
203
207
 
204
208
  bolt_result = upload_file(source, destination, target_node_name, options: options, config: nil, inventory: inventory_hash)
205
209
  span.add_field('litmus.bolt_result', bolt_result)
206
210
 
207
211
  result_obj = {
208
212
  exit_code: 0,
209
- stdout: bolt_result.first['result']['_output'],
213
+ stdout: bolt_result.first['value']['_output'],
210
214
  stderr: nil,
211
- result: bolt_result.first['result'],
215
+ result: bolt_result.first['value'],
212
216
  }
213
217
 
214
218
  if bolt_result.first['status'] != 'success'
@@ -218,7 +222,7 @@ module PuppetLitmus::PuppetHelpers
218
222
  end
219
223
 
220
224
  result_obj[:exit_code] = 255
221
- result_obj[:stderr] = bolt_result.first['result']['_error']['msg']
225
+ result_obj[:stderr] = bolt_result.first['value']['_error']['msg']
222
226
  end
223
227
 
224
228
  result = OpenStruct.new(exit_code: result_obj[:exit_code],
@@ -257,22 +261,22 @@ module PuppetLitmus::PuppetHelpers
257
261
  raise "Target '#{target_node_name}' not found in inventory.yaml" unless target_in_inventory?(inventory_hash, target_node_name)
258
262
 
259
263
  span.add_field('litmus.node_name', target_node_name)
260
- span.add_field('litmus.platform', facts_from_node(inventory_hash, target_node_name)['platform'])
264
+ PuppetLitmus::HoneycombUtils.add_platform_field(inventory_hash, target_node_name)
261
265
 
262
266
  bolt_result = run_task(task_name, target_node_name, params, config: config_data, inventory: inventory_hash)
263
267
  result_obj = {
264
268
  exit_code: 0,
265
269
  stdout: nil,
266
270
  stderr: nil,
267
- result: bolt_result.first['result'],
271
+ result: bolt_result.first['value'],
268
272
  }
269
273
 
270
274
  if bolt_result.first['status'] == 'success'
271
275
  # stdout returns unstructured data if structured data is not available
272
- result_obj[:stdout] = if bolt_result.first['result']['_output'].nil?
273
- bolt_result.first['result'].to_s
276
+ result_obj[:stdout] = if bolt_result.first['value']['_output'].nil?
277
+ bolt_result.first['value'].to_s
274
278
  else
275
- bolt_result.first['result']['_output']
279
+ bolt_result.first['value']['_output']
276
280
  end
277
281
 
278
282
  else
@@ -281,12 +285,12 @@ module PuppetLitmus::PuppetHelpers
281
285
  raise "task failed\n`#{task_name}`\n======\n#{bolt_result}"
282
286
  end
283
287
 
284
- result_obj[:exit_code] = if bolt_result.first['result']['_error']['details'].nil?
288
+ result_obj[:exit_code] = if bolt_result.first['value']['_error']['details'].nil?
285
289
  255
286
290
  else
287
- bolt_result.first['result']['_error']['details'].fetch('exitcode', 255)
291
+ bolt_result.first['value']['_error']['details'].fetch('exitcode', 255)
288
292
  end
289
- result_obj[:stderr] = bolt_result.first['result']['_error']['msg']
293
+ result_obj[:stderr] = bolt_result.first['value']['_error']['msg']
290
294
  end
291
295
 
292
296
  result = OpenStruct.new(exit_code: result_obj[:exit_code],
@@ -318,18 +322,18 @@ module PuppetLitmus::PuppetHelpers
318
322
  raise "Target '#{target_node_name}' not found in inventory.yaml" unless target_in_inventory?(inventory_hash, target_node_name)
319
323
 
320
324
  span.add_field('litmus.node_name', target_node_name)
321
- span.add_field('litmus.platform', facts_from_node(inventory_hash, target_node_name)['platform'])
325
+ PuppetLitmus::HoneycombUtils.add_platform_field(inventory_hash, target_node_name)
322
326
 
323
327
  bolt_result = run_script(script, target_node_name, arguments, options: opts, config: nil, inventory: inventory_hash)
324
328
 
325
- if bolt_result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true
329
+ if bolt_result.first['value']['exit_code'] != 0 && opts[:expect_failures] != true
326
330
  span.add_field('litmus_runscriptfailure', bolt_result)
327
331
  raise "script run failed\n`#{script}`\n======\n#{bolt_result}"
328
332
  end
329
333
 
330
- result = OpenStruct.new(exit_code: bolt_result.first['result']['exit_code'],
331
- stdout: bolt_result.first['result']['stdout'],
332
- stderr: bolt_result.first['result']['stderr'])
334
+ result = OpenStruct.new(exit_code: bolt_result.first['value']['exit_code'],
335
+ stdout: bolt_result.first['value']['stdout'],
336
+ stderr: bolt_result.first['value']['stderr'])
333
337
  yield result if block_given?
334
338
  span.add_field('litmus.result', result.to_h)
335
339
  result
@@ -353,7 +357,7 @@ module PuppetLitmus::PuppetHelpers
353
357
  puppet_apply_error = <<~ERROR
354
358
  apply manifest failed
355
359
  `#{command}`
356
- with exit code #{bolt_result.first['result']['exit_code']} (expected: #{acceptable_exit_codes})
360
+ with exit code #{bolt_result.first['value']['exit_code']} (expected: #{acceptable_exit_codes})
357
361
  ====== Start output of failed Puppet apply ======
358
362
  #{puppet_output(bolt_result)}
359
363
  ====== End output of failed Puppet apply ======
@@ -378,8 +382,8 @@ module PuppetLitmus::PuppetHelpers
378
382
 
379
383
  # Return the stdout of the puppet run
380
384
  def puppet_output(bolt_result)
381
- bolt_result.dig(0, 'result', 'stderr').to_s << \
382
- bolt_result.dig(0, 'result', 'stdout').to_s
385
+ bolt_result.dig(0, 'value', 'stderr').to_s << \
386
+ bolt_result.dig(0, 'value', 'stdout').to_s
383
387
  end
384
388
 
385
389
  # Checks a puppet return status and returns true if it both
@@ -1,9 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module PuppetLitmus; end # rubocop:disable Style/Documentation
4
-
3
+ require 'bolt_spec/run'
5
4
  require 'honeycomb-beeline'
5
+ require 'puppet_litmus/honeycomb_utils'
6
6
  Honeycomb.configure do |config|
7
+ # override client if no configuration is provided, so that the pesky libhoney warning about lack of configuration is not shown
8
+ unless ENV['HONEYCOMB_WRITEKEY'] && ENV['HONEYCOMB_DATASET']
9
+ config.client = Libhoney::NullClient.new
10
+ end
7
11
  end
8
12
  process_span = Honeycomb.start_span(name: 'Litmus Testing', serialized_trace: ENV['HTTP_X_HONEYCOMB_TRACE'])
9
13
  ENV['HTTP_X_HONEYCOMB_TRACE'] = process_span.to_trace_header unless ENV['HTTP_X_HONEYCOMB_TRACE']
@@ -37,7 +41,8 @@ end
37
41
 
38
42
  # helper methods for the litmus rake tasks
39
43
  module PuppetLitmus::RakeHelper
40
- DEFAULT_CONFIG_DATA ||= { 'modulepath' => File.join(Dir.pwd, 'spec', 'fixtures', 'modules') }.freeze
44
+ # DEFAULT_CONFIG_DATA should be frozen for our safety, but it needs to work around https://github.com/puppetlabs/bolt/pull/1696
45
+ DEFAULT_CONFIG_DATA ||= { 'modulepath' => File.join(Dir.pwd, 'spec', 'fixtures', 'modules') } # .freeze # rubocop:disable Style/MutableConstant
41
46
  SUPPORTED_PROVISIONERS ||= %w[abs docker docker_exp vagrant vmpooler].freeze
42
47
 
43
48
  # Gets a string representing the operating system and version.
@@ -99,32 +104,8 @@ module PuppetLitmus::RakeHelper
99
104
  end
100
105
  end
101
106
 
102
- # Builds all the modules in a specified module
103
- #
104
- # @param source_folder [String] the folder to get the modules from
105
- # @return [Array] an array of module tar's
106
- def build_modules_in_folder(source_folder)
107
- folder_list = Dir.entries(source_folder).reject { |f| File.directory? f }
108
- module_tars = []
109
- folder_list.each do |folder|
110
- folder_handle = Dir.open(File.join(source_folder, folder))
111
- next if File.symlink?(folder_handle)
112
-
113
- module_dir = folder_handle.path
114
- target_dir = File.join(Dir.pwd, 'pkg')
115
- # remove old build folder if exists, before we build afresh
116
- FileUtils.rm_rf(target_dir) if File.directory?(target_dir)
117
-
118
- # build_module
119
- module_tar = build_module(module_dir, target_dir)
120
- module_tars.push(File.new(module_tar))
121
- end
122
- module_tars
123
- end
124
-
125
107
  def provision(provisioner, platform, inventory_vars)
126
- require 'bolt_spec/run'
127
- include BoltSpec::Run
108
+ include ::BoltSpec::Run
128
109
  raise "the provision module was not found in #{DEFAULT_CONFIG_DATA['modulepath']}, please amend the .fixtures.yml file" unless
129
110
  File.directory?(File.join(DEFAULT_CONFIG_DATA['modulepath'], 'provision'))
130
111
 
@@ -140,7 +121,7 @@ module PuppetLitmus::RakeHelper
140
121
 
141
122
  bolt_result = run_task(provisioner_task(provisioner), 'localhost', params, config: DEFAULT_CONFIG_DATA, inventory: nil)
142
123
 
143
- span.add_field('litmus.node_name', bolt_result&.first&.dig('result', 'node_name'))
124
+ span.add_field('litmus.node_name', bolt_result&.first&.dig('value', 'node_name'))
144
125
 
145
126
  bolt_result
146
127
  end
@@ -165,8 +146,7 @@ module PuppetLitmus::RakeHelper
165
146
  ENV['HTTP_X_HONEYCOMB_TRACE'] = span.to_trace_header unless ENV['HTTP_X_HONEYCOMB_TRACE']
166
147
  span.add_field('litmus.targets', targets)
167
148
 
168
- require 'bolt_spec/run'
169
- include BoltSpec::Run
149
+ include ::BoltSpec::Run
170
150
  config_data = { 'modulepath' => File.join(Dir.pwd, 'spec', 'fixtures', 'modules') }
171
151
  raise "the provision module was not found in #{config_data['modulepath']}, please amend the .fixtures.yml file" unless File.directory?(File.join(config_data['modulepath'], 'provision'))
172
152
 
@@ -185,12 +165,12 @@ module PuppetLitmus::RakeHelper
185
165
  Honeycomb.start_span(name: 'litmus.tear_down') do |span|
186
166
  ENV['HTTP_X_HONEYCOMB_TRACE'] = span.to_trace_header unless ENV['HTTP_X_HONEYCOMB_TRACE']
187
167
  # how do we know what provisioner to use
188
- node_facts = facts_from_node(inventory_hash, node_name)
189
168
 
190
169
  span.add_field('litmus.node_name', node_name)
191
- span.add_field('litmus.platform', node_facts['platform'])
170
+ PuppetLitmus::HoneycombUtils.add_platform_field(inventory_hash, node_name)
192
171
 
193
172
  params = { 'action' => 'tear_down', 'node_name' => node_name, 'inventory' => Dir.pwd }
173
+ node_facts = facts_from_node(inventory_hash, node_name)
194
174
  run_task(provisioner_task(node_facts['provisioner']), 'localhost', params, config: DEFAULT_CONFIG_DATA, inventory: nil)
195
175
  end
196
176
  end
@@ -201,8 +181,7 @@ module PuppetLitmus::RakeHelper
201
181
  span.add_field('litmus.collection', collection)
202
182
  span.add_field('litmus.targets', targets)
203
183
 
204
- require 'bolt_spec/run'
205
- include BoltSpec::Run
184
+ include ::BoltSpec::Run
206
185
  params = if collection.nil?
207
186
  {}
208
187
  else
@@ -213,7 +192,9 @@ module PuppetLitmus::RakeHelper
213
192
  unless File.directory?(File.join(DEFAULT_CONFIG_DATA['modulepath'], 'puppet_agent'))
214
193
 
215
194
  # using boltspec, when the runner is called it changes the inventory_hash dropping the version field. The clone works around this
216
- run_task('puppet_agent::install', targets, params, config: DEFAULT_CONFIG_DATA, inventory: inventory_hash.clone)
195
+ bolt_result = run_task('puppet_agent::install', targets, params, config: DEFAULT_CONFIG_DATA, inventory: inventory_hash.clone)
196
+ raise_bolt_errors(bolt_result, 'Installation of agent failed.')
197
+ bolt_result
217
198
  end
218
199
  end
219
200
 
@@ -244,26 +225,57 @@ module PuppetLitmus::RakeHelper
244
225
  builder.build
245
226
  end
246
227
 
247
- def install_module(inventory_hash, target_node_name, module_tar)
248
- require 'bolt_spec/run'
249
- include BoltSpec::Run
250
- target_nodes = find_targets(inventory_hash, target_node_name)
251
- target_string = if target_node_name.nil?
252
- 'all'
253
- else
254
- target_node_name
255
- end
256
- run_local_command("bundle exec bolt file upload \"#{module_tar}\" /tmp/#{File.basename(module_tar)} --nodes #{target_string} --inventoryfile inventory.yaml")
257
- install_module_command = "puppet module install /tmp/#{File.basename(module_tar)}"
228
+ def install_module(inventory_hash, target_node_name, module_tar, module_repository = 'https://forgeapi.puppetlabs.com')
258
229
  Honeycomb.start_span(name: 'install_module') do |span|
259
230
  ENV['HTTP_X_HONEYCOMB_TRACE'] = span.to_trace_header unless ENV['HTTP_X_HONEYCOMB_TRACE']
260
- span.add_field('litmus.install_module_command', install_module_command)
231
+ span.add_field('litmus.target_node_name', target_node_name)
232
+ span.add_field('litmus.module_tar', module_tar)
233
+
234
+ # make sure the target module is not installed
235
+ # otherwise `puppet module install` might silently skip it
236
+ uninstall_module(inventory_hash.clone, target_node_name, force: true)
237
+
238
+ include ::BoltSpec::Run
239
+
240
+ target_nodes = find_targets(inventory_hash, target_node_name)
261
241
  span.add_field('litmus.target_nodes', target_nodes)
242
+ bolt_result = upload_file(module_tar, "/tmp/#{File.basename(module_tar)}", target_nodes, options: {}, config: nil, inventory: inventory_hash.clone)
243
+ raise_bolt_errors(bolt_result, 'Failed to upload module.')
244
+
245
+ install_module_command = "puppet module install --module_repository '#{module_repository}' /tmp/#{File.basename(module_tar)}"
246
+ span.add_field('litmus.install_module_command', install_module_command)
262
247
 
263
- run_command(install_module_command, target_nodes, config: nil, inventory: inventory_hash)
248
+ bolt_result = run_command(install_module_command, target_nodes, config: nil, inventory: inventory_hash.clone)
249
+ raise_bolt_errors(bolt_result, "Installation of package #{module_tar} failed.")
250
+ bolt_result
264
251
  end
265
252
  end
266
253
 
254
+ # Builds all the modules in a specified module
255
+ #
256
+ # @param source_folder [String] the folder to get the modules from
257
+ # @return [Array] an array of module tar's
258
+ def build_modules_in_folder(source_folder)
259
+ folder_list = Dir.entries(source_folder).reject { |f| File.directory? f }
260
+ module_tars = []
261
+
262
+ target_dir = File.join(Dir.pwd, 'pkg')
263
+ # remove old build folder if exists, before we build afresh
264
+ FileUtils.rm_rf(target_dir) if File.directory?(target_dir)
265
+
266
+ folder_list.each do |folder|
267
+ folder_handle = Dir.open(File.join(source_folder, folder))
268
+ next if File.symlink?(folder_handle)
269
+
270
+ module_dir = folder_handle.path
271
+
272
+ # build_module
273
+ module_tar = build_module(module_dir, target_dir)
274
+ module_tars.push(File.new(module_tar))
275
+ end
276
+ module_tars
277
+ end
278
+
267
279
  def metadata_module_name
268
280
  require 'json'
269
281
  raise 'Could not find metadata.json' unless File.exist?(File.join(Dir.pwd, 'metadata.json'))
@@ -274,12 +286,12 @@ module PuppetLitmus::RakeHelper
274
286
  metadata['name']
275
287
  end
276
288
 
277
- def uninstall_module(inventory_hash, target_node_name, module_to_remove = nil)
278
- require 'bolt_spec/run'
279
- include BoltSpec::Run
289
+ def uninstall_module(inventory_hash, target_node_name, module_to_remove = nil, **opts)
290
+ include ::BoltSpec::Run
280
291
  module_name = module_to_remove || metadata_module_name
281
292
  target_nodes = find_targets(inventory_hash, target_node_name)
282
293
  install_module_command = "puppet module uninstall #{module_name}"
294
+ install_module_command += ' --force' if opts[:force]
283
295
  run_command(install_module_command, target_nodes, config: nil, inventory: inventory_hash)
284
296
  end
285
297
 
@@ -289,11 +301,10 @@ module PuppetLitmus::RakeHelper
289
301
  # if we're only checking connectivity for a single node
290
302
  if target_node_name
291
303
  span.add_field('litmus.node_name', target_node_name)
292
- span.add_field('litmus.platform', facts_from_node(inventory_hash, target_node_name)['platform'])
304
+ PuppetLitmus::HoneycombUtils.add_platform_field(inventory_hash, target_node_name)
293
305
  end
294
306
 
295
- require 'bolt_spec/run'
296
- include BoltSpec::Run
307
+ include ::BoltSpec::Run
297
308
  target_nodes = find_targets(inventory_hash, target_node_name)
298
309
  results = run_command('cd .', target_nodes, config: nil, inventory: inventory_hash)
299
310
  span.add_field('litmus.bolt_result', results)
@@ -316,4 +327,38 @@ module PuppetLitmus::RakeHelper
316
327
  provisioner.to_s
317
328
  end
318
329
  end
330
+
331
+ # Parse out errors messages in result set returned by Bolt command.
332
+ #
333
+ # @param result_set [Array] result set returned by Bolt command.
334
+ # @return [Hash] Error messages grouped by target.
335
+ def check_bolt_errors(result_set)
336
+ errors = {}
337
+ # iterate through each error
338
+ result_set.each do |target_result|
339
+ status = target_result['status']
340
+ # jump to the next one when there is not fail
341
+ next if status != 'failure'
342
+
343
+ target = target_result['target']
344
+ # get some info from error
345
+ error_msg = target_result['value']['_error']['msg']
346
+ errors[target] = error_msg
347
+ end
348
+ errors
349
+ end
350
+
351
+ # Parse out errors messages in result set returned by Bolt command. If there are errors, raise them.
352
+ #
353
+ # @param result_set [Array] result set returned by Bolt command.
354
+ # @param error_msg [String] error message to raise when errors are detected. The actual errors will be appended.
355
+ def raise_bolt_errors(result_set, error_msg)
356
+ errors = check_bolt_errors(result_set)
357
+
358
+ unless errors.empty?
359
+ raise "#{error_msg}\nErrors: #{errors}"
360
+ end
361
+
362
+ nil
363
+ end
319
364
  end
@@ -57,9 +57,9 @@ namespace :litmus do
57
57
  end
58
58
 
59
59
  if result.first['status'] != 'success'
60
- failed_image_message += "=====\n#{result.first['node']}\n#{result.first['result']['_output']}\n#{result.inspect}"
60
+ failed_image_message += "=====\n#{result.first['target']}\n#{result.first['value']['_output']}\n#{result.inspect}"
61
61
  else
62
- STDOUT.puts "#{result.first['result']['node_name']}, #{image}"
62
+ STDOUT.puts "#{result.first['value']['node_name']}, #{image}"
63
63
  end
64
64
  results << result
65
65
  end
@@ -96,7 +96,7 @@ namespace :litmus do
96
96
  else
97
97
  spinner.success
98
98
  end
99
- puts "#{results.first['result']['node_name']}, #{args[:platform]}"
99
+ puts "#{results.first['value']['node_name']}, #{args[:platform]}"
100
100
  end
101
101
 
102
102
  # Install puppet agent on a collection of nodes
@@ -119,11 +119,11 @@ namespace :litmus do
119
119
  results = install_agent(args[:collection], targets, inventory_hash)
120
120
  results.each do |result|
121
121
  if result['status'] != 'success'
122
- command_to_run = "bolt task run puppet_agent::install --targets #{result['node']} --inventoryfile inventory.yaml --modulepath #{DEFAULT_CONFIG_DATA['modulepath']}"
123
- raise "Failed on #{result['node']}\n#{result}\ntry running '#{command_to_run}'"
122
+ command_to_run = "bolt task run puppet_agent::install --targets #{result['target']} --inventoryfile inventory.yaml --modulepath #{DEFAULT_CONFIG_DATA['modulepath']}"
123
+ raise "Failed on #{result['target']}\n#{result}\ntry running '#{command_to_run}'"
124
124
  else
125
125
  # add puppet-agent feature to successful nodes
126
- inventory_hash = add_feature_to_node(inventory_hash, 'puppet-agent', result['node'])
126
+ inventory_hash = add_feature_to_node(inventory_hash, 'puppet-agent', result['target'])
127
127
  end
128
128
  end
129
129
  # update the inventory with the puppet-agent feature set per node
@@ -134,7 +134,7 @@ namespace :litmus do
134
134
 
135
135
  results.each do |result|
136
136
  if result['status'] != 'success'
137
- puts "Failed on #{result['node']}\n#{result}"
137
+ puts "Failed on #{result['target']}\n#{result}"
138
138
  end
139
139
  end
140
140
  end
@@ -171,7 +171,8 @@ namespace :litmus do
171
171
  # @param :source [String] source directory to look in (ignores symlinks) defaults do './spec/fixtures/modules'.
172
172
  # @param :target_node_name [Array] nodes on which to install a puppet module for testing.
173
173
  desc 'install_module - build and install module'
174
- task :install_modules_from_directory, [:source, :target_node_name] do |_task, args|
174
+ task :install_modules_from_directory, [:source, :target_node_name, :module_repository] do |_task, args|
175
+ args.with_defaults(source: nil, target_node_name: nil, module_repository: 'https://forgeapi.puppetlabs.com')
175
176
  inventory_hash = inventory_hash_from_inventory_file
176
177
  target_nodes = find_targets(inventory_hash, args[:target_node_name])
177
178
  if target_nodes.empty?
@@ -185,24 +186,15 @@ namespace :litmus do
185
186
  end
186
187
  raise "Source folder doesnt exist #{source_folder}" unless File.directory?(source_folder)
187
188
 
188
- module_tars = build_modules_in_folder(source_folder)
189
189
  puts 'Building'
190
- module_tars.each do |module_tar|
191
- print "#{File.basename(module_tar)} "
192
- end
190
+ module_tars = build_modules_in_folder(source_folder)
193
191
  require 'bolt_spec/run'
194
192
  include BoltSpec::Run
195
- puts "\nSending"
196
- module_tars.each do |module_tar|
197
- upload_file(module_tar.path, "/tmp/#{File.basename(module_tar)}", target_nodes, options: {}, config: nil, inventory: inventory_hash)
198
- print "#{File.basename(module_tar)} "
199
- end
200
193
  puts "\nInstalling"
201
194
  module_tars.each do |module_tar|
202
- # install_module
203
- install_module_command = "puppet module install --force /tmp/#{File.basename(module_tar)}"
204
- run_command(install_module_command, target_nodes, config: nil, inventory: inventory_hash)
205
- print "#{File.basename(module_tar)} "
195
+ target_nodes.each do |target_node_name|
196
+ install_module(inventory_hash, target_node_name, module_tar, args[:module_repository])
197
+ end
206
198
  end
207
199
  end
208
200
 
@@ -224,7 +216,8 @@ namespace :litmus do
224
216
  #
225
217
  # @param :target_node_name [Array] nodes on which to install a puppet module for testing.
226
218
  desc 'install_module - build and install module'
227
- task :install_module, [:target_node_name] do |_task, args|
219
+ task :install_module, [:target_node_name, :module_repository] do |_task, args|
220
+ args.with_defaults(target_node_name: nil, module_repository: 'https://forgeapi.puppetlabs.com')
228
221
  inventory_hash = inventory_hash_from_inventory_file
229
222
  target_nodes = find_targets(inventory_hash, args[:target_node_name])
230
223
  if target_nodes.empty?
@@ -238,13 +231,7 @@ namespace :litmus do
238
231
  # module_tar = Dir.glob('pkg/*.tar.gz').max_by { |f| File.mtime(f) }
239
232
  raise "Unable to find package in 'pkg/*.tar.gz'" if module_tar.nil?
240
233
 
241
- result = install_module(inventory_hash, args[:target_node_name], module_tar)
242
-
243
- raise "Failed trying to run 'puppet module install /tmp/#{File.basename(module_tar)}' against inventory." unless result.is_a?(Array)
244
-
245
- result.each do |node|
246
- puts "#{node['node']} failed #{node['result']}" if node['status'] != 'success'
247
- end
234
+ install_module(inventory_hash, args[:target_node_name], module_tar, args[:module_repository])
248
235
 
249
236
  puts 'Installed'
250
237
  end
@@ -254,11 +241,12 @@ namespace :litmus do
254
241
  # @param :key [String] key that maps to a value for a provisioner and an image to be used for each OS provisioned.
255
242
  # @param :collection [String] parameters to pass to the puppet agent install command.
256
243
  desc 'provision_install - provision a list of machines, install an agent, and the module.'
257
- task :provision_install, [:key, :collection] do |_task, args|
244
+ task :provision_install, [:key, :collection, :module_repository] do |_task, args|
245
+ args.with_defaults(module_repository: 'https://forgeapi.puppetlabs.com')
258
246
  Rake::Task['spec_prep'].invoke
259
247
  Rake::Task['litmus:provision_list'].invoke(args[:key])
260
248
  Rake::Task['litmus:install_agent'].invoke(args[:collection])
261
- Rake::Task['litmus:install_module'].invoke
249
+ Rake::Task['litmus:install_module'].invoke(nil, args[:module_repository])
262
250
  end
263
251
 
264
252
  # Decommissions test machines.
@@ -277,7 +265,7 @@ namespace :litmus do
277
265
  results = tear_down_nodes(targets, inventory_hash)
278
266
  results.each do |node, result|
279
267
  if result.first['status'] != 'success'
280
- bad_results << "#{node}, #{result.first['result']['_error']['msg']}"
268
+ bad_results << "#{node}, #{result.first['value']['_error']['msg']}"
281
269
  else
282
270
  puts "#{node}: #{result.first['status']}"
283
271
  end
@@ -308,7 +296,7 @@ namespace :litmus do
308
296
  raise "Failed trying to run 'puppet module uninstall #{module_name}' against inventory." unless result.is_a?(Array)
309
297
 
310
298
  result.each do |node|
311
- puts "#{node['node']} failed #{node['result']}" if node['status'] != 'success'
299
+ puts "#{node['target']} failed #{node['value']}" if node['status'] != 'success'
312
300
  end
313
301
 
314
302
  puts 'Uninstalled'
@@ -318,9 +306,10 @@ namespace :litmus do
318
306
  #
319
307
  # @param :target_node_name [Array] nodes on which to install a puppet module for testing.
320
308
  desc 'reinstall_module - reinstall module'
321
- task :reinstall_module, [:target_node_name] do |_task, args|
309
+ task :reinstall_module, [:target_node_name, :module_repository] do |_task, args|
310
+ args.with_defaults(target_node_name: nil, module_repository: 'https://forgeapi.puppetlabs.com')
322
311
  Rake::Task['litmus:uninstall_module'].invoke(args[:target_node_name])
323
- Rake::Task['litmus:install_module'].invoke(args[:target_node_name])
312
+ Rake::Task['litmus:install_module'].invoke(args[:target_node_name], args[:module_repository])
324
313
  end
325
314
 
326
315
  namespace :acceptance do
@@ -2,5 +2,5 @@
2
2
 
3
3
  # version of this gem
4
4
  module PuppetLitmus
5
- VERSION ||= '0.17.0'
5
+ VERSION ||= '0.18.0'
6
6
  end
@@ -23,8 +23,8 @@ RSpec.describe PuppetLitmus::PuppetHelpers do
23
23
  describe '.apply_manifest' do
24
24
  context 'when specifying a hiera config' do
25
25
  let(:manifest) { "include '::doot'" }
26
- let(:result) { ['result' => { 'exit_code' => 0, 'stdout' => nil, 'stderr' => nil }] }
27
- let(:command) { " puppet apply /bla.pp --modulepath #{Dir.pwd}/spec/fixtures/modules --hiera_config='/hiera.yaml'" }
26
+ let(:result) { ['value' => { 'exit_code' => 0, 'stdout' => nil, 'stderr' => nil }] }
27
+ let(:command) { " puppet apply /bla.pp --trace --modulepath #{Dir.pwd}/spec/fixtures/modules --hiera_config='/hiera.yaml'" }
28
28
 
29
29
  it 'passes the --hiera_config flag if the :hiera_config opt is specified' do
30
30
  expect(File).to receive(:exist?).with('inventory.yaml').and_return(false)
@@ -38,8 +38,8 @@ RSpec.describe PuppetLitmus::PuppetHelpers do
38
38
 
39
39
  context 'when using detailed-exitcodes' do
40
40
  let(:manifest) { "include '::doot'" }
41
- let(:result) { ['result' => { 'exit_code' => 0, 'stdout' => nil, 'stderr' => nil }] }
42
- let(:command) { " puppet apply /bla.pp --modulepath #{Dir.pwd}/spec/fixtures/modules --detailed-exitcodes" }
41
+ let(:result) { ['value' => { 'exit_code' => 0, 'stdout' => nil, 'stderr' => nil }] }
42
+ let(:command) { " puppet apply /bla.pp --trace --modulepath #{Dir.pwd}/spec/fixtures/modules --detailed-exitcodes" }
43
43
 
44
44
  it 'uses detailed-exitcodes with expect_failures' do
45
45
  expect(File).to receive(:exist?).with('inventory.yaml').and_return(false)
@@ -86,7 +86,7 @@ RSpec.describe PuppetLitmus::PuppetHelpers do
86
86
 
87
87
  describe '.run_shell' do
88
88
  let(:command_to_run) { "puts 'doot'" }
89
- let(:result) { ['result' => { 'exit_code' => 0, 'exit_status' => 0, 'stdout' => nil, 'stderr' => nil }] }
89
+ let(:result) { ['value' => { 'exit_code' => 0, 'exit_status' => 0, 'stdout' => nil, 'stderr' => nil }] }
90
90
 
91
91
  it 'responds to run_shell' do
92
92
  expect(described_class).to respond_to(:run_shell).with(1..2).arguments
@@ -120,8 +120,8 @@ RSpec.describe PuppetLitmus::PuppetHelpers do
120
120
  let(:remote) { '/remote_tmp' }
121
121
  # Ignore rubocop because these hashes are representative of output from an external method and editing them leads to test failures.
122
122
  # rubocop:disable Layout/SpaceInsideHashLiteralBraces, Layout/SpaceInsideBlockBraces, Layout/SpaceAroundOperators, Layout/LineLength, Layout/SpaceAfterComma
123
- let(:result_success) {[{'node'=>'some.host','target'=>'some.host','action'=>'upload','object'=>'C:\foo\bar.ps1','status'=>'success','result'=>{'_output'=>'Uploaded \'C:\foo\bar.ps1\' to \'some.host:C:\bar\''}}]}
124
- let(:result_failure) {[{'node'=>'some.host','target'=>'some.host','action'=>nil,'object'=>nil,'status'=>'failure','result'=>{'_error'=>{'kind'=>'puppetlabs.tasks/task_file_error','msg'=>'No such file or directory @ rb_sysopen - /nonexistant/file/path','details'=>{},'issue_code'=>'WRITE_ERROR'}}}]}
123
+ let(:result_success) {[{'target'=>'some.host','action'=>'upload','object'=>'C:\foo\bar.ps1','status'=>'success','value'=>{'_output'=>'Uploaded \'C:\foo\bar.ps1\' to \'some.host:C:\bar\''}}]}
124
+ let(:result_failure) {[{'target'=>'some.host','action'=>nil,'object'=>nil,'status'=>'failure','value'=>{'_error'=>{'kind'=>'puppetlabs.tasks/task_file_error','msg'=>'No such file or directory @ rb_sysopen - /nonexistant/file/path','details'=>{},'issue_code'=>'WRITE_ERROR'}}}]}
125
125
  # rubocop:enable Layout/SpaceInsideHashLiteralBraces, Layout/SpaceInsideBlockBraces, Layout/SpaceAroundOperators, Layout/LineLength, Layout/SpaceAfterComma
126
126
 
127
127
  it 'responds to run_shell' do
@@ -174,7 +174,7 @@ RSpec.describe PuppetLitmus::PuppetHelpers do
174
174
 
175
175
  describe '.bolt_run_script' do
176
176
  let(:script) { '/tmp/script.sh' }
177
- let(:result) { ['result' => { 'exit_code' => 0, 'stdout' => nil, 'stderr' => nil }] }
177
+ let(:result) { ['value' => { 'exit_code' => 0, 'stdout' => nil, 'stderr' => nil }] }
178
178
 
179
179
  it 'responds to bolt_run_script' do
180
180
  expect(described_class).to respond_to(:bolt_run_script).with(1..2).arguments
@@ -222,9 +222,9 @@ RSpec.describe PuppetLitmus::PuppetHelpers do
222
222
  let(:config_data) { { 'modulepath' => File.join(Dir.pwd, 'spec', 'fixtures', 'modules') } }
223
223
  # Ignore rubocop because these hashes are representative of output from an external method and editing them leads to test failures.
224
224
  # rubocop:disable Layout/SpaceInsideHashLiteralBraces, Layout/SpaceBeforeBlockBraces, Layout/SpaceInsideBlockBraces, Layout/SpaceAroundOperators, Layout/LineLength, Layout/SpaceAfterComma
225
- let(:result_unstructured_task_success){ [{'node'=>'some.host','target'=>'some.host','action'=>'task','object'=>'testtask::unstructured','status'=>'success','result'=>{'_output'=>'SUCCESS!'}}]}
226
- let(:result_structured_task_success){ [{'node'=>'some.host','target'=>'some.host','action'=>'task','object'=>'testtask::structured','status'=>'success','result'=>{'key1'=>'foo','key2'=>'bar'}}]}
227
- let(:result_failure) {[{'node'=>'some.host','target'=>'some.host','action'=>'task','object'=>'testtask::unstructured','status'=>'failure','result'=>{'_error'=>{'msg'=>'FAILURE!','kind'=>'puppetlabs.tasks/task-error','details'=>{'exitcode'=>123}}}}]}
225
+ let(:result_unstructured_task_success){ [{'target'=>'some.host','action'=>'task','object'=>'testtask::unstructured','status'=>'success','value'=>{'_output'=>'SUCCESS!'}}]}
226
+ let(:result_structured_task_success){ [{'target'=>'some.host','action'=>'task','object'=>'testtask::structured','status'=>'success','value'=>{'key1'=>'foo','key2'=>'bar'}}]}
227
+ let(:result_failure) {[{'target'=>'some.host','action'=>'task','object'=>'testtask::unstructured','status'=>'failure','value'=>{'_error'=>{'msg'=>'FAILURE!','kind'=>'puppetlabs.tasks/task-error','details'=>{'exitcode'=>123}}}}]}
228
228
  # rubocop:enable Layout/SpaceInsideHashLiteralBraces, Layout/SpaceBeforeBlockBraces, Layout/SpaceInsideBlockBraces, Layout/SpaceAroundOperators, Layout/LineLength, Layout/SpaceAfterComma
229
229
 
230
230
  it 'responds to bolt_run_task' do
@@ -102,11 +102,16 @@ RSpec.describe PuppetLitmus::RakeHelper do
102
102
  end
103
103
  let(:module_tar) { '/tmp/foo.tar.gz' }
104
104
  let(:targets) { ['some.host'] }
105
- let(:install_module_command) { "puppet module install /tmp/#{File.basename(module_tar)}" }
105
+ let(:uninstall_module_command) { 'puppet module uninstall foo --force' }
106
+ let(:install_module_command) { "puppet module install --module_repository 'https://forgeapi.puppetlabs.com' #{module_tar}" }
106
107
 
107
108
  it 'calls function' do
108
- allow(Open3).to receive(:capture3).with("bundle exec bolt file upload \"#{module_tar}\" /tmp/#{File.basename(module_tar)} --nodes all --inventoryfile inventory.yaml")
109
+ allow_any_instance_of(BoltSpec::Run).to receive(:upload_file).with(module_tar, module_tar, targets, options: {}, config: nil, inventory: inventory_hash).and_return([])
110
+ allow(File).to receive(:exist?).with(File.join(Dir.pwd, 'metadata.json')).and_return(true)
111
+ allow(File).to receive(:read).with(File.join(Dir.pwd, 'metadata.json')).and_return(JSON.dump({ name: 'foo' }))
112
+ allow(Open3).to receive(:capture3).with("bundle exec bolt file upload \"#{module_tar}\" /tmp/#{File.basename(module_tar)} --targets all --inventoryfile inventory.yaml")
109
113
  .and_return(['success', '', 0])
114
+ allow_any_instance_of(BoltSpec::Run).to receive(:run_command).with(uninstall_module_command, targets, config: nil, inventory: inventory_hash).and_return([])
110
115
  allow_any_instance_of(BoltSpec::Run).to receive(:run_command).with(install_module_command, targets, config: nil, inventory: inventory_hash).and_return([])
111
116
  described_class.install_module(inventory_hash, nil, module_tar)
112
117
  end
@@ -32,15 +32,17 @@ describe 'litmus rake tasks' do
32
32
  let(:dummy_tar) { File.new('spec/data/doot.tar.gz') }
33
33
 
34
34
  it 'happy path' do
35
+ allow(File).to receive(:exist?).with(File.join(Dir.pwd, 'metadata.json')).and_return(true)
36
+ allow(File).to receive(:read).with(File.join(Dir.pwd, 'metadata.json')).and_return(JSON.dump({ name: 'foo' }))
37
+
35
38
  stub_const('ENV', ENV.to_hash.merge('TARGET_HOST' => 'some.host'))
36
39
  expect_any_instance_of(PuppetLitmus::InventoryManipulation).to receive(:inventory_hash_from_inventory_file).and_return(inventory_hash)
37
40
  expect(File).to receive(:directory?).with(target_folder).and_return(true)
38
41
  expect_any_instance_of(Object).to receive(:build_modules_in_folder).with(target_folder).and_return([dummy_tar])
39
42
  expect(STDOUT).to receive(:puts).with('Building')
40
- expect(STDOUT).to receive(:puts).with("\nSending")
41
- expect_any_instance_of(Object).to receive(:upload_file).once
43
+ expect_any_instance_of(Object).to receive(:upload_file).once.and_return([])
42
44
  expect(STDOUT).to receive(:puts).with("\nInstalling")
43
- expect_any_instance_of(Object).to receive(:run_command).once
45
+ expect_any_instance_of(Object).to receive(:run_command).twice.and_return([])
44
46
  Rake::Task['litmus:install_modules_from_directory'].invoke('./spec/fixtures/modules')
45
47
  end
46
48
  end
@@ -57,12 +59,11 @@ describe 'litmus rake tasks' do
57
59
 
58
60
  context 'with litmus:provision task' do
59
61
  it 'happy path' do
60
- results = [{ 'node' => 'localhost',
61
- 'target' => 'localhost',
62
+ results = [{ 'target' => 'localhost',
62
63
  'action' => 'task',
63
64
  'object' => 'provision::docker',
64
65
  'status' => 'success',
65
- 'result' => { 'status' => 'ok', 'node_name' => 'localhost:2222' } }]
66
+ 'value' => { 'status' => 'ok', 'node_name' => 'localhost:2222' } }]
66
67
 
67
68
  allow(File).to receive(:directory?).with(any_args).and_return(true)
68
69
  allow_any_instance_of(BoltSpec::Run).to receive(:run_task).with(any_args).and_return(results)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet_litmus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.0
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-24 00:00:00.000000000 Z
11
+ date: 2020-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bolt
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.13.1
19
+ version: 2.0.1
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: 2.0.0
22
+ version: 3.0.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 1.13.1
29
+ version: 2.0.1
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: 2.0.0
32
+ version: 3.0.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: puppet-modulebuilder
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -151,6 +151,7 @@ files:
151
151
  - LICENSE
152
152
  - README.md
153
153
  - lib/puppet_litmus.rb
154
+ - lib/puppet_litmus/honeycomb_utils.rb
154
155
  - lib/puppet_litmus/inventory_manipulation.rb
155
156
  - lib/puppet_litmus/puppet_helpers.rb
156
157
  - lib/puppet_litmus/rake_helper.rb
@@ -197,10 +198,10 @@ test_files:
197
198
  - spec/data/doot.tar.gz
198
199
  - spec/data/inventory.yaml
199
200
  - spec/data/jim.yaml
200
- - spec/lib/puppet_litmus/inventory_manipulation_spec.rb
201
- - spec/lib/puppet_litmus/rake_tasks_spec.rb
202
201
  - spec/lib/puppet_litmus/util_spec.rb
203
202
  - spec/lib/puppet_litmus/version_spec.rb
204
- - spec/lib/puppet_litmus/puppet_helpers_spec.rb
203
+ - spec/lib/puppet_litmus/inventory_manipulation_spec.rb
205
204
  - spec/lib/puppet_litmus/rake_helper_spec.rb
205
+ - spec/lib/puppet_litmus/puppet_helpers_spec.rb
206
+ - spec/lib/puppet_litmus/rake_tasks_spec.rb
206
207
  - spec/spec_helper.rb