puppet_litmus 0.4.0 → 0.5.0

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: b8793e294b24574549eb709f40fd2f4c60a7995e
4
- data.tar.gz: 5f786dd179b80096027dbd60a5a0e3cfb805dc19
3
+ metadata.gz: 33763c6946158b131037d7d28f96b7db4ae5b924
4
+ data.tar.gz: f85aa0cd77c310d4e798f8676189839bb4276d2b
5
5
  SHA512:
6
- metadata.gz: ddb4a53476e159cf891c661830f6d94af3600c1a6ce4127ca3cd7b9401aa51cd3efca458794b0e8ebd040b3269f783b52da3e285a1a99892ce0e9ae7f5e693b5
7
- data.tar.gz: 9a730ae696a455ecd35ec5c544920b0a349a59aa9c42c63f897fe20d0c7e2dfe9757ae2cbee70bd3ce5a5a61b05569cc62f4f20418a94d7cf0cac8adb28f2325
6
+ metadata.gz: 345cfa379161bccf03db5945499114e6d322161891b66d85aac934e7cd8de8834cc73c465d65a19c482cf8320d22c1ae89b1afb8bcc9794dab2faf3a7460aeec
7
+ data.tar.gz: bc6916ad37c08f73ab2594c9537e14212257583e37437c396ea1f716219edfdda2a9be430c9d55bc8b7b1f777ec27beac7c76f1a97fb6d676f72bb36327a3ccf
@@ -2,6 +2,10 @@
2
2
 
3
3
  # helper functions for manipulating and reading a bolt inventory file
4
4
  module PuppetLitmus::InventoryManipulation
5
+ # Creates an inventory hash from the inventory.yaml.
6
+ #
7
+ # @param inventory_full_path [String] path to the inventory.yaml file
8
+ # @return [Hash] hash of the inventory.yaml file.
5
9
  def inventory_hash_from_inventory_file(inventory_full_path = nil)
6
10
  inventory_full_path = if inventory_full_path.nil?
7
11
  'inventory.yaml'
@@ -14,6 +18,11 @@ module PuppetLitmus::InventoryManipulation
14
18
  inventory_hash
15
19
  end
16
20
 
21
+ # Finds targets to perform operations on from an inventory hash.
22
+ #
23
+ # @param inventory_hash [Hash] hash of the inventory.yaml file
24
+ # @param targets [Array]
25
+ # @return [Array] array of targets.
17
26
  def find_targets(inventory_hash, targets)
18
27
  if targets.nil?
19
28
  inventory = Bolt::Inventory.new(inventory_hash, nil)
@@ -24,6 +33,12 @@ module PuppetLitmus::InventoryManipulation
24
33
  targets
25
34
  end
26
35
 
36
+ # Determines if a node_name exists in a group in the inventory_hash.
37
+ #
38
+ # @param inventory_hash [Hash] hash of the inventory.yaml file
39
+ # @param node_name [String] node to locate in the group
40
+ # @param group_name [String] group of nodes to limit the search for the node_name in
41
+ # @return [Boolean] true if node_name exists in group_name.
27
42
  def target_in_group(inventory_hash, node_name, group_name)
28
43
  exists = false
29
44
  inventory_hash['groups'].each do |group|
@@ -36,6 +51,11 @@ module PuppetLitmus::InventoryManipulation
36
51
  exists
37
52
  end
38
53
 
54
+ # Finds a config hash in the inventory hash by searching for a node name.
55
+ #
56
+ # @param inventory_hash [Hash] hash of the inventory.yaml file
57
+ # @param node_name [String] node to locate in the group
58
+ # @return [Hash] config for node of name node_name
39
59
  def config_from_node(inventory_hash, node_name)
40
60
  inventory_hash['groups'].each do |group|
41
61
  group['nodes'].each do |node|
@@ -47,6 +67,11 @@ module PuppetLitmus::InventoryManipulation
47
67
  raise "No config was found for #{node_name}"
48
68
  end
49
69
 
70
+ # Finds a facts hash in the inventory hash by searching for a node name.
71
+ #
72
+ # @param inventory_hash [Hash] hash of the inventory.yaml file
73
+ # @param node_name [String] node to locate in the group
74
+ # @return [Hash] facts for node of name node_name
50
75
  def facts_from_node(inventory_hash, node_name)
