Merge pull request #595 from tphoney/4.12.0_release

master to 4.12.x
This commit is contained in:
Helen 2016-04-15 13:29:23 +01:00
commit d9f65387c9
27 changed files with 237 additions and 171 deletions

View file

@ -1,9 +0,0 @@
---
.travis.yml:
script: "\"bundle exec rake validate && bundle exec rake lint && bundle exec rake spec SPEC_OPTS='--color --format documentation'\""
Rakefile:
unmanaged: true
Gemfile:
unmanaged: true
spec/spec_helper.rb:
unmanaged: true

View file

@ -4,7 +4,7 @@ sudo: false
language: ruby
cache: bundler
bundler_args: --without system_tests
script: "bundle exec rake validate && bundle exec rake lint && bundle exec rake spec SPEC_OPTS='--color --format documentation'"
script: "bundle exec rake validate lint spec"
matrix:
fast_finish: true
include:

72
Gemfile
View file

@ -1,61 +1,39 @@
source ENV['GEM_SOURCE'] || 'https://rubygems.org'
#This file is generated by ModuleSync, do not edit.
def location_for(place, fake_version = nil)
source ENV['GEM_SOURCE'] || "https://rubygems.org"
def location_for(place, version = nil)
if place =~ /^(git[:@][^#]*)#(.*)/
[fake_version, { :git => $1, :branch => $2, :require => false }].compact
[version, { :git => $1, :branch => $2, :require => false}].compact
elsif place =~ /^file:\/\/(.*)/
['>= 0', { :path => File.expand_path($1), :require => false }]
['>= 0', { :path => File.expand_path($1), :require => false}]
else
[place, { :require => false }]
[place, version, { :require => false}].compact
end
end
group :development, :unit_tests do
# rspec must be v2 for ruby 1.8.7
if RUBY_VERSION >= '1.8.7' and RUBY_VERSION < '1.9'
gem 'rspec', '~> 2.0'
else
gem 'rspec', '~> 3.1.0', :require => false
end
gem 'rake', '~> 10.1.0', :require => false
gem 'rspec-puppet', '~> 2.2', :require => false
gem 'mocha', :require => false
# keep for its rake task for now
gem 'puppetlabs_spec_helper', :require => false
gem 'puppet-lint', :require => false
gem 'metadata-json-lint', :require => false
gem 'pry', :require => false
gem 'simplecov', :require => false
gem 'json', :require => false
gem 'metadata-json-lint', :require => false
gem 'puppet_facts', :require => false
gem 'puppet-blacksmith', :require => false
gem 'puppetlabs_spec_helper', :require => false
gem 'rspec-puppet', '>= 2.3.2', :require => false
gem 'simplecov', :require => false
end
beaker_version = ENV['BEAKER_VERSION']
beaker_rspec_version = ENV['BEAKER_RSPEC_VERSION']
group :system_tests do
if beaker_version
gem 'beaker', *location_for(beaker_version)
end
if beaker_rspec_version
gem 'beaker-rspec', *location_for(beaker_rspec_version)
else
gem 'beaker-rspec', :require => false
end
gem 'serverspec', :require => false
gem 'beaker-puppet_install_helper', :require => false
gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION'] || '>= 3.4')
gem 'beaker', *location_for(ENV['BEAKER_VERSION'])
gem 'serverspec', :require => false
gem 'beaker-puppet_install_helper', :require => false
gem 'master_manipulator', :require => false
gem 'beaker-hostgenerator', *location_for(ENV['BEAKER_HOSTGENERATOR_VERSION'])
end
facterversion = ENV['GEM_FACTER_VERSION'] || ENV['FACTER_GEM_VERSION']
if facterversion
gem 'facter', *location_for(facterversion)
else
gem 'facter', :require => false
end
gem 'facter', *location_for(ENV['FACTER_GEM_VERSION'])
gem 'puppet', *location_for(ENV['PUPPET_GEM_VERSION'])
puppetversion = ENV['GEM_PUPPET_VERSION'] || ENV['PUPPET_GEM_VERSION']
if puppetversion
gem 'puppet', *location_for(puppetversion)
else
gem 'puppet', :require => false
end
# vim:ft=ruby
if File.exists? "#{__FILE__}.local"
eval(File.read("#{__FILE__}.local"), binding)
end

View file

@ -265,7 +265,7 @@ Takes a resource reference and an optional hash of attributes. Returns 'true' if
#### `delete`
Deletes all instances of a given element from an array, substring from a string, or key from a hash. For example, `delete(['a','b','c','b'], 'b')` returns ['a','c']; `delete('abracadabra', 'bra')` returns 'acada'. `delete({'a' => 1,'b' => 2,'c' => 3},['b','c'])` returns {'a'=> 1}. *Type*: rvalue.
Deletes all instances of a given element from an array, substring from a string, or key from a hash. Arrays and hashes may also match on regular expressions. For example, `delete(['a','b','c','b'], 'b')` returns ['a','c']; `delete('abracadabra', 'bra')` returns 'acada'. `delete({'a' => 1,'b' => 2,'c' => 3},['b','c'])` returns {'a'=> 1}, `delete(['abf', 'ab', 'ac'], '^ab.*')` returns ['ac']. *Type*: rvalue.
#### `delete_at`

View file

@ -1,7 +1,42 @@
require 'rubygems'
# keep for compatibility for now
require 'puppetlabs_spec_helper/rake_tasks'
require 'puppet_blacksmith/rake_tasks'
require 'puppet-lint/tasks/puppet-lint'
require 'puppetlabs_spec_helper/rake_tasks'
PuppetLint.configuration.fail_on_warnings = true
PuppetLint.configuration.send('relative')
PuppetLint.configuration.send('disable_80chars')
PuppetLint.configuration.send('disable_class_inherits_from_params_class')
PuppetLint.configuration.send('disable_documentation')
PuppetLint.configuration.send('disable_single_quote_string_with_variables')
PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"]
desc 'Generate pooler nodesets'
task :gen_nodeset do
require 'beaker-hostgenerator'
require 'securerandom'
require 'fileutils'
agent_target = ENV['TEST_TARGET']
if ! agent_target
STDERR.puts 'TEST_TARGET environment variable is not set'
STDERR.puts 'setting to default value of "redhat-64default."'
agent_target = 'redhat-64default.'
end
master_target = ENV['MASTER_TEST_TARGET']
if ! master_target
STDERR.puts 'MASTER_TEST_TARGET environment variable is not set'
STDERR.puts 'setting to default value of "redhat7-64mdcl"'
master_target = 'redhat7-64mdcl'
end
targets = "#{master_target}-#{agent_target}"
cli = BeakerHostGenerator::CLI.new([targets])
nodeset_dir = "tmp/nodesets"
nodeset = "#{nodeset_dir}/#{targets}-#{SecureRandom.uuid}.yaml"
FileUtils.mkdir_p(nodeset_dir)
File.open(nodeset, 'w') do |fh|
fh.print(cli.execute)
end
puts nodeset
end

View file

@ -48,7 +48,7 @@ class Facter::Util::DotD
end
end
end
rescue Exception => e
rescue StandardError => e
Facter.warn("Failed to handle #{file} as text facts: #{e.class}: #{e}")
end
@ -65,7 +65,7 @@ class Facter::Util::DotD
setcode { v }
end
end
rescue Exception => e
rescue StandardError => e
Facter.warn("Failed to handle #{file} as json facts: #{e.class}: #{e}")
end
@ -77,7 +77,7 @@ class Facter::Util::DotD
setcode { v }
end
end
rescue Exception => e
rescue StandardError => e
Facter.warn("Failed to handle #{file} as yaml facts: #{e.class}: #{e}")
end
@ -106,7 +106,7 @@ class Facter::Util::DotD
end
end
end
rescue Exception => e
rescue StandardError => e
Facter.warn("Failed to handle #{file} as script facts: #{e.class}: #{e}")
Facter.debug(e.backtrace.join("\n\t"))
end

View file

@ -31,7 +31,7 @@ Would result in:
arguments.shift
arguments.each do |x|
result = result + Array(x)
result = result + (x.is_a?(Array) ? x : [x])
end
return result

View file

@ -2,8 +2,6 @@
# delete.rb
#
# TODO(Krzysztof Wilczynski): We need to add support for regular expression ...
module Puppet::Parser::Functions
newfunction(:delete, :type => :rvalue, :doc => <<-EOS
Deletes all instances of a given element from an array, substring from a
@ -34,7 +32,7 @@ string, or key from a hash.
Array(arguments[1]).each do |item|
case collection
when Array, Hash
collection.delete item
collection.delete_if { |coll_item| coll_item =~ %r{#{item}} }
when String
collection.gsub! item, ''
else

View file

@ -29,7 +29,7 @@ Would return: {'a'=>1,'b'=>2,'c'=>3}
# This is to make it compatible with older version of Ruby ...
array = array.flatten
result = Hash[*array]
rescue Exception
rescue StandardError
raise(Puppet::ParseError, 'hash(): Unable to compute ' +
'hash from array given')
end

View file

@ -0,0 +1,21 @@
#
# is_email_address.rb
#
module Puppet::Parser::Functions
newfunction(:is_email_address, type: :rvalue, doc: <<-EOS
Returns true if the string passed to this function is a valid email address.
EOS
) do |arguments|
if arguments.size != 1
raise(Puppet::ParseError, 'is_email_address(): Wrong number of arguments '\
"given #{arguments.size} for 1")
end
# Taken from http://emailregex.com/ (simpler regex)
valid_email_regex = %r{\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z}
return (arguments[0] =~ valid_email_regex) == 0
end
end
# vim: set ts=2 sw=2 et :

View file

@ -15,7 +15,7 @@ be returned if the parsing of YAML string have failed.
begin
PSON::load(arguments[0]) || arguments[1]
rescue Exception => e
rescue StandardError => e
if arguments[1]
arguments[1]
else

View file

@ -16,7 +16,10 @@ be returned if the parsing of YAML string have failed.
begin
YAML::load(arguments[0]) || arguments[1]
rescue Exception => e
# in ruby 1.9.3 Psych::SyntaxError is a RuntimeException
# this still needs to catch that and work also on rubies that
# do not have Psych available.
rescue StandardError, Psych::SyntaxError => e
if arguments[1]
arguments[1]
else

View file

@ -53,7 +53,7 @@ module Puppet::Parser::Functions
rescue Puppet::ExecutionFailure => detail
msg += "\n#{detail}"
raise Puppet::ParseError, msg
rescue Exception => detail
rescue StandardError => detail
msg += "\n#{detail.class.name} #{detail}"
raise Puppet::ParseError, msg
ensure

View file

@ -0,0 +1,31 @@
module Puppet::Parser::Functions
newfunction(:validate_email_address, doc: <<-ENDHEREDOC
Validate that all values passed are valid email addresses.
Fail compilation if any value fails this check.
The following values will pass:
$my_email = "waldo@gmail.com"
validate_email_address($my_email)
validate_email_address("bob@gmail.com", "alice@gmail.com", $my_email)
The following values will fail, causing compilation to abort:
$some_array = [ 'bad_email@/d/efdf.com' ]
validate_email_address($some_array)
ENDHEREDOC
) do |args|
rescuable_exceptions = [ArgumentError]
if args.empty?
raise Puppet::ParseError, "validate_email_address(): wrong number of arguments (#{args.length}; must be > 0)"
end
args.each do |arg|
raise Puppet::ParseError, "#{arg.inspect} is not a string." unless arg.is_a?(String)
begin
raise Puppet::ParseError, "#{arg.inspect} is not a valid email address" unless function_is_email_address([arg])
rescue *rescuable_exceptions
raise Puppet::ParseError, "#{arg.inspect} is not a valid email address"
end
end
end
end

View file

@ -111,8 +111,13 @@ Puppet::Type.newtype(:file_line) do
end
validate do
unless self[:line] and self[:path]
raise(Puppet::Error, "Both line and path are required attributes")
unless self[:line]
unless (self[:ensure].to_s == 'absent') and (self[:match_for_absence].to_s == 'true') and self[:match]
raise(Puppet::Error, "line is a required attribute")
end
end
unless self[:path]
raise(Puppet::Error, "path is a required attribute")
end
end
end

View file

@ -34,6 +34,20 @@ describe 'concat function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('oper
}
EOS
apply_manifest(pp, :catch_failures => true)
end
it 'should concat hash arguments' do
pp = <<-EOS
$output = concat([{"a" => "b"}], {"c" => "d", "e" => "f"})
validate_array($output)
if size($output) != 2 {
fail("${output} should have 2 elements.")
}
if $output[1] != {"c" => "d", "e" => "f"} {
fail("${output} does not have the expected hash for the second element.")
}
EOS
apply_manifest(pp, :catch_failures => true)
end
end

View file

@ -11,6 +11,7 @@ describe 'concat' do
it { is_expected.to run.with_params(['1','2','3'],[['4','5'],'6']).and_return(['1','2','3',['4','5'],'6']) }
it { is_expected.to run.with_params(['1','2'],['3','4'],['5','6']).and_return(['1','2','3','4','5','6']) }
it { is_expected.to run.with_params(['1','2'],'3','4',['5','6']).and_return(['1','2','3','4','5','6']) }
it { is_expected.to run.with_params([{"a" => "b"}], {"c" => "d", "e" => "f"}).and_return([{"a" => "b"}, {"c" => "d", "e" => "f"}]) }
it "should leave the original array intact" do
argument1 = ['1','2','3']

View file

@ -12,6 +12,7 @@ describe 'delete' do
it { is_expected.to run.with_params([], 'two').and_return([]) }
it { is_expected.to run.with_params(['two'], 'two').and_return([]) }
it { is_expected.to run.with_params(['two', 'two'], 'two').and_return([]) }
it { is_expected.to run.with_params(['one', 'two', 'three'], '^t.*').and_return(['one']) }
it { is_expected.to run.with_params(['one', 'two', 'three'], 'four').and_return(['one', 'two', 'three']) }
it { is_expected.to run.with_params(['one', 'two', 'three'], 'two').and_return(['one', 'three']) }
it { is_expected.to run.with_params(['two', 'one', 'two', 'three', 'two'], 'two').and_return(['one', 'three']) }
@ -32,7 +33,7 @@ describe 'delete' do
it { is_expected.to run.with_params('barfoobar', ['foo', 'barbar']).and_return('') }
end
describe 'deleting from an array' do
describe 'deleting from a hash' do
it { is_expected.to run.with_params({}, '').and_return({}) }
it { is_expected.to run.with_params({}, 'key').and_return({}) }
it { is_expected.to run.with_params({'key' => 'value'}, 'key').and_return({}) }
@ -44,6 +45,10 @@ describe 'delete' do
.with_params({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, ['key1', 'key2']) \
.and_return( {'key3' => 'value3'})
}
it { is_expected.to run \
.with_params({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, ['^key\d']) \
.and_return({})
}
end
it "should leave the original array intact" do

View file

@ -5,11 +5,7 @@ describe 'get_module_path' do
it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/) }
it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/) }
it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/) }
if Puppet.version.to_f >= 4.0
it { is_expected.to run.with_params('one').and_raise_error(Puppet::Environments::EnvironmentNotFound, /Could not find a directory environment/) }
else
it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /Could not find module/) }
end
it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /Could not find module/) }
class StubModule
attr_reader :path

