Skip to content

Commit

Permalink
(FM-7891) separate serverspec helpers and add unit
Browse files Browse the repository at this point in the history
  • Loading branch information
tphoney committed Apr 18, 2019
1 parent 0cc2e0e commit 9c93ff0
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 83 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ rvm:
- 2.5.1
matrix:
include:
env: CHECK="rubocop"
rvm: 2.4.4
- env: CHECK="rubocop"
- env: CHECK='spec'
4 changes: 4 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'rubocop/rake_task'
require 'github_changelog_generator/task'
require 'puppet_litmus/version'
require 'rspec/core/rake_task'

GitHubChangelogGenerator::RakeTask.new :changelog do |config|
config.user = 'puppetlabs'
Expand Down Expand Up @@ -31,3 +32,6 @@ end
RuboCop::RakeTask.new(:rubocop) do |task|
task.options = %w[-D -S -E]
end

RSpec::Core::RakeTask.new(:spec)
task :default => :spec
83 changes: 2 additions & 81 deletions lib/puppet_litmus.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,90 +2,11 @@

require 'bolt_spec/run'
require 'puppet_litmus/inventory_manipulation'
require 'puppet_litmus/serverspec'

# Helper methods for testing puppet content
module PuppetLitmus
include BoltSpec::Run
include PuppetLitmus::InventoryManipulation
def apply_manifest(manifest, opts = {})
target_node_name = ENV['TARGET_HOST']
raise 'manifest and manifest_file_location in the opts hash are mutually exclusive arguments, pick one' if !manifest.nil? && !opts[:manifest_file_location].nil?
raise 'please pass a manifest or the manifest_file_location in the opts hash' if (manifest.nil? || manifest == '') && opts[:manifest_file_location].nil?

manifest_file_location = opts[:manifest_file_location] || create_manifest_file(manifest)
inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
nil
else
inventory_hash_from_inventory_file
end
command_to_run = "puppet apply #{manifest_file_location}"
command_to_run += " --modulepath #{Dir.pwd}/spec/fixtures/modules" if target_node_name.nil? || target_node_name == 'localhost'
command_to_run += ' --detailed-exitcodes' if !opts[:catch_changes].nil? && (opts[:catch_changes] == true)
# BOLT-608
if Gem.win_platform?
stdout, stderr, status = Open3.capture3(command_to_run)
status_text = if status.to_i.zero?
'success'
else
'failure'
end
result = [{ 'node' => 'localhost', 'status' => status_text, 'result' => { 'exit_code' => status.to_i, 'stderr' => stderr, 'stdout' => stdout } }]
else
result = run_command(command_to_run, target_node_name, config: nil, inventory: inventory_hash)
end

raise "apply mainfest failed\n`#{command_to_run}`\n======\n#{result}" if result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true

result
end

# creates a temp manifest file locally & remote depending on target
def create_manifest_file(manifest)
target_node_name = ENV['TARGET_HOST']
manifest_file = Tempfile.new(['manifest_', '.pp'])
manifest_file.write(manifest)
manifest_file.close
if target_node_name.nil? || target_node_name == 'localhost'
# no need to transfer
manifest_file_location = manifest_file.path
else
# transfer to TARGET_HOST
command = "bundle exec bolt file upload #{manifest_file.path} /tmp/#{File.basename(manifest_file)} --nodes #{target_node_name} --inventoryfile inventory.yaml"
stdout, stderr, status = Open3.capture3(command)
error_message = "Attempted to run\ncommand:'#{command}'\nstdout:#{stdout}\nstderr:#{stderr}"
raise error_message unless status.to_i.zero?

manifest_file_location = "/tmp/#{File.basename(manifest_file)}"
end
manifest_file_location
end

def apply_manifest_and_idempotent(manifest)
manifest_file_location = create_manifest_file(manifest)
apply_manifest(nil, catch_failures: true, manifest_file_location: manifest_file_location)
apply_manifest(nil, catch_changes: true, manifest_file_location: manifest_file_location)
end

def run_shell(command_to_run, opts = {})
inventory_hash = inventory_hash_from_inventory_file
target_node_name = ENV['TARGET_HOST']
result = run_command(command_to_run, target_node_name, config: nil, inventory: inventory_hash)

raise "shell failed\n`#{command_to_run}`\n======\n#{result}" if result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true

result
end

# Runs a selected task against the target host. Parameters should be passed in with a hash format.
def task_run(task_name, params)
config_data = { 'modulepath' => File.join(Dir.pwd, 'spec', 'fixtures', 'modules') }
inventory_hash = inventory_hash_from_inventory_file
target_node_name = ENV['TARGET_HOST'] if target_node_name.nil?