51
76
  inventory_hash['groups'].each do |group|
52
77
  group['nodes'].each do |node|
@@ -55,9 +80,15 @@ module PuppetLitmus::InventoryManipulation
55
80
  end
56
81
  end
57
82
  end
58
- raise "No config was found for #{node_name}"
83
+ raise "No facts were found for #{node_name}"
59
84
  end
60
85
 
86
+ # Adds a node to a group specified, if group_name exists in inventory hash.
87
+ #
88
+ # @param inventory_hash [Hash] hash of the inventory.yaml file
89
+ # @param node_name [String] node to locate in the group
90
+ # group_name [String] group of nodes to limit the search for the node_name in
91
+ # @return [Hash] inventory_hash with node added to group if group_name exists in inventory hash.
61
92
  def add_node_to_group(inventory_hash, node_name, group_name)
62
93
  inventory_hash['groups'].each do |group|
63
94
  if group['name'] == group_name
@@ -67,6 +98,11 @@ module PuppetLitmus::InventoryManipulation
67
98
  inventory_hash
68
99
  end
69
100
 
101
+ # Removes named node from a group inside an inventory_hash.
102
+ #
103
+ # @param inventory_hash [Hash] hash of the inventory.yaml file
104
+ # @param node_name [String] node to locate in the group
105
+ # @return [Hash] inventory_hash with node of node_name removed.
70
106
  def remove_node(inventory_hash, node_name)
71
107
  inventory_hash['groups'].each do |group|
72
108
  group['nodes'].delete_if { |i| i['name'] == node_name }
@@ -8,51 +8,64 @@ require 'pdk'
8
8
  require 'json'
9
9
  require 'parallel'
10
10
 
11
- def get_metadata_operating_systems(metadata)
12
- return unless metadata.is_a?(Hash)
13
- return unless metadata['operatingsystem_support'].is_a?(Array)
14
-
15
- metadata['operatingsystem_support'].each do |os_info|
16
- next unless os_info['operatingsystem'] && os_info['operatingsystemrelease']
17
-
18
- os_name = case os_info['operatingsystem']
19
- when 'Amazon', 'Archlinux', 'AIX', 'OSX'
20
- next
21
- when 'OracleLinux'
22
- 'oracle'
23
- when 'Windows'
24
- 'win'
25
- else
26
- os_info['operatingsystem'].downcase
27
- end
11
+ # helper methods for the litmus rake tasks
12
+ module LitmusRakeHelper
13
+ # Gets a string representing the operating system and version.
14
+ #
15
+ # @param metadata [Hash] metadata to parse for operating system info
16
+ # @return [String] the operating system string with version info for use in provisioning.
17
+ def get_metadata_operating_systems(metadata)
18
+ return unless metadata.is_a?(Hash)
19
+ return unless metadata['operatingsystem_support'].is_a?(Array)
20
+
21
+ metadata['operatingsystem_support'].each do |os_info|
22
+ next unless os_info['operatingsystem'] && os_info['operatingsystemrelease']
28
23
 
29
- os_info['operatingsystemrelease'].each do |release|
30
- version = case os_name
31
- when 'ubuntu', 'osx'
32
- release.sub('.', '')
33
- when 'sles'
34
- release.gsub(%r{ SP[14]}, '')
35
- when 'win'
36
- release = release.delete('.') if release.include? '8.1'
37
- release.sub('Server', '').sub('10', '10-pro')
24
+ os_name = case os_info['operatingsystem']
25
+ when 'Amazon', 'Archlinux', 'AIX', 'OSX'
26
+ next
27
+ when 'OracleLinux'
28
+ 'oracle'
29
+ when 'Windows'
30
+ 'win'
38
31
  else
39
- release
32
+ os_info['operatingsystem'].downcase
40
33
  end
41
34
 
42
- yield "#{os_name}-#{version.downcase}-x86_64".delete(' ')
35
+ os_info['operatingsystemrelease'].each do |release|
36
+ version = case os_name
37
+ when 'ubuntu', 'osx'
38
+ release.sub('.', '')
39
+ when 'sles'
40
+ release.gsub(%r{ SP[14]}, '')
41
+ when 'win'
42
+ release = release.delete('.') if release.include? '8.1'
43
+ release.sub('Server', '').sub('10', '10-pro')
44
+ else
45
+ release
46
+ end
47
+
48
+ yield "#{os_name}-#{version.downcase}-x86_64".delete(' ')
49
+ end
43
50
  end