View file

@ -0,0 +1,14 @@
require 'spec_helper'
describe 'is_email_address' do
it { is_expected.not_to eq(nil) }
it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) }
it { is_expected.to run.with_params([], []).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) }
it { is_expected.to run.with_params('bob@gmail.com').and_return(true) }
it { is_expected.to run.with_params('alice+puppetlabs.com@gmail.com').and_return(true) }
it { is_expected.to run.with_params('peter.parker@gmail.com').and_return(true) }
it { is_expected.to run.with_params('1.2.3@domain').and_return(false) }
it { is_expected.to run.with_params('1.2.3.4.5@').and_return(false) }
it { is_expected.to run.with_params({}).and_return(false) }
it { is_expected.to run.with_params([]).and_return(false) }
end

View file

@ -0,0 +1,23 @@
require 'spec_helper'
describe 'validate_email_address' do
describe 'signature validation' do
it { is_expected.not_to eq(nil) }
it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) }
end
describe 'valid inputs' do
it { is_expected.to run.with_params('bob@gmail.com') }
it { is_expected.to run.with_params('alice+puppetlabs.com@gmail.com') }
end
describe 'invalid inputs' do
it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /is not a string/) }
it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not a string/) }
it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /is not a string/) }
it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /is not a valid email/) }
it { is_expected.to run.with_params('bob@gmail.com', {}).and_raise_error(Puppet::ParseError, /is not a string/) }
it { is_expected.to run.with_params('bob@gmail.com', true).and_raise_error(Puppet::ParseError, /is not a string/) }
it { is_expected.to run.with_params('bob@gmail.com', 'one').and_raise_error(Puppet::ParseError, /is not a valid email/) }
end
end