result = run_task(task_name, target_node_name, params, config: config_data, inventory: inventory_hash)

raise "task failed\n`#{task_name}`\n======\n#{result}" if result.first['status'] != 'success'

result
end
include PuppetLitmus::Serverspec
end
86 changes: 86 additions & 0 deletions lib/puppet_litmus/serverspec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# frozen_string_literal: true

# helper functions for running puppet commands, and helpers
module PuppetLitmus::Serverspec
def apply_manifest_and_idempotent(manifest)
manifest_file_location = create_manifest_file(manifest)
apply_manifest(nil, catch_failures: true, manifest_file_location: manifest_file_location)
apply_manifest(nil, catch_changes: true, manifest_file_location: manifest_file_location)
end

def apply_manifest(manifest, opts = {})
target_node_name = ENV['TARGET_HOST']
raise 'manifest and manifest_file_location in the opts hash are mutually exclusive arguments, pick one' if !manifest.nil? && !opts[:manifest_file_location].nil?
raise 'please pass a manifest or the manifest_file_location in the opts hash' if (manifest.nil? || manifest == '') && opts[:manifest_file_location].nil?

manifest_file_location = opts[:manifest_file_location] || create_manifest_file(manifest)
inventory_hash = if target_node_name.nil? || target_node_name == 'localhost'
nil
else
inventory_hash_from_inventory_file
end
command_to_run = "puppet apply #{manifest_file_location}"
command_to_run += " --modulepath #{Dir.pwd}/spec/fixtures/modules" if target_node_name.nil? || target_node_name == 'localhost'
command_to_run += ' --detailed-exitcodes' if !opts[:catch_changes].nil? && (opts[:catch_changes] == true)
# BOLT-608
if Gem.win_platform?
stdout, stderr, status = Open3.capture3(command_to_run)
status_text = if status.to_i.zero?
'success'
else
'failure'
end
result = [{ 'node' => 'localhost', 'status' => status_text, 'result' => { 'exit_code' => status.to_i, 'stderr' => stderr, 'stdout' => stdout } }]
else
result = run_command(command_to_run, target_node_name, config: nil, inventory: inventory_hash)
end

raise "apply mainfest failed\n`#{command_to_run}`\n======\n#{result}" if result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true

result
end

# creates a temp manifest file locally & remote depending on target
def create_manifest_file(manifest)
target_node_name = ENV['TARGET_HOST']
manifest_file = Tempfile.new(['manifest_', '.pp'])
manifest_file.write(manifest)
manifest_file.close
if target_node_name.nil? || target_node_name == 'localhost'
# no need to transfer
manifest_file_location = manifest_file.path
else
# transfer to TARGET_HOST
command = "bundle exec bolt file upload #{manifest_file.path} /tmp/#{File.basename(manifest_file)} --nodes #{target_node_name} --inventoryfile inventory.yaml"
stdout, stderr, status = Open3.capture3(command)
error_message = "Attempted to run\ncommand:'#{command}'\nstdout:#{stdout}\nstderr:#{stderr}"
raise error_message unless status.to_i.zero?

manifest_file_location = "/tmp/#{File.basename(manifest_file)}"
end
manifest_file_location
end

def run_shell(command_to_run, opts = {})
inventory_hash = inventory_hash_from_inventory_file
target_node_name = ENV['TARGET_HOST']
result = run_command(command_to_run, target_node_name, config: nil, inventory: inventory_hash)

raise "shell failed\n`#{command_to_run}`\n======\n#{result}" if result.first['result']['exit_code'] != 0 && opts[:expect_failures] != true

result
end

# Runs a selected task against the target host. Parameters should be passed in with a hash format.
def task_run(task_name, params)
config_data = { 'modulepath' => File.join(Dir.pwd, 'spec', 'fixtures', 'modules') }
inventory_hash = inventory_hash_from_inventory_file
target_node_name = ENV['TARGET_HOST'] if target_node_name.nil?

result = run_task(task_name, target_node_name, params, config: config_data, inventory: inventory_hash)

raise "task failed\n`#{task_name}`\n======\n#{result}" if result.first['status'] != 'success'

result
end
end
10 changes: 10 additions & 0 deletions spec/lib/puppet_litmus_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe PuppetLitmus do
it 'has a version number' do
expect(described_class::VERSION).not_to be nil
expect(described_class::VERSION).to be_a_kind_of(String)
end
end
4 changes: 4 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

require 'rspec'
require 'puppet_litmus'

0 comments on commit 9c93ff0

Please sign in to comment.