44
51
  end
45
- end
46
52
 
47
- def run_local_command(command)
48
- stdout, stderr, status = Open3.capture3(command)
49
- error_message = "Attempted to run\ncommand:'#{command}'\nstdout:#{stdout}\nstderr:#{stderr}"
50
- raise error_message unless status.to_i.zero?
53
+ # Executes a command on the test runner.
54
+ #
55
+ # @param command [String] command to execute.
56
+ # @return [Object] the standard out stream.
57
+ def run_local_command(command)
58
+ stdout, stderr, status = Open3.capture3(command)
59
+ error_message = "Attempted to run\ncommand:'#{command}'\nstdout:#{stdout}\nstderr:#{stderr}"
60
+ raise error_message unless status.to_i.zero?
51
61
 
52
- stdout
62
+ stdout
63
+ end
53
64
  end
54
65
 
55
66
  namespace :litmus do
67
+ include LitmusRakeHelper
68
+ # Prints all supported OSes from metadata.json file.
56
69
  desc 'print all supported OSes from metadata'
57
70
  task :metadata do
58
71
  metadata = JSON.parse(File.read('metadata.json'))
@@ -61,7 +74,11 @@ namespace :litmus do
61
74
  end
62
75
  end
63
76
 
64
- desc "provision all supported OSes on with abs eg 'bundle exec rake 'litmus:provision_from_metadata'"
77
+ # DEPRECATED - Provisions all supported OSes with provisioner eg 'bundle exec rake litmus:provision_from_metadata['vmpooler']'.
78
+ #
79
+ # @param :provisioner [String] provisioner to use in provisioning all OSes.
80
+ desc "DEPRECATED: provision_from_metadata task is deprecated.
81
+ Provision all supported OSes with provisioner eg 'bundle exec rake 'litmus:provision_from_metadata'"
65
82
  task :provision_from_metadata, [:provisioner] do |_task, args|
66
83
  metadata = JSON.parse(File.read('metadata.json'))
67
84
  get_metadata_operating_systems(metadata) do |os_and_version|
@@ -83,6 +100,9 @@ namespace :litmus do
83
100
  end
84
101
  end
85
102
 
103
+ # Provisions a list of OSes from provision.yaml file e.g. 'bundle exec rake litmus:provision_list[default]'.
104
+ #
105
+ # @param :key [String] key that maps to a value for a provisioner and an image to be used for each OS provisioned.
86
106
  desc "provision list of machines from provision.yaml file. 'bundle exec rake 'litmus:provision_list[default]'"
87
107
  task :provision_list, [:key] do |_task, args|
88
108
  provision_hash = YAML.load_file('./provision.yaml')
@@ -103,9 +123,19 @@ namespace :litmus do
103
123
  raise "Failed to provision with '#{provisioner}'\n #{failed_image_message}" unless failed_image_message.empty?
104
124
  end
105
125
 
126
+ # Provision a container or VM with a given platform 'bundle exec rake 'litmus:provision[vmpooler, ubuntu-1604-x86_64]'.
127
+ #
128
+ # @param :provisioner [String] provisioner to use in provisioning given platform.
129
+ # @param :platform [String] OS platform for container or VM to use.
106
130
  desc "provision container/VM - abs/docker/vagrant/vmpooler eg 'bundle exec rake 'litmus:provision[vmpooler, ubuntu-1604-x86_64]'"
107
131
  task :provision, [:provisioner, :platform] do |_task, args|
108
132
  include BoltSpec::Run
133
+ spinner = if (ENV['CI'] == 'true') || !ENV['DISTELLI_BUILDNUM'].nil?
134
+ TTY::Spinner.new(':spinner', frames: ['.'], interval: 0.1)
135
+ else
136
+ TTY::Spinner.new("Provisioning #{args[:platform]} using #{args[:provisioner]} provisioner.[:spinner]")
137
+ end
138
+ spinner.auto_spin
109
139
  Rake::Task['spec_prep'].invoke
110
140
  config_data = { 'modulepath' => File.join(Dir.pwd, 'spec', 'fixtures', 'modules') }
111
141
  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'))