View file

@ -1,34 +0,0 @@
#This file pulls in only the minimum necessary to let unmigrated specs still work
# Define the main module namespace for use by the helper modules
module PuppetlabsSpec
# FIXTURE_DIR represents the standard locations of all fixture data. Normally
# this represents <project>/spec/fixtures. This will be used by the fixtures
# library to find relative fixture data.
FIXTURE_DIR = File.join("spec", "fixtures") unless defined?(FIXTURE_DIR)
end
# Require all necessary helper libraries so they can be used later
require 'puppetlabs_spec_helper/puppetlabs_spec/files'
require 'puppetlabs_spec_helper/puppetlabs_spec/fixtures'
#require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
require 'puppetlabs_spec_helper/puppetlabs_spec/matchers'
RSpec.configure do |config|
# Include PuppetlabsSpec helpers so they can be called at convenience
config.extend PuppetlabsSpec::Files
config.extend PuppetlabsSpec::Fixtures
config.include PuppetlabsSpec::Fixtures
config.parser = 'future' if ENV['FUTURE_PARSER'] == 'yes'
config.strict_variables = true if ENV['STRICT_VARIABLES'] == 'yes'
config.stringify_facts = false if ENV['STRINGIFY_FACTS'] == 'no'
config.trusted_node_data = true if ENV['TRUSTED_NODE_DATA'] == 'yes'
config.ordering = ENV['ORDERING'] if ENV['ORDERING']
# This will cleanup any files that were created with tmpdir or tmpfile
config.after :each do
PuppetlabsSpec::Files.cleanup
end
end

View file

@ -1,6 +0,0 @@
--format
s
--colour
--loadby
mtime
--backtrace

View file

@ -1,49 +1,8 @@
#! /usr/bin/env ruby -S rspec
dir = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift File.join(dir, 'lib')
# So everyone else doesn't have to include this base constant.
module PuppetSpec
FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR)
end
require 'puppet'
require 'rspec-puppet'
#This file is generated by ModuleSync, do not edit.
require 'puppetlabs_spec_helper/module_spec_helper'
require 'monkey_patches/alias_should_to_must'
require 'mocha/api'
#require 'puppetlabs_spec_helper/module_spec_helper'
require 'puppetlabs_spec_helper_clone'
# hack to enable all the expect syntax (like allow_any_instance_of) in rspec-puppet examples
RSpec::Mocks::Syntax.enable_expect(RSpec::Puppet::ManifestMatchers)
RSpec.configure do |config|
config.module_path = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'modules')
config.manifest_dir = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'manifests')
config.environmentpath = spec_path = File.expand_path(File.join(Dir.pwd, 'spec'))
config.add_setting :puppet_future
#config.puppet_future = (ENV['FUTURE_PARSER'] == 'yes' or Puppet.version.to_f >= 4.0)
config.puppet_future = Puppet.version.to_f >= 4.0
config.before :each do
# Ensure that we don't accidentally cache facts and environment between
# test cases. This requires each example group to explicitly load the
# facts being exercised with something like
# Facter.collection.loader.load(:ipaddress)
Facter.clear
Facter.clear_messages
RSpec::Mocks.setup
end
config.after :each do
RSpec::Mocks.verify
RSpec::Mocks.teardown
end
end
# Helper class to test handling of arguments which are derived from string
class AlsoString < String
# put local configuration and setup into spec_helper_local
begin
require 'spec_helper_local'
rescue LoadError
end