@@ -116,17 +146,29 @@ namespace :litmus do
116
146
 
117
147
  params = { 'action' => 'provision', 'platform' => args[:platform], 'inventory' => Dir.pwd }
118
148
  results = run_task("provision::#{args[:provisioner]}", 'localhost', params, config: config_data, inventory: nil)
119
- raise "Failed provisioning #{args[:platform]} using #{args[:provisioner]}\n#{results.first}" if results.first['status'] != 'success'
149
+ if results.first['status'] != 'success'
150
+ spinner.error
151
+ raise "Failed provisioning #{args[:platform]} using #{args[:provisioner]}\n#{results.first}"
152
+ end
120
153
 
154
+ spinner.success
121
155
  puts "#{results.first['result']['node_name']}, #{args[:platform]}"
122
156
  end
123
157
 
158
+ # Install puppet agent on a collection of nodes
159
+ #
160
+ # @param :collection [String] parameters to pass to the puppet agent install command.
161
+ # @param :target_node_name [Array] nodes on which to install puppet agent.
124
162
  desc 'install puppet agent, [:collection, :target_node_name]'
125
163
  task :install_agent, [:collection, :target_node_name] do |_task, args|
126
- puts 'install_agent'
127
- include BoltSpec::Run
128
164
  inventory_hash = inventory_hash_from_inventory_file
129
165
  targets = find_targets(inventory_hash, args[:target_node_name])
166
+ if targets.empty?
167
+ puts 'No targets found'
168
+ exit 0
169
+ end
170
+ puts 'install_agent'
171
+ include BoltSpec::Run
130
172
  Rake::Task['spec_prep'].invoke
131
173
  config_data = { 'modulepath' => File.join(Dir.pwd, 'spec', 'fixtures', 'modules') }
132
174
  params = if args[:collection].nil?
@@ -153,8 +195,69 @@ namespace :litmus do
153
195
  end
154
196
  end
155
197
 
198
+ # Install puppet enterprise - for internal puppet employees only - Requires an el7 provisioned machine - experimental feature [:target_node_name]'
199
+ #
200
+ # @param :target_node_name [Array] nodes on which to install puppet agent.
201
+ desc 'install puppet enterprise - for internal puppet employees only - Requires an el7 provisioned machine - experimental feature [:target_node_name]'
202
+ task :install_pe, [:target_node_name] do |_task, args|
203
+ inventory_hash = inventory_hash_from_inventory_file
204
+ target_nodes = find_targets(inventory_hash, args[:target_node_name])
205
+ if target_nodes.empty?
206
+ puts 'No targets found'
207
+ exit 0
208
+ end
209
+ puts 'install_pe'
210
+ include BoltSpec::Run
211
+ Rake::Task['spec_prep'].invoke
212
+ config_data = { 'modulepath' => File.join(Dir.pwd, 'spec', 'fixtures', 'modules') }
213
+
214
+ puts 'Setting up parameters'
215
+
216
+ PE_RELEASE = 2019.0
217
+ pe_latest_cmd = "curl http://enterprise.delivery.puppetlabs.net/#{PE_RELEASE}/ci-ready/LATEST"
218
+ pe_latest = run_command(pe_latest_cmd, target_nodes, config: config_data, inventory: inventory_hash)
219
+ pe_latest_string = pe_latest[0]['result']['stdout'].delete("\n")
220
+ PE_FILE_NAME = "puppet-enterprise-#{pe_latest_string}-el-7-x86_64"
221
+ TAR_FILE = "#{PE_FILE_NAME}.tar"
222
+ DOWNLOAD_URL = "http://enterprise.delivery.puppetlabs.net/#{PE_RELEASE}/ci-ready/#{TAR_FILE}"
223
+
224
+ puts 'Initiating PE download'
225
+
226
+ # Download PE
227
+ download_pe_cmd = "wget -q #{DOWNLOAD_URL}"
228
+ run_command(download_pe_cmd, target_nodes, config: config_data, inventory: inventory_hash)
229
+
230
+ puts 'PE successfully downloaded, running installer (this may take 5 or so minutes, please be patient)'
231
+
232
+ # Install PE
233
+ untar_cmd = "tar xvf #{TAR_FILE}"
234
+ run_command(untar_cmd, target_nodes, config: config_data, inventory: inventory_hash)
235
+ puts run_command("cd #{PE_FILE_NAME} && 1 | ./puppet-enterprise-installer", target_nodes, config: nil, inventory: inventory_hash)[0]['result']['stdout']
236
+
237
+ puts 'Autosigning Certificates'
238
+
239
+ # Set Autosign
240
+ autosign_cmd = "echo 'autosign = true' >> /etc/puppetlabs/puppet/puppet.conf"
241
+ run_command(autosign_cmd, target_nodes, config: config_data, inventory: inventory_hash)
242
+
243
+ puts 'Finishing installation with a Puppet Agent run'
244
+
245
+ run_command('puppet agent -t', target_nodes, config: config_data, inventory: inventory_hash)
246
+
247
+ puts 'PE Installation is now complete'
248
+ end
249
+
250
+ # Install the puppet module under test on a collection of nodes
251
+ #
252
+ # @param :target_node_name [Array] nodes on which to install a puppet module for testing.
156
253
  desc 'install_module - build and install module'