29
spec/spec_helper_local.rb Normal file
View file

@ -0,0 +1,29 @@
# hack to enable all the expect syntax (like allow_any_instance_of) in rspec-puppet examples
RSpec::Mocks::Syntax.enable_expect(RSpec::Puppet::ManifestMatchers)
RSpec.configure do |config|
# supply tests with a possibility to test for the future parser
config.add_setting :puppet_future
config.puppet_future = Puppet.version.to_f >= 4.0
config.before :each do
# Ensure that we don't accidentally cache facts and environment between
# test cases. This requires each example group to explicitly load the
# facts being exercised with something like
# Facter.collection.loader.load(:ipaddress)
Facter.clear
Facter.clear_messages
RSpec::Mocks.setup
end
config.after :each do
RSpec::Mocks.verify
RSpec::Mocks.teardown
end
end
# Helper class to test handling of arguments which are derived from string
class AlsoString < String
end

View file

@ -398,7 +398,7 @@ describe provider_class do
expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n")
end
it 'should ignore the match if match_for_absense is not specified' do
it 'should ignore the match if match_for_absence is not specified' do
@resource = Puppet::Type::File_line.new(
{
:name => 'foo',
@ -416,7 +416,7 @@ describe provider_class do
expect(File.read(@tmpfile)).to eql("foo1\nfoo\n")
end
it 'should ignore the match if match_for_absense is false' do
it 'should ignore the match if match_for_absence is false' do
@resource = Puppet::Type::File_line.new(
{
:name => 'foo',

View file

@ -41,10 +41,13 @@ describe Puppet::Type.type(:file_line) do
expect { file_line[:path] = 'file' }.to raise_error(Puppet::Error, /File paths must be fully qualified/)
end
it 'should require that a line is specified' do
expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => '/tmp/file') }.to raise_error(Puppet::Error, /Both line and path are required attributes/)
expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => '/tmp/file') }.to raise_error(Puppet::Error, /line is a required attribute/)
end
it 'should not require that a line is specified when matching for absence' do
expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => '/tmp/file', :ensure => :absent, :match_for_absence => :true, :match => 'match') }.not_to raise_error
end
it 'should require that a file is specified' do
expect { Puppet::Type.type(:file_line).new(:name => 'foo', :line => 'path') }.to raise_error(Puppet::Error, /Both line and path are required attributes/)
expect { Puppet::Type.type(:file_line).new(:name => 'foo', :line => 'path') }.to raise_error(Puppet::Error, /path is a required attribute/)
end
it 'should default to ensure => present' do
expect(file_line[:ensure]).to eq :present