157
254
  task :install_module, [:target_node_name] do |_task, args|
255
+ inventory_hash = inventory_hash_from_inventory_file
256
+ target_nodes = find_targets(inventory_hash, args[:target_node_name])
257
+ if target_nodes.empty?
258
+ puts 'No targets found'
259
+ exit 0
260
+ end
158
261
  include BoltSpec::Run
159
262
  # old cli_way
160
263
  # pdk_build_command = 'bundle exec pdk build --force'
@@ -167,8 +270,6 @@ namespace :litmus do
167
270
  module_tar = builder.build
168
271
  puts 'Built'
169
272
 
170
- inventory_hash = inventory_hash_from_inventory_file
171
- target_nodes = find_targets(inventory_hash, args[:target_node_name])
172
273
  # module_tar = Dir.glob('pkg/*.tar.gz').max_by { |f| File.mtime(f) }
173
274
  raise "Unable to find package in 'pkg/*.tar.gz'" if module_tar.nil?
174
275
 
@@ -192,15 +293,34 @@ namespace :litmus do
192
293
  puts 'Installed'
193
294
  end
194
295
 
296
+ # Provision a list of machines, install a puppet agent, and install the puppet module under test on a collection of nodes
297
+ #
298
+ # @param :key [String] key that maps to a value for a provisioner and an image to be used for each OS provisioned.
299
+ # @param :collection [String] parameters to pass to the puppet agent install command.
300
+ desc 'provision_install - provision a list of machines, install an agent, and the module.'
301
+ task :provision_install, [:key, :collection] do |_task, args|
302
+ Rake::Task['spec_prep'].invoke
303
+ Rake::Task['litmus:provision_list'].invoke(args[:key])
304
+ Rake::Task['litmus:install_agent'].invoke(args[:collection])
305
+ Rake::Task['litmus:install_module'].invoke
306
+ end
307
+
308
+ # Decommissions test machines.
309
+ #
310
+ # @param :target [Array] nodes to remove from test environemnt and decommission.
195
311
  desc 'tear-down - decommission machines'
196
312
  task :tear_down, [:target] do |_task, args|
313
+ inventory_hash = inventory_hash_from_inventory_file
314
+ targets = find_targets(inventory_hash, args[:target])
315
+ if targets.empty?
316
+ puts 'No targets found'
317
+ exit 0
318
+ end
197
319
  include BoltSpec::Run
198
320
  Rake::Task['spec_prep'].invoke
199
321
  config_data = { 'modulepath' => File.join(Dir.pwd, 'spec', 'fixtures', 'modules') }
200
322
  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'))
201
323
 
202
- inventory_hash = inventory_hash_from_inventory_file
203
- targets = find_targets(inventory_hash, args[:target])
204
324
  bad_results = []
205
325
  targets.each do |node_name|
206
326
  # how do we know what provisioner to use
@@ -229,8 +349,13 @@ namespace :litmus do
229
349
  inventory_hash = inventory_hash_from_inventory_file
230
350
  targets = find_targets(inventory_hash, nil)
231
351
 
352
+ # Run acceptance tests against all machines in the inventory file in parallel.
232
353
  desc 'Run tests in parallel against all machines in the inventory file'
233
354
  task :parallel do
355
+ if targets.empty?
356
+ puts 'No targets found'
357
+ exit 0
358
+ end
234
359
  spinners = TTY::Spinner::Multi.new("Running against #{targets.size} targets.[:spinner]", frames: ['.'], interval: 0.1)
235
360
  payloads = []
236
361
  targets.each do |target|
@@ -21,11 +21,11 @@ module PuppetLitmus::Serverspec
21
21
  # @param opts [Hash] Alters the behaviour of the command. Valid options are:
22
22
  # :catch_changes [Boolean] exit status of 1 if there were changes.
23
23
  # :expect_failures [Boolean] doesnt return an exit code of non-zero if the apply failed.
24
- # :manifest_file_location [Path] The place on the target system.
25
- # :prefix_command [String] prefixes the puppet apply command; eg "export LANGUAGE='ja'".
26
- # :debug [Boolean] run puppet apply with the debug flag.
27
- # :noop [Boolean] run puppet apply with the noop flag.
28
- # @param [Block] his method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
24
+ # :manifest_file_location [Path] The place on the target system.
25
+ # :prefix_command [String] prefixes the puppet apply command; eg "export LANGUAGE='ja'".
26
+ # :debug [Boolean] run puppet apply with the debug flag.
27
+ # :noop [Boolean] run puppet apply with the noop flag.
28
+ # @yieldreturn [Block] this method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
29
29
  # @return [Object] A result object from the apply.
30
30
  def apply_manifest(manifest, opts = {})
31
31
  # rubocop:enable Layout/TrailingWhitespace
@@ -83,13 +83,16 @@ module PuppetLitmus::Serverspec
83
83
  #
84
84
  # @param command_to_run [String] The command to execute.
85
85
  # @param opts [Hash] Alters the behaviour of the command. Valid options are :expect_failures [Boolean] doesnt return an exit code of non-zero if the command failed.
86
- # @param [Block] his method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
86
+ # @yieldreturn [Block] this method will yield to a block of code passed by the caller; this can be used for additional validation, etc.
87
87
  # @return [Object] A result object from the command.
88
88
  def run_shell(command_to_run, opts = {})
89
- inventory_hash = inventory_hash_from_inventory_file
90
89
  target_node_name = ENV['TARGET_HOST']
90
+ inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
91
+ nil
92
+ else
93
+ inventory_hash_from_inventory_file
94
+ end
91
95
  result = run_command(command_to_run, target_node_name, config: nil, inventory: inventory_hash)
92
-
93
96
  raise "shell failed\n`#{command_to_run}`\n======\n#{result}" if result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true
94
97
 
95
98
  result = OpenStruct.new(exit_code: result.first['result']['exit_code'],
@@ -2,5 +2,5 @@
2
2
 
3
3
  # version of this gem
4
4
  module PuppetLitmus
5
- VERSION ||= '0.4.0'
5
+ VERSION ||= '0.5.0'
6
6
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe PuppetLitmus::InventoryManipulation do
6
+ class DummyClass
7
+ end
8
+ let(:dummy_class) do
9
+ dummy_class = DummyClass.new
10
+ dummy_class.extend(described_class)
11
+ dummy_class
12
+ end
13
+
14
+ context 'with config_from_node' do
15
+ let(:no_config_hash) do
16
+ { 'groups' =>
17
+ [{ 'name' => 'ssh_nodes',
18
+ 'nodes' =>
19
+ [{ 'name' => 'test.delivery.puppetlabs.net',
20
+ 'facts' => { 'provisioner' => 'vmpooler', 'platform' => 'centos-5-x86_64' } }] },
21
+ { 'name' => 'winrm_nodes', 'nodes' => [] }] }
22
+ end
23
+
24
+ let(:config_hash) do
25
+ { 'groups' =>
26
+ [{ 'name' => 'ssh_nodes',
27
+ 'nodes' =>
28
+ [{ 'name' => 'test.delivery.puppetlabs.net',
29
+ 'config' => { 'transport' => 'ssh', 'ssh' => { 'user' => 'root', 'password' => 'Qu@lity!', 'host-key-check' => false } },
30
+ 'facts' => { 'provisioner' => 'vmpooler', 'platform' => 'centos-5-x86_64' } }] },
31
+ { 'name' => 'winrm_nodes', 'nodes' => [] }] }
32
+ end
33
+
34
+ it 'no matching node, raises' do
35
+ expect { dummy_class.config_from_node(config_hash, 'not.here') }.to raise_error('No config was found for not.here')
36
+ end
37
+
38
+ it 'no config section, returns nil' do
39
+ expect(dummy_class.config_from_node(no_config_hash, 'test.delivery.puppetlabs.net')).to eq(nil)
40
+ end
41
+
42
+ it 'config exists, and returns' do
43
+ expect(dummy_class.config_from_node(config_hash, 'test.delivery.puppetlabs.net')).to eq('transport' => 'ssh', 'ssh' =>
44
+ { 'user' => 'root', 'password' => 'Qu@lity!', 'host-key-check' => false })
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'rake'
5
+
6
+ describe 'litmus rake tasks' do
7
+ before(:all) do # rubocop:disable RSpec/BeforeAfterAll
8
+ load File.expand_path('../../../lib/puppet_litmus/rake_tasks.rb', __dir__)
9
+ # the spec_prep task is stubbed, rather than load from another gem.
10
+ Rake::Task.define_task(:spec_prep)
11
+ end
12
+
13
+ context 'with litmus:metadata task' do
14
+ it 'happy path' do
15
+ metadata = { 'name' => 'puppetlabs-postgresql',
16
+ 'version' => '6.0.0',
17
+ 'operatingsystem_support' =>
18
+ [{ 'operatingsystem' => 'RedHat', 'operatingsystemrelease' => ['5'] },
19
+ { 'operatingsystem' => 'Ubuntu', 'operatingsystemrelease' => ['14.04', '18.04'] }],
20
+ 'template-ref' => 'heads/master-0-g7827fc2' }
21
+ expect(File).to receive(:read).with(any_args).once
22
+ expect(JSON).to receive(:parse).with(any_args).and_return(metadata)
23
+ expect(STDOUT).to receive(:puts).with('redhat-5-x86_64')
24
+ expect(STDOUT).to receive(:puts).with('ubuntu-1404-x86_64')
25
+ expect(STDOUT).to receive(:puts).with('ubuntu-1804-x86_64')
26
+ Rake::Task['litmus:metadata'].invoke
27
+ end
28
+ end
29
+
30
+ context 'with litmus:provision_install task' do
31
+ it 'happy path' do
32
+ expect(Rake::Task['spec_prep']).to receive(:invoke).and_return('').once
33
+ expect(Rake::Task['litmus:provision_list']).to receive(:invoke).with('default').once
34
+ expect(Rake::Task['litmus:install_agent']).to receive(:invoke).with('puppet6').once
35
+ expect(Rake::Task['litmus:install_module']).to receive(:invoke).once
36
+ Rake::Task['litmus:provision_install'].invoke('default', 'puppet6')
37
+ end
38
+ end
39
+
40
+ context 'with litmus:provision task' do
41
+ it 'provisions' do
42
+ results = [{ 'node' => 'localhost',
43
+ 'target' => 'localhost',
44
+ 'action' => 'task',
45
+ 'object' => 'provision::docker',
46
+ 'status' => 'success',
47
+ 'result' => { 'status' => 'ok', 'node_name' => 'localhost:2222' } }]
48
+
49
+ allow(File).to receive(:directory?).with(any_args).and_return(true)
50
+ allow_any_instance_of(BoltSpec::Run).to receive(:run_task).with(any_args).and_return(results) # rubocop:disable RSpec/AnyInstance
51
+ expect(STDOUT).to receive(:puts).with('localhost:2222, centos:7')
52
+ Rake::Task['litmus:provision'].invoke('docker', 'centos:7')
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe PuppetLitmus::Serverspec do
6
+ class DummyClass
7
+ end
8
+ let(:dummy_class) do
9
+ dummy_class = DummyClass.new
10
+ dummy_class.extend(described_class)
11
+ dummy_class
12
+ end
13
+
14
+ context 'with idempotent_apply' do
15
+ let(:manifest) do
16
+ "include '::doot'"
17
+ end
18
+
19
+ it 'calls all functions' do
20
+ expect(dummy_class).to receive(:create_manifest_file).with(manifest).and_return('/bla.pp')
21
+ expect(dummy_class).to receive(:apply_manifest).with(nil, catch_failures: true, manifest_file_location: '/bla.pp')
22
+ expect(dummy_class).to receive(:apply_manifest).with(nil, catch_changes: true, manifest_file_location: '/bla.pp')
23
+ dummy_class.idempotent_apply(manifest)
24
+ end
25
+ end
26
+
27
+ describe '.run_shell' do
28
+ let(:command_to_run) { "puts 'doot'" }
29
+ let(:result) { ['result' => { 'exit_code' => 0, 'stdout' => nil, 'stderr' => nil }] }
30
+ let(:inventory_hash) { Hash.new(0) }
31
+
32
+ it 'responds to run_shell' do
33
+ expect(dummy_class).to respond_to(:run_shell).with(1..2).arguments
34
+ end
35
+
36
+ context 'when running against localhost and no inventory.yaml file' do
37
+ it 'does run_shell against localhost without error' do
38
+ allow(ENV).to receive(:[]).with('TARGET_HOST').and_return('localhost')
39
+ expect(dummy_class).to receive(:run_command).with(command_to_run, 'localhost', config: nil, inventory: nil).and_return(result)
40
+ expect { dummy_class.run_shell(command_to_run) }.not_to raise_error
41
+ end
42
+ end
43
+
44
+ context 'when running against remote host' do
45
+ it 'does run_shell against remote host without error' do
46
+ allow(ENV).to receive(:[]).with('TARGET_HOST').and_return('some.host')
47
+ expect(dummy_class).to receive(:inventory_hash_from_inventory_file).and_return(inventory_hash)
48
+ expect(dummy_class).to receive(:run_command).with(command_to_run, 'some.host', config: nil, inventory: inventory_hash).and_return(result)
49
+ expect { dummy_class.run_shell(command_to_run) }.not_to raise_error
50
+ end
51
+ end
52
+ end
53
+ end
data/spec/spec_helper.rb CHANGED
@@ -2,3 +2,28 @@
2
2
 
3
3
  require 'rspec'
4
4
  require 'puppet_litmus'
5
+
6
+ if ENV['COVERAGE'] == 'yes'
7
+ require 'simplecov'
8
+
9
+ SimpleCov.formatters = [
10
+ SimpleCov::Formatter::HTMLFormatter,
11
+ ]
12
+ SimpleCov.start do
13
+ track_files 'lib/**/*.rb'
14
+
15
+ add_filter '/spec'
16
+
17
+ # do not track vendored files
18
+ add_filter '/vendor'
19
+ add_filter '/.vendor'
20
+
21
+ # do not track gitignored files
22
+ # this adds about 4 seconds to the coverage check
23
+ # this could definitely be optimized
24
+ add_filter do |f|
25
+ # system returns true if exit status is 0, which with git-check-ignore means file is ignored
26
+ system("git check-ignore --quiet #{f.filename}")
27
+ end
28
+ end
29
+ end
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.4.0
4
+ version: 0.5.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: 2019-05-30 00:00:00.000000000 Z
11
+ date: 2019-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bolt
@@ -85,7 +85,10 @@ files:
85
85
  - lib/puppet_litmus/rake_tasks.rb
86
86
  - lib/puppet_litmus/serverspec.rb
87
87
  - lib/puppet_litmus/version.rb
88
- - spec/lib/puppet_litmus_spec.rb
88
+ - spec/lib/puppet_litmus/inventory_manipulation_spec.rb
89
+ - spec/lib/puppet_litmus/rake_tasks_spec.rb
90
+ - spec/lib/puppet_litmus/serverspec_spec.rb
91
+ - spec/lib/puppet_litmus/version_spec.rb
89
92
  - spec/spec_helper.rb
90
93
  homepage: https://github.com/puppetlabs/puppet_litmus
91
94
  licenses:
@@ -114,4 +117,7 @@ summary: Providing a simple command line tool for puppet content creators, to en
114
117
  simple and complex test deployments.
115
118
  test_files:
116
119
  - spec/spec_helper.rb
117
- - spec/lib/puppet_litmus_spec.rb
120
+ - spec/lib/puppet_litmus/rake_tasks_spec.rb
121
+ - spec/lib/puppet_litmus/version_spec.rb
122
+ - spec/lib/puppet_litmus/inventory_manipulation_spec.rb
123
+ - spec/lib/puppet_litmus/serverspec_spec.rb